mirror of
https://github.com/luxfi/precompile.git
synced 2026-09-24 00:26:21 +00:00
94 lines
5.6 KiB
Go
94 lines
5.6 KiB
Go
// Copyright (C) 2026, Lux Industries Inc. All rights reserved.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
// errors.go — the bridge's error surface. Every error here makes the precompile
|
|
// REVERT cleanly (geth-canonical: charged gas consumed, remaining returned) and
|
|
// NEVER credits or mutates C state. Fail-secure is the rule: when in doubt, deny.
|
|
|
|
package aivmbridge
|
|
|
|
import "errors"
|
|
|
|
var (
|
|
// ErrAChainUnavailable is returned by Pattern A when the node-LOCAL A-Chain
|
|
// on-ramp is not wired in (the default client). A node that serves the bridge
|
|
// selectors but is not running its local A on-ramp reverts cleanly — it never
|
|
// fabricates a result and never masks the absent on-ramp. Mirror of
|
|
// dex.ErrDChainUnavailable.
|
|
ErrAChainUnavailable = errors.New("aivmbridge: local A-Chain on-ramp unavailable (node must wire the A-Chain on-ramp to submit inference intents)")
|
|
|
|
// --- calldata / decode ---------------------------------------------------
|
|
|
|
// ErrInputTooShort: the calldata is shorter than the fixed-width ABI frame the
|
|
// selector requires.
|
|
ErrInputTooShort = errors.New("aivmbridge: input too short")
|
|
// ErrInputOversized: the calldata is longer than the fixed-width ABI frame the
|
|
// selector accepts (reject trailing junk rather than silently ignore it).
|
|
ErrInputOversized = errors.New("aivmbridge: input larger than expected frame")
|
|
// ErrDirtyWord: a fixed-width numeric ABI word carries non-zero high bytes
|
|
// above the field's declared width (a caller must not smuggle bits there).
|
|
ErrDirtyWord = errors.New("aivmbridge: numeric ABI word has dirty high bytes")
|
|
// ErrBadFanout: N outside [1, MaxFanout].
|
|
ErrBadFanout = errors.New("aivmbridge: N out of range")
|
|
// ErrBadThreshold: threshold outside [1, N].
|
|
ErrBadThreshold = errors.New("aivmbridge: threshold out of range")
|
|
// ErrZeroModelSpec / ErrZeroPrompt: an all-zero commitment is never a valid
|
|
// request (it would collide an unbound intent across callers/models).
|
|
ErrZeroModelSpec = errors.New("aivmbridge: modelSpecHash must be non-zero")
|
|
ErrZeroPrompt = errors.New("aivmbridge: promptHash must be non-zero")
|
|
// ErrZeroTxHash: the C tx identity (StateDB.TxHash() and, on fallback, the atomic
|
|
// TxID) resolved to all-zero — a broken host wiring under which distinct C txs would
|
|
// alias the same deterministic intent id. Reject rather than mint an unbound id.
|
|
ErrZeroTxHash = errors.New("aivmbridge: c_tx_hash must be non-zero (host wired no tx identity)")
|
|
|
|
// --- intent state --------------------------------------------------------
|
|
|
|
// ErrIntentReplay: an intent with this deterministic id was already submitted
|
|
// (a re-derived id from a distinct tx must not double-write the outbox).
|
|
ErrIntentReplay = errors.New("aivmbridge: intent already submitted (replay)")
|
|
|
|
// --- receipt verification (Pattern B) ------------------------------------
|
|
|
|
// ErrReceiptDecode: the receipt bytes are malformed (wrong length / version).
|
|
ErrReceiptDecode = errors.New("aivmbridge: receipt decode failed")
|
|
// ErrProofDecode: the proof bytes are malformed (length not a multiple of the
|
|
// hash width, or impossible index).
|
|
ErrProofDecode = errors.New("aivmbridge: proof decode failed")
|
|
// ErrReceiptRootNotCommitted: the proof's ReceiptRoot is not committed in C
|
|
// state. The root authenticity is the A->C atomic-import seam; a root C has not
|
|
// recorded as committed is untrusted and the verify is inert (fail-secure).
|
|
ErrReceiptRootNotCommitted = errors.New("aivmbridge: receipt root is not committed in C state")
|
|
// ErrMerkleVerify: the receipt_hash is not included under ReceiptRoot at Index
|
|
// along Path (a forged or wrong proof).
|
|
ErrMerkleVerify = errors.New("aivmbridge: merkle inclusion proof failed")
|
|
// ErrNoMatchingIntent: the receipt's IntentID does not match a pending C-outbox
|
|
// intent (a receipt for an intent C never submitted is not actionable).
|
|
ErrNoMatchingIntent = errors.New("aivmbridge: receipt does not match a pending C intent")
|
|
// ErrIntentConsumed: the matching intent was already consumed by a prior
|
|
// verified receipt (double-consume guard).
|
|
ErrIntentConsumed = errors.New("aivmbridge: intent already consumed by a prior receipt")
|
|
// ErrReceiptNotCompleted: the receipt status is not Completed (a pending /
|
|
// failed / challenged receipt carries no actionable output — inert).
|
|
ErrReceiptNotCompleted = errors.New("aivmbridge: receipt status is not Completed")
|
|
// ErrZeroOutput: a Completed receipt with an all-zero CanonicalOutputHash is
|
|
// self-contradictory and never actionable.
|
|
ErrZeroOutput = errors.New("aivmbridge: completed receipt has zero canonical output hash")
|
|
// ErrReceiptBindMismatch: the receipt's model/prompt/requester/chain binding
|
|
// does not match the pending intent it claims to settle.
|
|
ErrReceiptBindMismatch = errors.New("aivmbridge: receipt does not match the bound intent fields")
|
|
|
|
// --- read-only -----------------------------------------------------------
|
|
|
|
// ErrReadOnly: a state-mutating selector was invoked in a read-only (static)
|
|
// call context. Both bridge ops mutate the C outbox, so a static call reverts.
|
|
ErrReadOnly = errors.New("aivmbridge: cannot submit/verify in read-only mode")
|
|
|
|
// --- atomic capability ---------------------------------------------------
|
|
|
|
// ErrNoAtomicState: the host did not wire the cross-chain atomic capability
|
|
// (single-chain dev / non-atomic harness). The deterministic intent id binds
|
|
// the C/A chain ids + tx id sourced from this capability; without it the bridge
|
|
// cannot mint a network-scoped id and reverts rather than guess a peer.
|
|
ErrNoAtomicState = errors.New("aivmbridge: cross-chain atomic capability unavailable (host wired no shared-memory runtime)")
|
|
)
|