Sigil documentation
ReferenceRust referencesigil-node

sigil-node · executor

Source declarations, signatures and documentation for executor.

Source: sigil/node/sigil-node/src/executor.rs. SHA-256: 0e296c403ef21e4fd4e81e81f448be6e3ead66e0bbdfc44fce11d9c6b223f1d3.

This reference follows declared source modules, retains conditional attributes, and includes public declarations and implementation methods. Private-module re-exports and trait resolution require the compiler; this is a source reference, not a claim that every listed item is a root import. Function bodies and constant values are omitted.

executor::BOOTSTRAP_SECURITY_MIN_BP_STAKE

Bootstrap security floor for Block Producers: 100,000,000 MINT.

pub const BOOTSTRAP_SECURITY_MIN_BP_STAKE: u64;

Source line: 65.

executor::BOOTSTRAP_SECURITY_MIN_BV_STAKE

Bootstrap security floor for Block Validators: 25,000,000 MINT.

pub const BOOTSTRAP_SECURITY_MIN_BV_STAKE: u64;

Source line: 67.

executor::DEFAULT_VALIDATOR_REWARD_RESERVE_DID

Default pre-funded account used to pay validator rewards without inflating native supply.

pub const DEFAULT_VALIDATOR_REWARD_RESERVE_DID: &str;

Source line: 84.

executor::ValidatorRecord

On-chain validator record managed by the executor.

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ValidatorRecord {
/// OAS DID of the validator.

pub did: String,
/// micro-MINT staked by the validator itself.

pub stake: u64,
/// Validator mode: BlockProducer or BlockValidator.

pub mode: ValidatorMode,
/// Whether this validator is in the active set.

pub active: bool,
/// Total delegated stake from delegators.

pub delegated_stake: u64,
/// Total delegation pool shares issued to delegators.

#[serde(default)]
pub delegated_shares: u64,
/// Accumulated rewards in micro-MINT.

pub accumulated_rewards: u64,
/// Epoch at which unbonding completes (None if not unbonding).

pub unbonding_epoch: Option<u64>,
/// Self-stake waiting out the unbonding period before it can return to the liquid balance.

#[serde(default)]
pub unbonding_stake: u64,
/// Epoch through which a slashed validator is jailed and epoch-excluded.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub slashed_until_epoch: Option<u64>
}

Source line: 98.

executor::ValidatorRecord::total_stake

Total effective stake (self + delegated).

pub fn total_stake(&self) -> u64;

Source line: 126.

executor::StakingPolicy

Height-gated staking policy used by transaction execution.

Existing chains can continue from their current history by configuring a future activation height. Before that height, legacy minimums apply so already-running validator sets keep producing blocks while operators top up. At and after activation, new stakes and post-unstake active eligibility use the upgraded floor.

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct StakingPolicy {
pub legacy_min_bp_stake: u64,
pub legacy_min_bv_stake: u64,
pub activation_height: Option<u64>,
pub activated_min_bp_stake: u64,
pub activated_min_bv_stake: u64
}

Source line: 139.

executor::NativeSupplyPolicy

Native MINT/BITS supply policy enforced by launch-live execution paths.

A fixed supply chain must not silently mint rewards. Rewards are paid by debiting a pre-funded reserve account that was included in genesis.

#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct NativeSupplyPolicy {
pub max_supply: Option<u64>,
pub validator_reward_reserve_did: Option<String>
}

Source line: 152.

executor::CustomTokenClass

Launch-live custom-token class record.

Balances for these token ids use the same deterministic DEX asset-balance table so a freshly minted token can be pooled and traded without a shadow ledger. Amounts are currently bounded to u64::MAX at the executor edge because the DEX/labor asset ledger is u64.

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CustomTokenClass {
pub token_id: String,
pub ticker: String,
pub decimals: u8,
pub issuer_did: String,
pub controller_did: String,
pub supply_policy: SupplyPolicy,
pub transfer_policy: Option<ControlPolicy>,
pub metadata_uri: Option<String>,
pub total_supply: u128
}

Source line: 164.

executor::DelegationUnbonding

Delegated-stake redemption waiting out the unbonding period before withdrawal.

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DelegationUnbonding {
/// Pool shares redeemed from the delegator position.

pub shares: u64,
/// Native token amount claimable after `unlock_height`.

pub amount: u64,
/// Block height at which the claim becomes withdrawable.

pub unlock_height: u64
}

Source line: 178.

executor::AccountSnapshot

Read-only account summary returned to public explorer RPCs.

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AccountSnapshot {
pub did: String,
pub balance: u64,
pub nonce: u64,
pub staked_amount: u64,
pub transaction_count: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub identity_doc: Option<serde_json::Value>
}

Source line: 189.

executor::NativeSupplyPolicy::fixed_at_genesis

pub fn fixed_at_genesis(max_supply: u64) -> Self;

Source line: 200.

executor::StakingPolicy::from_env

pub fn from_env() -> Result<Self, NodeError>;

Source line: 221.

executor::StakingPolicy::min_stake_for_mode_at

pub fn min_stake_for_mode_at(&self, mode: &ValidatorMode, block_height: u64) -> u64;

Source line: 245.

executor::ProposalStatus

Status of a governance proposal.

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ProposalStatus {
    /// Voting is open.
    Voting,
    /// Proposal passed.
    Passed,
    /// Proposal rejected.
    Rejected,
    /// Proposal cancelled by proposer.
    Cancelled,
    /// Proposal executed.
    Executed,
}

Source line: 277.

executor::Proposal

On-chain governance proposal.

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Proposal {
/// Auto-incrementing proposal ID.

pub id: u64,
/// DID of the proposer.

pub proposer: String,
/// Proposal title.

pub title: String,
/// Proposal description.

pub description: String,
/// Block height at which this proposal was created.

pub created_height: u64,
/// Block height at which voting ends.

pub voting_end_height: u64,
/// Total yes votes (stake-weighted, in micro-MINT).

pub votes_yes: u64,
/// Total no votes (stake-weighted, in micro-MINT).

pub votes_no: u64,
/// Total abstain votes (stake-weighted, in micro-MINT).

pub votes_abstain: u64,
/// Current proposal status.

pub status: ProposalStatus,
/// Deposit amount locked by the proposer.

pub deposit: u64
}

Source line: 292.

executor::StateRootEntry

One canonical leaf in Sigil's global state commitment.

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StateRootEntry {
/// Top-level state namespace, e.g. `balance`, `nonce`, `validator`.

pub partition: String,
/// Namespaced state key within the partition.

pub key: Vec<u8>,
/// Canonically encoded value bytes.

pub value: Vec<u8>
}

Source line: 323.

executor::ExecutionState

State interface for the executor.

Provides read/write access to account balances, nonces, identity documents, validator records, delegation mappings, and governance proposals.

pub trait ExecutionState: Send + Sync {
    // -- Account state --
    fn get_balance(&self, did: &str) -> Result<u64, NodeError>;
    fn set_balance(&self, did: &str, amount: u64) -> Result<(), NodeError>;
    fn get_nonce(&self, did: &str) -> Result<u64, NodeError>;
    fn increment_nonce(&self, did: &str) -> Result<(), NodeError>;
    fn has_sponsored_setup_idempotency(
        &self,
        _subject_did: &str,
        _setup_scope: &SponsoredSetupScope,
        _idempotency_key: &str,
    ) -> Result<bool, NodeError> ;
    fn mark_sponsored_setup_idempotency(
        &self,
        _subject_did: &str,
        _setup_scope: &SponsoredSetupScope,
        _idempotency_key: &str,
    ) -> Result<(), NodeError> ;

    // -- Identity state --
    /// Returns the OAS identity document for a DID, or None if not registered.
    fn get_identity(&self, did: &str) -> Result<Option<serde_json::Value>, NodeError>;
    /// Stores an OAS identity document for a DID.
    fn set_identity(&self, did: &str, document: serde_json::Value) -> Result<(), NodeError>;
    fn get_initial_device_anchor(
        &self,
        _subject_did: &str,
        _device_id: &str,
    ) -> Result<Option<sigil_core::InitialDeviceAnchorData>, NodeError> ;
    fn put_initial_device_anchor(
        &self,
        _anchor: sigil_core::InitialDeviceAnchorData,
    ) -> Result<(), NodeError> ;
    /// Returns whether this DID received a balance at genesis.
    fn is_genesis_balance_account(&self, _did: &str) -> Result<bool, NodeError> ;

    // -- Validator state --
    /// Returns the validator record for a DID, or None if not staked.
    fn get_validator(&self, did: &str) -> Result<Option<ValidatorRecord>, NodeError>;
    /// Stores or updates a validator record.
    fn set_validator(&self, did: &str, record: ValidatorRecord) -> Result<(), NodeError>;
    /// Returns all active validators.
    fn get_active_validators(&self) -> Result<Vec<ValidatorRecord>, NodeError>;

    // -- Delegation state --
    /// Returns delegation pool shares from `delegator` to `validator`.
    fn get_delegation(&self, delegator: &str, validator: &str) -> Result<u64, NodeError>;
    /// Returns all known delegation pool shares for `delegator`.
    fn list_delegations_for_delegator(
        &self,
        delegator: &str,
    ) -> Result<Vec<(String, u64)>, NodeError> ;
    /// Sets delegation pool shares from `delegator` to `validator`.
    fn set_delegation(
        &self,
        delegator: &str,
        validator: &str,
        amount: u64,
    ) -> Result<(), NodeError>;
    /// Returns a pending delegation unbonding claim, if one exists.
    fn get_delegation_unbonding(
        &self,
        delegator: &str,
        validator: &str,
    ) -> Result<Option<DelegationUnbonding>, NodeError> ;
    /// Sets or clears a pending delegation unbonding claim.
    fn set_delegation_unbonding(
        &self,
        delegator: &str,
        validator: &str,
        claim: Option<DelegationUnbonding>,
    ) -> Result<(), NodeError> ;

    // -- Custom token state -------------------------------------------------
    fn get_token_class(&self, _token_id: &str) -> Result<Option<CustomTokenClass>, NodeError> ;

    fn put_token_class(&self, _class: CustomTokenClass) -> Result<(), NodeError> ;

    /// Lists account summaries for explorer/public RPC views.
    fn list_accounts(
        &self,
        _limit: usize,
        _offset: usize,
    ) -> Result<Vec<AccountSnapshot>, NodeError> ;

    /// Lists registered identity documents for explorer/public RPC views.
    fn list_identities(
        &self,
        limit: usize,
        offset: usize,
    ) -> Result<Vec<AccountSnapshot>, NodeError> ;

    // -- Governance state --
    /// Returns a governance proposal by ID, or None.
    fn get_proposal(&self, id: u64) -> Result<Option<Proposal>, NodeError>;
    /// Lists governance proposals for public RPC and wallet views.
    fn list_proposals(
        &self,
        _status: Option<ProposalStatus>,
        _limit: usize,
        _offset: usize,
    ) -> Result<Vec<Proposal>, NodeError> ;
    /// Stores or updates a governance proposal.
    fn set_proposal(&self, proposal: Proposal) -> Result<(), NodeError>;
    /// Returns the next proposal ID and increments the counter.
    fn next_proposal_id(&self) -> Result<u64, NodeError>;
    /// Returns whether `voter_did` has already voted on `proposal_id`.
    fn has_voted(&self, proposal_id: u64, voter_did: &str) -> Result<bool, NodeError>;
    /// Records that `voter_did` has voted on `proposal_id`.
    fn record_vote(&self, proposal_id: u64, voter_did: &str) -> Result<(), NodeError>;

    // -- Global Anchor Layer (GAL) ----------------------------------
    //
    // These methods back the public `gal_*` RPC surface used by OAS/HMR
    // resolvers. Defaults fail closed or return empty so test-only backends
    // that do not wire GAL cannot accidentally approve production identity
    // checks.
    #[cfg(feature = "tower")]
    fn get_gal_hmr(&self, _did: &str) -> Result<Option<sigil_core::HmrAnchor>, NodeError> ;

    #[cfg(feature = "tower")]
    fn put_gal_hmr(&self, _anchor: sigil_core::HmrAnchor) -> Result<(), NodeError> ;

    #[cfg(feature = "tower")]
    fn get_gal_mhr(&self, _did: &str) -> Result<Option<sigil_core::MhrAnchor>, NodeError> ;

    #[cfg(feature = "tower")]
    fn put_gal_mhr(&self, _anchor: sigil_core::MhrAnchor) -> Result<(), NodeError> ;

    #[cfg(feature = "tower")]
    fn get_gal_enr(&self, _did: &str) -> Result<Option<sigil_core::EnrAnchor>, NodeError> ;

    #[cfg(feature = "tower")]
    fn put_gal_enr(&self, _anchor: sigil_core::EnrAnchor) -> Result<(), NodeError> ;

    #[cfg(feature = "tower")]
    fn get_gal_org_root(
        &self,
        _org_did: &str,
    ) -> Result<Option<sigil_core::OrgLineageRoot>, NodeError> ;

    #[cfg(feature = "tower")]
    fn put_gal_org_root(&self, _root: sigil_core::OrgLineageRoot) -> Result<(), NodeError> ;

    #[cfg(feature = "tower")]
    fn get_gal_shard_assignment(
        &self,
        _did: &str,
    ) -> Result<Option<sigil_core::ShardAssignment>, NodeError> ;

    #[cfg(feature = "tower")]
    fn put_gal_shard_assignment(
        &self,
        _assignment: sigil_core::ShardAssignment,
    ) -> Result<(), NodeError> ;

    #[cfg(feature = "tower")]
    fn get_gal_revocation(
        &self,
        _did: &str,
    ) -> Result<Option<sigil_core::RevocationRecord>, NodeError> ;

    #[cfg(feature = "tower")]
    fn put_gal_revocation(&self, _record: sigil_core::RevocationRecord) -> Result<(), NodeError> ;

    #[cfg(feature = "tower")]
    fn check_gal_revocation(&self, did: &str) -> Result<sigil_core::RevocationStatus, NodeError> ;

    #[cfg(feature = "tower")]
    fn put_gal_topology(&self, _entry: sigil_core::ShardTopologyEntry) -> Result<(), NodeError> ;

    #[cfg(feature = "tower")]
    fn list_gal_topology(&self) -> Result<Vec<sigil_core::ShardTopologyEntry>, NodeError> ;

    /// Return the on-chain governance parameters loaded from genesis.
    ///
    /// The default returns `GovernanceParams::default()` so that test
    /// backends and old-format genesis files that pre-date this field
    /// continue to work. Production `MemoryExecutionState` overrides this
    /// to return whatever was stored via `install_governance_policy`.
    fn governance_params(&self) -> sigil_core::genesis::GovernanceParams ;

    /// Return the effective staking policy for consensus-critical stake checks.
    ///
    /// Production nodes should run with identical environment values or a
    /// backend override installed at startup. The default keeps legacy behavior
    /// when no upgrade env is configured.
    fn staking_policy(&self) -> Result<StakingPolicy, NodeError> ;

    /// Return launch activation policy for EOS-style stake collection gating.
    ///
    /// Production backends derive this from the fixed staking policy and
    /// launch environment. Tests can override it directly so environment
    /// changes do not leak between parallel test cases.
    fn network_activation_policy(&self) -> Result<NetworkActivationPolicy, NodeError> ;

    /// Return the native supply policy.
    ///
    /// Production backends install a fixed-at-genesis policy during bootstrap.
    /// The default is uncapped only for older tests and external lightweight
    /// state implementations that have not opted into launch-live accounting.
    fn native_supply_policy(&self) -> NativeSupplyPolicy ;

    /// Return smart-contract platform parameters loaded from genesis.
    #[cfg(feature = "contracts")]
    fn contract_params(&self) -> sigil_core::genesis::ContractParams ;

    /// Return CZAC protocol parameters loaded from genesis.
    fn czac_params(&self) -> sigil_core::genesis::CzacParams ;

    /// Return Vigils launch and source-gating parameters loaded from genesis.
    fn vigils_params(&self) -> sigil_core::genesis::VigilsParams ;

    /// Transaction signature batch size configured from genesis.
    ///
    /// Batch size only affects verifier throughput. It does not change block
    /// validity, and the batch verifier derives its scalars from the input
    /// transcript rather than from wall-clock or process RNG.
    fn signature_batch_size(&self) -> usize ;

    /// Current epoch for DAO/labor validator snapshots.
    ///
    /// Production backends should override this from consensus state. The
    /// default keeps genesis-free tests deterministic.
    fn current_epoch_for_dao(&self) -> Result<u64, NodeError> ;

    /// Current finalized block height used as the DAO snapshot block.
    ///
    /// This is deliberately state-derived rather than clock-derived so replay
    /// and consensus execution see identical validator context.
    fn current_block_height_for_dao(&self) -> Result<u64, NodeError> ;

    // -- Crucible training coordination -------------------------------------
    //
    // Defaults fail closed for writes and expose an explicit disabled policy.
    // Production `MemoryExecutionState` overrides these with durable AkashaKV
    // storage; lightweight tests must opt in deliberately before transactions
    // can mutate training state.

    fn crucible_policy(&self) -> Result<sigil_crucible::CruciblePolicy, NodeError> ;

    fn get_training_run(
        &self,
        _run_id: &str,
    ) -> Result<Option<sigil_crucible::TrainingRun>, NodeError> ;

    fn list_training_runs(&self) -> Result<Vec<sigil_crucible::TrainingRun>, NodeError> ;

    fn get_training_rollout_batch(
        &self,
        _run_id: &str,
        _batch_id: &str,
    ) -> Result<Option<sigil_crucible::RolloutBatchCommitment>, NodeError> ;

    fn list_training_rollout_batches(
        &self,
        _run_id: &str,
    ) -> Result<Vec<sigil_crucible::RolloutBatchCommitment>, NodeError> ;

    fn get_training_weights(
        &self,
        _run_id: &str,
        _model_root: &SigilHash,
    ) -> Result<Option<sigil_crucible::WeightPublicationRecord>, NodeError> ;

    fn list_training_weights(
        &self,
        _run_id: &str,
    ) -> Result<Vec<sigil_crucible::WeightPublicationRecord>, NodeError> ;

    fn list_training_rewards(
        &self,
        _run_id: &str,
    ) -> Result<Vec<sigil_crucible::RewardBatchAttestation>, NodeError> ;

    fn list_training_slashes(
        &self,
        _run_id: &str,
    ) -> Result<Vec<sigil_crucible::TrainingSlashRecord>, NodeError> ;

    fn list_training_events(
        &self,
        _run_id: Option<&str>,
    ) -> Result<Vec<crate::crucible_durable::CrucibleEvent>, NodeError> ;

    fn commit_crucible_tx(
        &self,
        _batch: crate::crucible_durable::CrucibleWriteBatch,
    ) -> Result<(), NodeError> ;

    // -- Vigils --------------------------------------------------------------
    //
    // Defaults fail closed for writes so a backend cannot silently accept
    // autonomous subscription state without storage. Read/list defaults keep
    // test-only backends usable until they opt in.
    #[cfg(feature = "vigils-v1")]
    fn get_vigil_subscription(
        &self,
        _subscription_id: &sigil_core::SigilHash,
    ) -> Result<Option<sigil_core::vigil::VigilSubscription>, NodeError> ;

    #[cfg(feature = "vigils-v1")]
    fn put_vigil_subscription(
        &self,
        _subscription: sigil_core::vigil::VigilSubscription,
    ) -> Result<(), NodeError> ;

    #[cfg(feature = "vigils-v1")]
    fn list_vigil_subscriptions(
        &self,
        _subscriber_did: Option<&str>,
        _limit: u32,
    ) -> Result<Vec<sigil_core::vigil::VigilSubscription>, NodeError> ;

    #[cfg(feature = "vigils-v1")]
    fn get_vigil_ingestor(
        &self,
        _ingestor_did: &str,
    ) -> Result<Option<sigil_core::vigil::Ingestor>, NodeError> ;

    #[cfg(feature = "vigils-v1")]
    fn put_vigil_ingestor(&self, _ingestor: sigil_core::vigil::Ingestor) -> Result<(), NodeError> ;

    #[cfg(feature = "vigils-v1")]
    fn list_vigil_ingestors(&self) -> Result<Vec<sigil_core::vigil::Ingestor>, NodeError> ;

    #[cfg(feature = "vigils-v1")]
    fn has_vigil_delivery(
        &self,
        _subscription_id: &sigil_core::SigilHash,
        _event_id: &sigil_core::SigilHash,
    ) -> Result<bool, NodeError> ;

    #[cfg(feature = "vigils-v1")]
    fn put_vigil_delivery(
        &self,
        _record: sigil_core::vigil::VigilDeliveryRecord,
    ) -> Result<(), NodeError> ;

    #[cfg(feature = "vigils-v1")]
    fn list_vigil_delivery_history(
        &self,
        _subscription_id: &sigil_core::SigilHash,
        _limit: u32,
    ) -> Result<Vec<sigil_core::vigil::VigilDeliveryRecord>, NodeError> ;

    #[cfg(feature = "vigils-v1")]
    fn schedule_vigil_callback(
        &self,
        _callback: sigil_core::vigil::ScheduledVigilCallback,
    ) -> Result<(), NodeError> ;

    #[cfg(feature = "vigils-v1")]
    fn drain_vigil_callbacks_for_height(
        &self,
        _height: u64,
        _limit: u32,
    ) -> Result<Vec<sigil_core::vigil::ScheduledVigilCallback>, NodeError> ;

    // -- Tx-inclusion replay barrier (Round-7 P0) --
    //
    // `is_tx_included` and `mark_tx_included` form a durable barrier that
    // closes the crash-window replay window for non-NFT tx types. The
    // executor calls `is_tx_included` before its nonce-equality check and
    // `mark_tx_included` on the success path **before** the sequential
    // `increment_nonce`. Once the inclusion entry has committed, even a
    // crash that loses the post-execution nonce write cannot replay the
    // signed transaction on restart — the inclusion check fires first.
    //
    // The default impls return `false` / `Ok(())` so test backends and
    // genesis-bootstrap code paths that have no durable store still work.
    // Production `MemoryExecutionState` overrides both to delegate to
    // `compute_durable` when wired.

    /// Was this signed transaction already durably recorded as applied?
    fn is_tx_included(&self, _tx_hash: &[u8; 32]) -> Result<bool, NodeError> ;

    /// Record this signed transaction as durably applied at `block_height`.
    /// Must be called BEFORE `increment_nonce` on every successful tx
    /// (NFT executors that already fold the nonce update into their atomic
    /// batch should still mark the inclusion so non-`compute` builds remain
    /// safe under restart).
    fn mark_tx_included(&self, _tx_hash: &[u8; 32], _block_height: u64) -> Result<(), NodeError> ;

    // -- Native DEX state ---------------------------------------------------
    //
    // DEX is consensus state: pools, LP positions, non-native asset balances,
    // and audit events must be backed by the same replayable/snapshot-friendly
    // execution state as balances and nonces. Defaults fail closed for every
    // write except native MINT balance reads/writes, which deliberately reuse
    // the account-balance ledger.

    fn get_dex_pool(&self, _pool_id: &str) -> Result<Option<sigil_core::dex::DexPool>, NodeError> ;

    fn put_dex_pool(&self, _pool: sigil_core::dex::DexPool) -> Result<(), NodeError> ;

    fn list_dex_pools(&self) -> Result<Vec<sigil_core::dex::DexPool>, NodeError> ;

    fn get_dex_position(
        &self,
        _pool_id: &str,
        _owner_did: &str,
    ) -> Result<Option<sigil_core::dex::DexPosition>, NodeError> ;

    fn put_dex_position(&self, _position: sigil_core::dex::DexPosition) -> Result<(), NodeError> ;

    fn list_dex_positions(
        &self,
        _owner_did: Option<&str>,
        _pool_id: Option<&str>,
    ) -> Result<Vec<sigil_core::dex::DexPosition>, NodeError> ;

    fn get_dex_asset_balance(&self, asset_id: &str, owner_did: &str) -> Result<u64, NodeError> ;

    fn set_dex_asset_balance(
        &self,
        asset_id: &str,
        owner_did: &str,
        amount: u64,
    ) -> Result<(), NodeError> ;

    fn append_dex_event(&self, _event: sigil_core::dex::DexEvent) -> Result<u64, NodeError> ;

    fn list_dex_events(
        &self,
        _pool_id: Option<&str>,
        _limit: usize,
    ) -> Result<Vec<sigil_core::dex::DexEvent>, NodeError> ;

    fn commit_dex_tx(&self, _batch: crate::dex_durable::DexWriteBatch) -> Result<(), NodeError> ;

    // -- Storage Pinning Marketplace state ---------------------------------
    //
    // Storage marketplace consensus state contains commitments, provider
    // records, pin contracts, receipts, challenge records, and slashing /
    // reward outcomes. Weave bytes stay off-chain.

    fn get_storage_provider(
        &self,
        _provider_did: &str,
    ) -> Result<Option<sigil_core::storage_market::StorageProviderRecord>, NodeError> ;

    fn list_storage_providers(
        &self,
    ) -> Result<Vec<sigil_core::storage_market::StorageProviderRecord>, NodeError> ;

    fn get_storage_pin_request(
        &self,
        _request_id: &str,
    ) -> Result<Option<sigil_core::storage_market::StoragePinRequest>, NodeError> ;

    fn list_storage_pin_requests_by_owner(
        &self,
        _owner_did: &str,
    ) -> Result<Vec<sigil_core::storage_market::StoragePinRequest>, NodeError> ;

    fn get_storage_pin_contract(
        &self,
        _contract_id: &str,
    ) -> Result<Option<sigil_core::storage_market::StoragePinContract>, NodeError> ;

    fn list_storage_pin_contracts_by_provider(
        &self,
        _provider_did: &str,
    ) -> Result<Vec<sigil_core::storage_market::StoragePinContract>, NodeError> ;

    fn list_storage_pin_contracts_by_request(
        &self,
        _request_id: &str,
    ) -> Result<Vec<sigil_core::storage_market::StoragePinContract>, NodeError> ;

    fn get_storage_pin_receipt(
        &self,
        _receipt_id: &str,
    ) -> Result<Option<sigil_core::storage_market::StoragePinReceipt>, NodeError> ;

    fn list_storage_pin_receipts_by_contract(
        &self,
        _contract_id: &str,
    ) -> Result<Vec<sigil_core::storage_market::StoragePinReceipt>, NodeError> ;

    fn get_storage_challenge(
        &self,
        _challenge_id: &str,
    ) -> Result<Option<sigil_core::storage_market::StorageChallengeRecord>, NodeError> ;

    fn list_storage_challenges_by_contract(
        &self,
        _contract_id: &str,
    ) -> Result<Vec<sigil_core::storage_market::StorageChallengeRecord>, NodeError> ;

    fn commit_storage_market_tx(
        &self,
        _batch: crate::storage_market_durable::StorageMarketWriteBatch,
    ) -> Result<(), NodeError> ;

    // -- Evidence anchoring state ------------------------------------------
    //
    // Reads default to empty; the write path fails closed so a backend
    // without evidence storage cannot silently accept anchor transactions.

    /// Fetch one evidence anchor record by deterministic anchor ID.
    fn get_evidence_anchor(
        &self,
        _anchor_id: &str,
    ) -> Result<Option<sigil_core::evidence::EvidenceAnchorRecord>, NodeError> ;

    /// List all evidence anchor records for a content digest.
    fn list_evidence_anchors_by_digest(
        &self,
        _digest: &str,
    ) -> Result<Vec<sigil_core::evidence::EvidenceAnchorRecord>, NodeError> ;

    /// Persist an evidence anchor record (keyed by `record.anchor_id`).
    fn put_evidence_anchor(
        &self,
        _record: sigil_core::evidence::EvidenceAnchorRecord,
    ) -> Result<(), NodeError> ;

    // -- Nova metaverse state ----------------------------------------------
    //
    // Nova is launch-scope consensus state. Defaults fail closed for writes so
    // no backend can appear launch-live without durable world/parcel storage.

    fn get_nova_world(
        &self,
        _world_id: &str,
    ) -> Result<Option<sigil_core::nova::NovaWorldConfig>, NodeError> ;

    fn put_nova_world(&self, _world: sigil_core::nova::NovaWorldConfig) -> Result<(), NodeError> ;

    fn list_nova_worlds(&self) -> Result<Vec<sigil_core::nova::NovaWorldConfig>, NodeError> ;

    fn get_nova_parcel(
        &self,
        _parcel_id: &str,
    ) -> Result<Option<sigil_core::nova::NovaParcelRecord>, NodeError> ;

    fn put_nova_parcel(
        &self,
        _parcel: sigil_core::nova::NovaParcelRecord,
    ) -> Result<(), NodeError> ;

    fn list_nova_parcels_in_region(
        &self,
        _world_id: &str,
        _region_x: i32,
        _region_z: i32,
    ) -> Result<Vec<sigil_core::nova::NovaParcelRecord>, NodeError> ;

    fn list_nova_parcels(&self) -> Result<Vec<sigil_core::nova::NovaParcelRecord>, NodeError> ;

    fn get_nova_building(
        &self,
        _building_id: &str,
    ) -> Result<Option<sigil_core::nova::NovaBuildingRecord>, NodeError> ;

    fn put_nova_building(
        &self,
        _building: sigil_core::nova::NovaBuildingRecord,
    ) -> Result<(), NodeError> ;

    fn delete_nova_building(&self, _building_id: &str) -> Result<(), NodeError> ;

    fn list_nova_buildings(&self) -> Result<Vec<sigil_core::nova::NovaBuildingRecord>, NodeError> ;

    fn get_nova_avatar(
        &self,
        _avatar_id: &str,
    ) -> Result<Option<sigil_core::nova::NovaAvatarRecord>, NodeError> ;

    fn put_nova_avatar(
        &self,
        _avatar: sigil_core::nova::NovaAvatarRecord,
    ) -> Result<(), NodeError> ;

    fn list_nova_avatars(&self) -> Result<Vec<sigil_core::nova::NovaAvatarRecord>, NodeError> ;

    fn get_nova_auction(
        &self,
        _auction_id: &str,
    ) -> Result<Option<sigil_core::nova::NovaAuctionRecord>, NodeError> ;

    fn put_nova_auction(
        &self,
        _auction: sigil_core::nova::NovaAuctionRecord,
    ) -> Result<(), NodeError> ;

    fn list_nova_auctions(&self) -> Result<Vec<sigil_core::nova::NovaAuctionRecord>, NodeError> ;

    fn commit_nova_tx(&self, _batch: crate::nova_durable::NovaWriteBatch) -> Result<(), NodeError> ;

    /// Create a disposable, copy-on-write validation snapshot.
    ///
    /// Consensus uses this before prevoting so proposal re-execution cannot
    /// mutate canonical state unless the block later finalizes.
    fn snapshot_for_validation(&self) -> Result<Box<dyn ExecutionState>, NodeError> ;

    /// Compute the deterministic global post-state root.
    ///
    /// Production backends must override this with their complete state snapshot.
    fn compute_state_root(&self) -> Result<SigilHash, NodeError> ;

    /// Compute the deterministic global post-state root for a specific block
    /// height.
    ///
    /// This is used during rolling protocol upgrades where new state-root
    /// namespaces must not alter historical replay before their configured
    /// activation height. Backends that do not need height-aware schemas may
    /// safely delegate to `compute_state_root`.
    fn compute_state_root_at_height(&self, _block_height: u64) -> Result<SigilHash, NodeError> ;

    fn state_root_entries_at_height(
        &self,
        _block_height: u64,
    ) -> Result<Vec<StateRootEntry>, NodeError> ;

    // -- Compute marketplace --
    //
    // The default implementations return NotSupported. Production state
    // backends (the `engine` module) override the methods they wire; the
    // executor's compute handlers fail closed when the backend has not yet
    // implemented compute storage.

    /// Current epoch (used by compute handlers to time-stamp records).
    #[cfg(feature = "compute")]
    fn current_epoch(&self) -> Result<u64, NodeError> ;

    /// Current block height (snapshot at execution).
    #[cfg(feature = "compute")]
    fn current_block_height(&self) -> Result<u64, NodeError> ;

    /// Snapshot of the chain-config policies the compute executor must
    /// enforce. The default returns a fail-closed policy: empty resolver
    /// allowlist (no challenge resolution permitted) and TEE verification
    /// disabled. Production backends override this from genesis.
    #[cfg(feature = "compute")]
    fn compute_policy(&self) -> Result<crate::compute_state::ComputePolicy, NodeError> ;

    /// Phase 13 — return the TEE verifier registry the executor will
    /// consult on T3 receipt settlement. The default registers the four
    /// production verifier stubs (each fails closed with
    /// `FixtureMaterialRequired`). Backends that need to override (e.g.
    /// tests using `TestAcceptor`, or ops that have plugged in real
    /// vendor reference material) provide a custom registry.
    ///
    /// Only available when the `tee-verify` feature is compiled in;
    /// production builds without `tee-verify` reject all T3 settlement
    /// upstream of the verifier check.
    #[cfg(feature = "tee-verify")]
    fn tee_verifier(&self) -> Result<crate::tee_verify::TeeVerifierRegistry, NodeError> ;

    #[cfg(feature = "compute")]
    fn get_compute_provider(
        &self,
        _provider_did: &str,
    ) -> Result<Option<crate::compute_state::ComputeProvider>, NodeError> ;

    #[cfg(feature = "compute")]
    fn put_compute_provider(
        &self,
        _provider: crate::compute_state::ComputeProvider,
    ) -> Result<(), NodeError> ;

    #[cfg(feature = "compute")]
    fn list_compute_providers(
        &self,
    ) -> Result<Vec<crate::compute_state::ComputeProvider>, NodeError> ;

    #[cfg(feature = "compute")]
    fn get_compute_escrow(
        &self,
        _owner_did: &str,
    ) -> Result<Option<crate::compute_state::ComputeEscrow>, NodeError> ;

    #[cfg(feature = "compute")]
    fn put_compute_escrow(
        &self,
        _escrow: crate::compute_state::ComputeEscrow,
    ) -> Result<(), NodeError> ;

    #[cfg(feature = "compute")]
    fn get_compute_job(
        &self,
        _job_id: &str,
    ) -> Result<Option<crate::compute_state::ComputeJob>, NodeError> ;

    #[cfg(feature = "compute")]
    fn put_compute_job(&self, _job: crate::compute_state::ComputeJob) -> Result<(), NodeError> ;

    #[cfg(feature = "compute")]
    fn list_compute_jobs(
        &self,
        _filter: &crate::compute_state::JobIndexFilter,
    ) -> Result<Vec<crate::compute_state::ComputeJob>, NodeError> ;

    #[cfg(feature = "compute")]
    fn get_compute_receipt(
        &self,
        _receipt_id: &str,
    ) -> Result<Option<crate::compute_state::ComputeReceiptRecord>, NodeError> ;

    #[cfg(feature = "compute")]
    fn put_compute_receipt(
        &self,
        _record: crate::compute_state::ComputeReceiptRecord,
    ) -> Result<(), NodeError> ;

    #[cfg(feature = "compute")]
    fn is_receipt_settled(&self, _receipt_id: &str) -> Result<bool, NodeError> ;

    #[cfg(feature = "compute")]
    fn is_receipt_tuple_settled(
        &self,
        receipt_id: &str,
        _job_id: &str,
        _task_id: Option<&str>,
    ) -> Result<bool, NodeError> ;

    #[cfg(feature = "compute")]
    fn get_compute_challenge(
        &self,
        _challenge_id: &str,
    ) -> Result<Option<crate::compute_state::ComputeChallenge>, NodeError> ;

    #[cfg(feature = "compute")]
    fn put_compute_challenge(
        &self,
        _challenge: crate::compute_state::ComputeChallenge,
    ) -> Result<(), NodeError> ;

    #[cfg(feature = "compute")]
    fn list_compute_challenges_by_receipt(
        &self,
        _receipt_id: &str,
    ) -> Result<Vec<crate::compute_state::ComputeChallenge>, NodeError> ;

    #[cfg(feature = "compute")]
    fn append_compute_audit_event(
        &self,
        _event: crate::compute_state::ComputeAuditEvent,
    ) -> Result<u64, NodeError> ;

    #[cfg(feature = "compute")]
    fn list_compute_audit_events(
        &self,
        _query: &crate::compute_state::AuditQuery,
    ) -> Result<Vec<crate::compute_state::ComputeAuditEvent>, NodeError> ;

    #[cfg(feature = "compute")]
    fn append_compute_reputation_signal(
        &self,
        _signal: crate::compute_state::ComputeReputationSignal,
    ) -> Result<(), NodeError> ;

    #[cfg(feature = "compute")]
    fn list_compute_reputation_signals(
        &self,
        _provider_did: &str,
    ) -> Result<Vec<crate::compute_state::ComputeReputationSignal>, NodeError> ;

    #[cfg(feature = "compute")]
    fn put_maca_work_claim(
        &self,
        _claim: crate::compute_state::MacaWorkClaim,
    ) -> Result<(), NodeError> ;

    #[cfg(feature = "compute")]
    fn get_maca_work_claim(
        &self,
        _work_id: &sigil_core::hash::SigilHash,
    ) -> Result<Option<crate::compute_state::MacaWorkClaim>, NodeError> ;

    #[cfg(feature = "compute")]
    fn put_maca_validation_record(
        &self,
        _record: crate::compute_state::MacaValidationRecord,
    ) -> Result<(), NodeError> ;

    #[cfg(feature = "compute")]
    fn list_maca_validation_records(
        &self,
        _work_id: &sigil_core::hash::SigilHash,
    ) -> Result<Vec<crate::compute_state::MacaValidationRecord>, NodeError> ;

    // -- MACA epoch / quorum aggregation (Phase 12) ------------------

    #[cfg(feature = "compute")]
    fn get_validator_agent(
        &self,
        _agent_did: &str,
    ) -> Result<Option<crate::compute_state::ValidatorAgentRecord>, NodeError> ;

    #[cfg(feature = "compute")]
    fn put_validator_agent(
        &self,
        _record: crate::compute_state::ValidatorAgentRecord,
    ) -> Result<(), NodeError> ;

    #[cfg(feature = "compute")]
    fn list_validator_agents(
        &self,
    ) -> Result<Vec<crate::compute_state::ValidatorAgentRecord>, NodeError> ;

    #[cfg(feature = "compute")]
    fn get_maca_beacon(
        &self,
        _epoch_id: u64,
    ) -> Result<Option<crate::compute_state::BeaconRecord>, NodeError> ;

    #[cfg(feature = "compute")]
    fn put_maca_beacon(
        &self,
        _record: crate::compute_state::BeaconRecord,
    ) -> Result<(), NodeError> ;

    #[cfg(feature = "compute")]
    fn get_maca_epoch(
        &self,
        _epoch_id: u64,
    ) -> Result<Option<crate::compute_state::MacaEpoch>, NodeError> ;

    #[cfg(feature = "compute")]
    fn put_maca_epoch(&self, _epoch: crate::compute_state::MacaEpoch) -> Result<(), NodeError> ;

    #[cfg(feature = "compute")]
    fn list_maca_epochs(
        &self,
        _query: &crate::compute_state::EpochQuery,
    ) -> Result<Vec<crate::compute_state::MacaEpoch>, NodeError> ;

    #[cfg(feature = "compute")]
    fn get_maca_quorum_proof(
        &self,
        _epoch_id: u64,
        _work_id: &sigil_core::hash::SigilHash,
    ) -> Result<Option<crate::compute_state::MacaQuorumProof>, NodeError> ;

    #[cfg(feature = "compute")]
    fn put_maca_quorum_proof(
        &self,
        _proof: crate::compute_state::MacaQuorumProof,
    ) -> Result<(), NodeError> ;

    #[cfg(feature = "compute")]
    fn list_maca_quorum_proofs(
        &self,
        _epoch_id: u64,
    ) -> Result<Vec<crate::compute_state::MacaQuorumProof>, NodeError> ;

    /// Returns all `MacaValidationRecord`s submitted under a given epoch
    /// + work_id pair. Used by `MacaFinalizeEpoch` to aggregate.
    #[cfg(feature = "compute")]
    fn list_maca_attestations_for_epoch_work(
        &self,
        _epoch_id: u64,
        _work_id: &sigil_core::hash::SigilHash,
    ) -> Result<Vec<crate::compute_state::MacaValidationRecord>, NodeError> ;

    // -- DAO Work OS state (Phase 3) ---------------------------------
    //
    // Mandate / labor-contract storage backing the validators in
    // `sigil_state::dao_validators`. Default implementations fail
    // closed when the backend has not wired DAO state — protected
    // transactions then produce typed `Failed` receipts rather than
    // silently no-op'ing.

    /// Fetch a Mandate by its `mandate_id` (DID), or `None` if absent.
    #[cfg(feature = "dao-validators")]
    fn get_mandate(&self, _mandate_id: &str) -> Result<Option<sigil_core::Mandate>, NodeError> ;

    /// Insert or update a Mandate. Replaces any existing record at the
    /// same `mandate_id`.
    #[cfg(feature = "dao-validators")]
    fn put_mandate(&self, _mandate: sigil_core::Mandate) -> Result<(), NodeError> ;

    /// Return active mandates for state-derived DAO validator snapshots.
    #[cfg(feature = "dao-validators")]
    fn list_active_mandates(&self) -> Result<Vec<sigil_core::Mandate>, NodeError> ;

    /// Fetch a `LaborJob` posting by its `job_id`, or `None` if absent.
    fn get_labor_job(&self, _job_id: &str) -> Result<Option<sigil_core::LaborJob>, NodeError> ;

    /// Insert or update a `LaborJob`. Replaces any existing record at the
    /// same `job_id`.
    fn put_labor_job(&self, _job: sigil_core::LaborJob) -> Result<(), NodeError> ;

    /// Fetch a `LaborBid` by its `bid_id`, or `None` if absent.
    fn get_labor_bid(&self, _bid_id: &str) -> Result<Option<sigil_core::LaborBid>, NodeError> ;

    /// Insert or update a `LaborBid`. Replaces any existing record at the
    /// same `bid_id`.
    fn put_labor_bid(&self, _bid: sigil_core::LaborBid) -> Result<(), NodeError> ;

    /// Return all `bid_id` strings for bids submitted against `job_id`.
    fn list_labor_bids_for_job(&self, _job_id: &str) -> Result<Vec<String>, NodeError> ;

    /// Look up the `contract_id` associated with `dispute_id`.
    /// Returns `None` if the dispute index entry does not exist.
    fn get_labor_dispute_contract_id(
        &self,
        _dispute_id: &str,
    ) -> Result<Option<String>, NodeError> ;

    /// Fetch a LaborContract by its `contract_id`, or `None` if absent.
    fn get_labor_contract(
        &self,
        _contract_id: &str,
    ) -> Result<Option<sigil_core::LaborContract>, NodeError> ;

    /// Insert or update a LaborContract. Replaces any existing record
    /// at the same `contract_id`.
    fn put_labor_contract(&self, _contract: sigil_core::LaborContract) -> Result<(), NodeError> ;

    /// Return labor contracts for state-derived DAO validator snapshots.
    fn list_labor_contracts(&self) -> Result<Vec<sigil_core::LaborContract>, NodeError> ;

    /// Fetch a single durable labor milestone.
    fn get_labor_milestone(
        &self,
        _contract_id: &str,
        _milestone_index: u32,
    ) -> Result<Option<sigil_core::Milestone>, NodeError> ;

    /// List milestones for a labor contract.
    fn list_labor_milestones(
        &self,
        _contract_id: &str,
    ) -> Result<Vec<sigil_core::Milestone>, NodeError> ;

    /// Return all labor jobs known to this state backend.
    fn list_labor_jobs(&self) -> Result<Vec<sigil_core::LaborJob>, NodeError> ;

    /// Return all labor bids known to this state backend.
    fn list_labor_bids(&self) -> Result<Vec<sigil_core::LaborBid>, NodeError> ;

    /// Fetch exact labor escrow accounting for a contract.
    fn get_labor_escrow(
        &self,
        _contract_id: &str,
    ) -> Result<Option<sigil_core::LaborEscrow>, NodeError> ;

    /// Insert or update exact labor escrow accounting.
    fn put_labor_escrow(&self, _escrow: sigil_core::LaborEscrow) -> Result<(), NodeError> ;

    /// Fetch a full labor dispute record.
    fn get_labor_dispute(
        &self,
        _dispute_id: &str,
    ) -> Result<Option<sigil_core::Dispute>, NodeError> ;

    /// Insert or update a full labor dispute record.
    fn put_labor_dispute(&self, _dispute: sigil_core::Dispute) -> Result<(), NodeError> ;

    /// List full labor dispute records.
    fn list_labor_disputes(
        &self,
        _state: Option<sigil_core::DisputeState>,
    ) -> Result<Vec<sigil_core::Dispute>, NodeError> ;

    /// Fetch an open bounty offer by ID.
    fn get_labor_offer(
        &self,
        _offer_id: &str,
    ) -> Result<Option<sigil_core::BountyOffer>, NodeError> ;

    /// List open bounty offers, optionally filtered by state.
    fn list_labor_offers(
        &self,
        _state: Option<sigil_core::BountyState>,
    ) -> Result<Vec<sigil_core::BountyOffer>, NodeError> ;

    /// Fetch an open bounty claim by ID.
    fn get_labor_claim(
        &self,
        _claim_id: &str,
    ) -> Result<Option<sigil_core::BountyClaim>, NodeError> ;

    /// List open bounty claims, optionally filtered by offer and claimant.
    fn list_labor_claims(
        &self,
        _offer_id: Option<&str>,
        _claimant_did: Option<&str>,
    ) -> Result<Vec<sigil_core::BountyClaim>, NodeError> ;

    /// Replay/equivocation guard for claimant deliverables.
    fn get_labor_claim_index(
        &self,
        _offer_id: &str,
        _claimant_did: &str,
        _deliverable_hash: &str,
    ) -> Result<Option<String>, NodeError> ;

    /// Fetch an attestation by ID.
    fn get_labor_claim_attestation(
        &self,
        _attestation_id: &str,
    ) -> Result<Option<sigil_core::ClaimAttestation>, NodeError> ;

    /// List attestations for one claim.
    fn list_labor_claim_attestations(
        &self,
        _claim_id: &str,
    ) -> Result<Vec<sigil_core::ClaimAttestation>, NodeError> ;

    /// Fetch durable Labor audit events in a block-height range.
    fn list_labor_events(
        &self,
        _from_height: u64,
        _to_height: u64,
    ) -> Result<Vec<crate::labor_durable::LaborEvent>, NodeError> ;

    // -- Agent Contract Zones (Phase 15) ------------------------------
    //
    // `contracts` feature surface. Default implementations fail closed
    // so that the four contract transactions (DeployContract,
    // CallContract, UpgradeContract, SetContractPolicy) cannot silently
    // no-op when the backend has not wired contract storage.

    /// Get a contract record by DID. Returns `None` if not deployed.
    #[cfg(feature = "contracts")]
    fn get_contract(
        &self,
        _contract_did: &str,
    ) -> Result<Option<sigil_execution::ContractRecord>, NodeError> ;

    /// Insert or replace a contract record.
    #[cfg(feature = "contracts")]
    fn put_contract(&self, _record: sigil_execution::ContractRecord) -> Result<(), NodeError> ;

    /// List all contracts deployed in `zone_id`.
    #[cfg(feature = "contracts")]
    fn list_zone_contracts(
        &self,
        _zone_id: &str,
    ) -> Result<Vec<sigil_execution::ContractRecord>, NodeError> ;

    /// List all known Organization Zones in deterministic order.
    #[cfg(feature = "contracts")]
    fn list_contract_zones(&self) -> Result<Vec<sigil_execution::OrganizationZone>, NodeError> ;

    /// Get an `OrganizationZone` by id.
    #[cfg(feature = "contracts")]
    fn get_zone(
        &self,
        _zone_id: &str,
    ) -> Result<Option<sigil_execution::OrganizationZone>, NodeError> ;

    /// Insert or replace an `OrganizationZone`.
    #[cfg(feature = "contracts")]
    fn put_zone(&self, _zone: sigil_execution::OrganizationZone) -> Result<(), NodeError> ;

    /// Read a single key from a contract's keyed state. Returns `None`
    /// if the key is unset.
    #[cfg(feature = "contracts")]
    fn get_contract_state(
        &self,
        _contract_did: &str,
        _key: &[u8],
    ) -> Result<Option<Vec<u8>>, NodeError> ;

    /// Write a single key into a contract's keyed state.
    #[cfg(feature = "contracts")]
    fn put_contract_state(
        &self,
        _contract_did: &str,
        _key: &[u8],
        _value: &[u8],
    ) -> Result<(), NodeError> ;

    /// Delete a single key from a contract's keyed state.
    #[cfg(feature = "contracts")]
    fn delete_contract_state(&self, _contract_did: &str, _key: &[u8]) -> Result<(), NodeError> ;

    /// Compute a deterministic state-root for a contract over its
    /// keyed state. Default returns `SigilHash::ZERO`. Production
    /// backends override with a Merkle-style root.
    #[cfg(feature = "contracts")]
    fn contract_state_root(
        &self,
        _contract_did: &str,
    ) -> Result<sigil_core::hash::SigilHash, NodeError> ;

    /// Append a contract event. Returns the assigned monotonic seq.
    #[cfg(feature = "contracts")]
    fn append_contract_event(
        &self,
        _event: sigil_execution::ContractEvent,
    ) -> Result<u64, NodeError> ;

    /// List contract events matching `query`. Default returns empty.
    #[cfg(feature = "contracts")]
    fn list_contract_events(
        &self,
        _query: &sigil_execution::ContractEventQuery,
    ) -> Result<Vec<sigil_execution::ContractEvent>, NodeError> ;

    /// Get the WASM bytecode blob keyed by its content-addressed hash.
    /// `None` if no blob has been registered for `code_hash`.
    #[cfg(feature = "contracts")]
    fn get_code_blob(
        &self,
        _code_hash: &sigil_core::hash::SigilHash,
    ) -> Result<Option<Vec<u8>>, NodeError> ;

    /// Insert a content-addressed WASM bytecode blob. The hash MUST
    /// match `SigilHash::digest(bytes)`; backends MUST verify before
    /// persisting.
    #[cfg(feature = "contracts")]
    fn put_code_blob(
        &self,
        _code_hash: &sigil_core::hash::SigilHash,
        _bytes: &[u8],
    ) -> Result<(), NodeError> ;

    // -- Cross-zone messaging (Phase 15-K) --
    //
    // The contract host fn `send_zone_message` enqueues messages here.
    // The target zone's executor drains them in a subsequent block via
    // `list_pending_zone_messages` + `mark_zone_message_delivered`.
    // Inline cross-zone delivery is deliberately out of scope — message
    // delivery is a separate consensus step, in line with the design
    // doc.

    #[cfg(feature = "contracts")]
    fn enqueue_zone_message(
        &self,
        _msg: sigil_execution::CrossZoneMessage,
    ) -> Result<(), NodeError> ;

    #[cfg(feature = "contracts")]
    fn list_pending_zone_messages(
        &self,
        _target_zone: &str,
    ) -> Result<Vec<sigil_execution::CrossZoneMessage>, NodeError> ;

    #[cfg(feature = "contracts")]
    fn mark_zone_message_delivered(
        &self,
        _msg_id: &str,
        _status: sigil_execution::MessageStatus,
    ) -> Result<(), NodeError> ;

    // -- Native NFT state (unconditional — NFTs are core, not optional) -------
    //
    // Default implementations fail closed so that callers never silently
    // no-op on backends without NFT storage.
    // `MemoryExecutionState` overrides all of these below.

    /// Fetch an NFT collection by id, or `None` if not found.
    fn get_nft_collection(
        &self,
        _collection_id: &sigil_core::nft::CollectionId,
    ) -> Result<Option<sigil_core::nft::NftCollection>, NodeError> ;

    /// Insert or replace an NFT collection record.
    fn put_nft_collection(
        &self,
        _collection: sigil_core::nft::NftCollection,
    ) -> Result<(), NodeError> ;

    /// Fetch an individual NFT token, or `None` if not found.
    fn get_nft_token(
        &self,
        _collection_id: &sigil_core::nft::CollectionId,
        _token_id: sigil_core::nft::TokenId,
    ) -> Result<Option<sigil_core::nft::NftToken>, NodeError> ;

    /// Insert or replace an NFT token record.
    fn put_nft_token(&self, _token: sigil_core::nft::NftToken) -> Result<(), NodeError> ;

    /// Delete a token record (used on burn). No-op if already absent.
    fn delete_nft_token(
        &self,
        _collection_id: &sigil_core::nft::CollectionId,
        _token_id: sigil_core::nft::TokenId,
    ) -> Result<(), NodeError> ;

    /// Return all `OwnerIndexEntry` records for `owner_did`, paged.
    ///
    /// `limit = 0` means "return all". Entries are returned in insertion order.
    fn list_nfts_by_owner(
        &self,
        _owner_did: &str,
        _limit: usize,
        _offset: usize,
    ) -> Result<Vec<sigil_core::nft::OwnerIndexEntry>, NodeError> ;

    /// Upsert the owner-index entry for `(collection_id, owner_did)`.
    fn put_owner_index_entry(
        &self,
        _entry: sigil_core::nft::OwnerIndexEntry,
    ) -> Result<(), NodeError> ;

    /// Remove a token from the owner-index entry for `(collection_id, owner_did)`.
    ///
    /// If the resulting token list is empty, the entry may be deleted.
    fn remove_owner_index_entry(
        &self,
        _collection_id: &sigil_core::nft::CollectionId,
        _owner_did: &str,
        _token_id: sigil_core::nft::TokenId,
    ) -> Result<(), NodeError> ;

    /// Fetch the DID-identity index for `subject_did`, or `None`.
    fn get_did_identity_nft(
        &self,
        _subject_did: &str,
    ) -> Result<Option<sigil_core::nft::DidIdentityIndex>, NodeError> ;

    /// Upsert the DID-identity index for a subject.
    fn put_did_identity_nft(
        &self,
        _index: sigil_core::nft::DidIdentityIndex,
    ) -> Result<(), NodeError> ;

    /// Remove a `(collection_id, token_id)` pair from the DID-identity index.
    ///
    /// Used on burn of an identity token. No-op if not present.
    fn remove_did_identity_nft(
        &self,
        _subject_did: &str,
        _collection_id: &sigil_core::nft::CollectionId,
        _token_id: sigil_core::nft::TokenId,
    ) -> Result<(), NodeError> ;

    /// Append an NFT lifecycle event to the event log. Returns the
    /// assigned monotonic sequence number.
    fn append_nft_event(&self, _event: sigil_core::nft::NftEvent) -> Result<u64, NodeError> ;

    /// List NFT events, optionally filtered by collection. Default returns
    /// empty.
    fn list_nft_events(
        &self,
        _collection_id: Option<&sigil_core::nft::CollectionId>,
    ) -> Result<Vec<sigil_core::nft::NftEvent>, NodeError> ;

    /// Commit a [`crate::nft_durable::NftWriteBatch`] atomically.
    ///
    /// This is the **only** write path that NFT transaction handlers must use.
    /// All mutations accumulated inside the batch are applied in a single MVCC
    /// transaction (when backed by AkashaKV) so a crash mid-handler leaves no
    /// partial state behind.
    ///
    /// Default implementation: **fail closed** — callers must explicitly
    /// override this method for any backend that actually persists NFT state.
    /// `MemoryExecutionState` overrides it to dispatch through the durable
    /// store when one is installed, or to apply ops sequentially in-memory.
    fn commit_nft_tx(&self, _batch: crate::nft_durable::NftWriteBatch) -> Result<(), NodeError> ;

    /// Commit a [`crate::compute_durable::ComputeWriteBatch`] atomically.
    ///
    /// This is the **only** write path that compute marketplace transaction
    /// handlers must use. All mutations accumulated inside the batch are
    /// applied in a single AkashaKV MVCC transaction so a crash mid-handler
    /// leaves no partial state behind.
    ///
    /// Default implementation: **fail closed** — callers must explicitly
    /// override this method for any backend that actually persists compute
    /// state. `MemoryExecutionState` overrides it to dispatch through the
    /// durable store when one is installed, or to apply ops sequentially
    /// in-memory.
    #[cfg(feature = "compute")]
    fn commit_compute_tx(
        &self,
        _batch: crate::compute_durable::ComputeWriteBatch,
    ) -> Result<(), NodeError> ;

    /// Commit a [`crate::contract_durable::ContractWriteBatch`] atomically.
    ///
    /// This is the **only** write path that contract transaction handlers must
    /// use. All mutations accumulated in the batch (contract records, keyed
    /// state, code blobs, zones, events, cross-zone messages) are applied in a
    /// single AkashaKV MVCC transaction so a crash mid-handler leaves no
    /// partial state behind.
    ///
    /// Default implementation: **fail closed** — callers must explicitly
    /// override this method for any backend that actually persists contract
    /// state. `MemoryExecutionState` overrides it to dispatch through the
    /// AkashaKV durable store when one is installed, or to apply ops
    /// sequentially in-memory (test/dev only, no crash-safety guarantee).
    #[cfg(feature = "contracts")]
    fn commit_contract_tx(
        &self,
        _batch: crate::contract_durable::ContractWriteBatch,
    ) -> Result<(), NodeError> ;

    // -- Tower (Casper FFG epoch finality) — core consensus, unconditional ----
    //
    // Tower is not feature-gated. Every node must be able to read and write
    // Tower finality state. Default implementations fail closed so that
    // callers see a clear error rather than silent data loss when the backend
    // has not yet wired Tower storage. `MemoryExecutionState` overrides all
    // of these to dispatch through the AkashaKV durable store when one is
    // installed, or to return the fail-closed error otherwise.

    /// Fetch a Tower validator record by DID. Returns `None` if not found.
    fn get_tower_validator(
        &self,
        _did: &str,
    ) -> Result<Option<sigil_tower::types::ValidatorRecord>, NodeError> ;

    /// Insert or replace a Tower validator record.
    fn put_tower_validator(
        &self,
        _record: sigil_tower::types::ValidatorRecord,
    ) -> Result<(), NodeError> ;

    /// Return all Tower validator records.
    fn list_tower_validators(&self) -> Result<Vec<sigil_tower::types::ValidatorRecord>, NodeError> ;

    /// Fetch accepted Tower slashing evidence by evidence hash.
    fn get_tower_evidence(
        &self,
        _evidence_hash: &SigilHash,
    ) -> Result<Option<sigil_tower::types::SlashingEvidence>, NodeError> ;

    /// Fetch a finality checkpoint by epoch. Returns `None` if not found.
    fn get_tower_checkpoint(
        &self,
        _epoch: u64,
    ) -> Result<Option<sigil_tower::types::FinalityCheckpoint>, NodeError> ;

    /// Insert or replace a finality checkpoint.
    fn put_tower_checkpoint(
        &self,
        _cp: sigil_tower::types::FinalityCheckpoint,
    ) -> Result<(), NodeError> ;

    /// Fetch the persisted finality state snapshot (justified/finalized epoch
    /// highwater marks). Returns `None` on a fresh store.
    fn get_tower_finality_state(
        &self,
    ) -> Result<Option<crate::tower_durable::FinalityStateSnapshot>, NodeError> ;

    /// Persist the finality state snapshot.
    fn put_tower_finality_state(
        &self,
        _snap: crate::tower_durable::FinalityStateSnapshot,
    ) -> Result<(), NodeError> ;

    /// Store a Casper FFG attestation (vote) for `(target_epoch, voter_did)`.
    fn put_tower_attestation(
        &self,
        _vote: sigil_tower::types::FinalityVote,
    ) -> Result<(), NodeError> ;

    /// Return all attestations cast for `epoch`.
    fn list_tower_attestations_for_epoch(
        &self,
        _epoch: u64,
    ) -> Result<Vec<sigil_tower::types::FinalityVote>, NodeError> ;

    /// Mark `epoch` as justified.
    fn tower_mark_justified(&self, _epoch: u64) -> Result<(), NodeError> ;

    /// Mark `epoch` as finalized.
    fn tower_mark_finalized(&self, _epoch: u64) -> Result<(), NodeError> ;

    /// Returns `true` if `epoch` has been marked finalized.
    fn tower_is_epoch_finalized(&self, _epoch: u64) -> Result<bool, NodeError> ;

    /// Return all epoch numbers that have been finalized, in ascending order.
    fn list_tower_finalized_epochs(&self) -> Result<Vec<u64>, NodeError> ;

    /// Apply all operations in `batch` atomically via a single AkashaKV MVCC
    /// transaction. Fail closed when no durable Tower store is wired.
    fn commit_tower_tx(
        &self,
        _batch: crate::tower_durable::TowerWriteBatch,
    ) -> Result<(), NodeError> ;

    /// Apply all governance operations in `batch` atomically via a single
    /// AkashaKV MVCC transaction. Fail closed when no durable Governance store
    /// is wired — ensures proposal creation and vote recording never leave
    /// partial state on disk.
    fn commit_governance_tx(
        &self,
        _batch: crate::governance_durable::GovernanceWriteBatch,
    ) -> Result<(), NodeError> ;

    /// Apply all labor operations in `batch` atomically via a single AkashaKV
    /// MVCC transaction. Fail closed when no durable Labor store is wired —
    /// ensures contract creation and milestone release never leave partial
    /// state on disk.
    fn commit_labor_tx(
        &self,
        _batch: crate::labor_durable::LaborWriteBatch,
    ) -> Result<(), NodeError> ;

    // -- Username state -----------------------------------------------------
    //
    // Default impls return None / empty / default-params / fail-closed so that
    // every existing test backend keeps compiling. Production
    // `MemoryExecutionState` overrides these to route through
    // `DurableUsernameStore` and the in-memory mirror.

    /// Username system parameters (length-tier prices, multipliers, reserved
    /// list, dispute multisig DIDs). Default returns
    /// `UsernameParams::default()` for backward compatibility.
    fn username_params(&self) -> sigil_core::username::UsernameParams ;

    /// Fetch a username record by canonical name. Default returns `None`.
    fn username_get(
        &self,
        _canonical_name: &str,
    ) -> Result<Option<sigil_core::username::UsernameRecord>, NodeError> ;

    /// Look up a DID's primary `@username`. Default returns `None`.
    fn username_lookup_reverse(&self, _owner_did: &str) -> Result<Option<String>, NodeError> ;

    /// List all username records owned by `owner_did`. Default returns empty.
    fn username_list_for_owner(
        &self,
        _owner_did: &str,
    ) -> Result<Vec<sigil_core::username::UsernameRecord>, NodeError> ;

    /// Search usernames by ASCII prefix, returning up to `limit` rows. The
    /// default returns empty so backends without a username index do not
    /// silently return wrong data.
    fn username_search_prefix(
        &self,
        _prefix: &str,
        _limit: usize,
    ) -> Result<Vec<sigil_core::username::UsernameRecord>, NodeError> ;

    /// Fetch a premium-name auction by canonical name. Default returns `None`.
    fn username_auction_get(
        &self,
        _canonical_name: &str,
    ) -> Result<Option<sigil_core::username::UsernameAuction>, NodeError> ;

    /// List all open premium-name auctions. Default returns empty.
    fn username_auctions_list_open(
        &self,
    ) -> Result<Vec<sigil_core::username::UsernameAuction>, NodeError> ;

    /// Fetch a username dispute by deterministic dispute ID. Default returns
    /// `None` so backends without username disputes fail closed in handlers.
    fn username_dispute_get(
        &self,
        _dispute_id: &str,
    ) -> Result<Option<sigil_core::username::UsernameDispute>, NodeError> ;

    /// List all currently-filed (unresolved) username disputes. Default empty.
    fn username_disputes_list_open(
        &self,
    ) -> Result<Vec<sigil_core::username::UsernameDispute>, NodeError> ;

    /// Apply all username operations in `batch` atomically. Fail closed when
    /// no username state is wired so the executor cannot silently no-op.
    fn commit_username_tx(
        &self,
        _batch: crate::username_durable::UsernameWriteBatch,
    ) -> Result<(), NodeError> ;

    // -- Sigil Mail + SNS state --------------------------------------------
    //
    // Defaults return empty/fail-closed so tests with custom state backends
    // keep compiling while production `MemoryExecutionState` wires durable
    // AkashaKV-backed storage.

    fn mail_get_mailbox(
        &self,
        _mailbox_id: &str,
    ) -> Result<Option<sigil_core::mail::MailboxCapabilityRecord>, NodeError> ;

    fn mail_list_mailboxes_by_owner(
        &self,
        _subject_did: &str,
    ) -> Result<Vec<sigil_core::mail::MailboxCapabilityRecord>, NodeError> ;

    fn mail_get_policy(
        &self,
        _mailbox_id: &str,
        _version: Option<u64>,
    ) -> Result<Option<sigil_core::mail::MailboxPolicyRecord>, NodeError> ;

    fn mail_get_keys(
        &self,
        _mailbox_id: &str,
        _purpose: Option<&str>,
    ) -> Result<Vec<sigil_core::mail::MailPublicKeyRecord>, NodeError> ;

    fn mail_get_delivery(
        &self,
        _delivery_commitment_id: &str,
    ) -> Result<Option<sigil_core::mail::DeliveryCommitmentRecord>, NodeError> ;

    fn mail_has_nonce(&self, _actor_did: &str, _nonce: &str) -> Result<bool, NodeError> ;

    fn mail_list_deliveries_by_recipient(
        &self,
        _mailbox_id: &str,
    ) -> Result<Vec<sigil_core::mail::DeliveryCommitmentRecord>, NodeError> ;

    fn mail_list_deliveries_by_sender(
        &self,
        _sender_route_id: &str,
    ) -> Result<Vec<sigil_core::mail::DeliveryCommitmentRecord>, NodeError> ;

    fn mail_get_delegation(
        &self,
        _grant_id: &str,
    ) -> Result<Option<sigil_core::mail::MailDelegationGrant>, NodeError> ;

    fn mail_list_delegations(
        &self,
        _mailbox_id: &str,
    ) -> Result<Vec<sigil_core::mail::MailDelegationGrant>, NodeError> ;

    fn mail_get_abuse_report(
        &self,
        _abuse_report_id: &str,
    ) -> Result<Option<sigil_core::mail::AbuseReport>, NodeError> ;

    fn sns_get_name(
        &self,
        _name_hash: &str,
    ) -> Result<Option<sigil_core::sns::SnsNameRecord>, NodeError> ;

    fn sns_get_records(
        &self,
        _name_hash: &str,
    ) -> Result<Vec<sigil_core::sns::SnsResolverRecord>, NodeError> ;

    fn sns_get_registration_commitment(
        &self,
        _commitment: &str,
    ) -> Result<Option<sigil_core::sns::SnsNameRegistrationCommitment>, NodeError> ;

    fn sns_get_sealed_bid(
        &self,
        _commitment: &str,
    ) -> Result<Option<sigil_core::sns::SnsSealedBidCommitment>, NodeError> ;

    fn sns_get_auction(
        &self,
        _auction_id: &str,
    ) -> Result<Option<sigil_core::sns::SnsAuctionRecord>, NodeError> ;

    fn commit_mail_tx(&self, _batch: crate::mail_durable::MailWriteBatch) -> Result<(), NodeError> ;

    // -- Recovery state -----------------------------------------------------
    //
    // Default impls return None / fail-closed so existing test backends
    // keep compiling without changes. Production `MemoryExecutionState`
    // overrides them to route through the durable AkashaKV-backed store
    // and the in-memory mirror.

    fn recovery_config_get(
        &self,
        _subject_did: &str,
    ) -> Result<Option<sigil_core::recovery::RecoveryConfig>, NodeError> ;

    fn recovery_ceremony_get(
        &self,
        _ceremony_id: &str,
    ) -> Result<Option<sigil_core::recovery::RecoveryCeremony>, NodeError> ;

    fn recovery_active_for(&self, _subject_did: &str) -> Result<Option<String>, NodeError> ;

    fn commit_recovery_tx(
        &self,
        _batch: crate::recovery_durable::RecoveryWriteBatch,
    ) -> Result<(), NodeError> ;
}

Source line: 368.

executor::DaoValidatorBacking

Backing for DAO Work OS state-transition validators. Always present in the type system (so default-feature builds compile and always match the protected transactions explicitly), but only carries a context when the dao-validators feature is enabled and a context was supplied.

Default = Disabled → protected DAO transactions fail closed. Wired(ctx) → protected DAO transactions consume ctx to look up pre-built [crate::executor_dao::GalSnapshot]s.

#[derive(Clone, Copy)]
pub struct DaoValidatorBacking<'a> {

}

Source line: 2692.

executor::DaoValidatorBacking<'a>::disabled

Disabled backing: protected DAO transactions fail closed.

pub const fn disabled() -> Self;

Source line: 2701.

executor::DaoValidatorBacking<'a>::wired

Wire a DAO validator context. Only available when dao-validators is enabled.

#[cfg(feature = "dao-validators")]
pub const fn wired(ctx: &'a crate::executor_dao::DaoValidatorContext) -> Self;

Source line: 2713.

executor::DaoValidatorBacking<'a>::context

Borrow the wired context, if any.

#[cfg(feature = "dao-validators")]
pub const fn context(&self) -> Option<&'a crate::executor_dao::DaoValidatorContext>;

Source line: 2719.

executor::build_dao_validator_context

Build the deterministic DAO validator context consumed by production block execution. The builder reads only ExecutionState; it performs no I/O, no RNG, and no clock reads.

#[cfg(feature = "dao-validators")]
pub fn build_dao_validator_context(
    state: &dyn ExecutionState,
) -> Result<crate::executor_dao::DaoValidatorContext, NodeError>;

Source line: 2734.

executor::execute_block

Execute all transactions in a block, producing receipts. Production entry point wires state-derived DAO/labor validator backing when the dao-validators feature is compiled in.

pub fn execute_block(
    block: &Block,
    state: &dyn ExecutionState,
    expected_chain_id: &str,
) -> Result<Vec<Receipt>, NodeError>;

Source line: 2743.

executor::execute_block_with_dao_backing

Execute all transactions in a block with an explicit DAO validator backing. Use [DaoValidatorBacking::wired] (feature-gated) when the block contains protected DAO transactions.

pub fn execute_block_with_dao_backing(
    block: &Block,
    state: &dyn ExecutionState,
    expected_chain_id: &str,
    dao: DaoValidatorBacking<'_>,
) -> Result<Vec<Receipt>, NodeError>;

Source line: 2773.

On this page