mars-protocol · anchor
Public declarations and documentation for mars-protocol::anchor.
Package: mars-protocol · Workspace version: 0.1.0 · Module: anchor
This reference follows declared modules and public syntax, including public implementation methods. Function bodies and constant values are omitted. Feature conditions are retained. Private-module re-exports and trait resolution require the compiler; not every declaration is a root import.
Module condition
#[cfg(feature = "sigil")]anchor::AnchorRecord
A confirmed on-chain anchor for a MARS entry.
Created after a transaction is committed to the Sigil blockchain, this record links a MARS entry to a specific block and transaction hash, and optionally includes a Merkle proof for independent verification.
#[cfg(feature = "sigil")]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "contracts", derive(schemars::JsonSchema, utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct AnchorRecord {
/// DID of the anchored entry.
pub entry_did: String,
/// SHA-256 content hash of the entry's `item_data`.
pub item_data_hash: String,
/// Block height at which the anchor was committed.
pub block_height: u64,
/// Transaction hash on the Sigil chain.
pub tx_hash: String,
/// Timestamp when the anchor was created on-chain.
pub anchor_time: chrono::DateTime<chrono::Utc>,
/// Optional Merkle proof for independent verification.
#[serde(skip_serializing_if = "Option::is_none")]
pub proof: Option<MerkleProof>
}Source line: 24.
anchor::MerkleProof
A Merkle inclusion proof linking a leaf hash to a root hash.
Verifiers walk the path from the leaf_hash to the root, combining
each ProofNode in sequence according to its direction.
MARS Merkle Proof v1 encoding
root, leafHash, and every sibling hash are textual lowercase
hexadecimal SHA-256 digests. Each level hashes the UTF-8 bytes of the
concatenated left and right hexadecimal strings, then lowercase-hex
encodes the resulting digest before processing the next level. This is a
compatibility contract; it is intentionally not raw 32-byte digest
concatenation.
#[cfg(feature = "sigil")]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "contracts", derive(schemars::JsonSchema, utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct MerkleProof {
/// Merkle root hash.
pub root: String,
/// Ordered path of sibling hashes from leaf to root.
pub path: Vec<ProofNode>,
/// Hash of the leaf being proved.
pub leaf_hash: String
}Source line: 60.
anchor::ProofNode
A single node in a Merkle proof path.
#[cfg(feature = "sigil")]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "contracts", derive(schemars::JsonSchema, utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct ProofNode {
/// Sibling hash at this level of the tree.
pub hash: String,
/// Whether this sibling is to the left or right of the current node.
pub direction: Direction
}Source line: 77.
anchor::Direction
Direction of a sibling node in a Merkle proof path.
#[cfg(feature = "sigil")]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "contracts", derive(schemars::JsonSchema, utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub enum Direction {
/// Sibling is on the left.
Left,
/// Sibling is on the right.
Right,
}Source line: 92.
anchor::AnchorStatus
Status of an on-chain anchor operation.
#[cfg(feature = "sigil")]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "contracts", derive(schemars::JsonSchema, utoipa::ToSchema))]
#[serde(rename_all = "camelCase", tag = "status")]
pub enum AnchorStatus {
/// Transaction submitted but not yet confirmed.
Pending,
/// Transaction confirmed on-chain.
Confirmed,
/// Anchor operation failed.
Failed {
/// Human-readable failure reason.
reason: String,
},
}Source line: 107.
anchor::AnchorRequest
A request to anchor a MARS entry on the Sigil chain.
#[cfg(feature = "sigil")]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "contracts", derive(schemars::JsonSchema, utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct AnchorRequest {
/// DID of the entry to anchor.
pub entry_did: String,
/// SHA-256 content hash of the entry's `item_data`.
pub item_data_hash: String,
/// DID of the publisher submitting the anchor.
pub publisher_did: String,
/// Ed25519 signature over the canonical anchor payload.
pub signature: String
}Source line: 127.
anchor::AnchorResponse
Response to an anchor submission.
#[cfg(feature = "sigil")]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "contracts", derive(schemars::JsonSchema, utoipa::ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct AnchorResponse {
/// Transaction hash assigned by the Sigil chain.
pub tx_hash: String,
/// Current status of the anchor operation.
pub status: AnchorStatus
}Source line: 146.
anchor::verify_merkle_proof
Verify a Merkle proof by recomputing the root from the leaf hash.
Walks the proof path from leaf_hash to the root, hashing left/right
hexadecimal UTF-8 strings at each level using SHA-256. Returns true if
the recomputed lowercase-hex string matches proof.root. See
[MerkleProof] for the exact v1 encoding contract.
#[cfg(feature = "sigil")]
pub fn verify_merkle_proof(proof: &MerkleProof) -> bool;Source line: 163.
anchor::AnchorError
Errors returned by [SigilAnchorClient].
#[cfg(feature = "sigil")]
#[derive(Debug, thiserror::Error)]
pub enum AnchorError {
/// Network / transport failure.
#[error("transport error: {0}")]
Transport(String),
/// The Sigil node returned a JSON-RPC error.
#[error("sigil rpc error: {code}: {message}")]
Rpc {
/// JSON-RPC error code.
code: i64,
/// Human-readable message.
message: String,
},
/// Anchor submission rejected by the chain.
#[error("anchor rejected: {0}")]
Rejected(String),
/// Invalid response payload.
#[error("invalid response: {0}")]
InvalidResponse(String),
}Source line: 202.
anchor::SigilAnchorClient
Async client that mediates real Sigil RPC anchor submission and queries.
Resolvers MUST call [check_revocation] first on every resolution path —
the revocation-first invariant from the GAL design doc. The trait does
not enforce that ordering; the caller does.
All query methods return Option<serde_json::Value> (or
serde_json::Value for the topology snapshot) so this crate can stay
free of a sigil-core dependency. Higher layers (sigil-sdk,
oas-resolve) deserialize into the canonical typed records.
#[cfg(feature = "sigil")]
#[async_trait::async_trait]
pub trait SigilAnchorClient: Send + Sync {
/// Submit a MARS entry anchor to the Sigil chain.
async fn submit_anchor(&self, req: AnchorRequest) -> Result<AnchorResponse, AnchorError>;
/// Fetch the typed `HmrAnchor` JSON for a DID, or `None` if absent.
async fn get_hmr(&self, did: &str) -> Result<Option<serde_json::Value>, AnchorError>;
/// Fetch the typed `MhrAnchor` JSON for a DID, or `None` if absent.
async fn get_mhr(&self, did: &str) -> Result<Option<serde_json::Value>, AnchorError>;
/// Fetch the typed `EnrAnchor` JSON for a DID, or `None` if absent.
async fn get_enr(&self, did: &str) -> Result<Option<serde_json::Value>, AnchorError>;
/// Fetch the typed `OrgLineageRoot` JSON for an org DID, or `None` if
/// absent.
async fn get_org_root(&self, org_did: &str) -> Result<Option<serde_json::Value>, AnchorError>;
/// Fetch the `ShardAssignment` (and any topology lineage) for a subject
/// DID, or `None` if absent.
async fn get_shard_assignment(
&self,
did: &str,
) -> Result<Option<serde_json::Value>, AnchorError>;
/// **Revocation-first**: fetch the `RevocationStatus` JSON for a DID.
/// Always succeeds; an unrevoked DID returns
/// `{ "revoked": false, "record": null }`.
async fn check_revocation(&self, did: &str) -> Result<serde_json::Value, AnchorError>;
/// Fetch the full `ShardTopologyEntry` snapshot.
async fn get_shard_topology(&self) -> Result<serde_json::Value, AnchorError>;
}Source line: 233.
anchor::MockSigilAnchorClient
Deterministic in-memory SigilAnchorClient impl for development and
integration tests.
Building a release with --features prod and --features mock-anchor
triggers a top-of-crate compile_error!, so the mock cannot ship to
production by accident.
#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub struct MockSigilAnchorClient {
}Source line: 277.
anchor::MockSigilAnchorClient::new
Create an empty mock client.
#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn new() -> Self;Source line: 305.
anchor::MockSigilAnchorClient::insert_hmr
Pre-populate an HMR record at the given DID.
#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn insert_hmr(&self, did: &str, record: serde_json::Value) -> Result<(), AnchorError>;Source line: 316.
anchor::MockSigilAnchorClient::insert_mhr
Pre-populate an MHR record.
#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn insert_mhr(&self, did: &str, record: serde_json::Value) -> Result<(), AnchorError>;Source line: 322.
anchor::MockSigilAnchorClient::insert_enr
Pre-populate an ENR record.
#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn insert_enr(&self, did: &str, record: serde_json::Value) -> Result<(), AnchorError>;Source line: 328.
anchor::MockSigilAnchorClient::insert_org_root
Pre-populate an org lineage root.
#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn insert_org_root(
&self,
org_did: &str,
record: serde_json::Value,
) -> Result<(), AnchorError>;Source line: 334.
anchor::MockSigilAnchorClient::insert_shard_assignment
Pre-populate a shard assignment.
#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn insert_shard_assignment(
&self,
did: &str,
record: serde_json::Value,
) -> Result<(), AnchorError>;Source line: 346.
anchor::MockSigilAnchorClient::insert_revocation
Mark a DID as revoked.
#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn insert_revocation(
&self,
did: &str,
record: serde_json::Value,
) -> Result<(), AnchorError>;Source line: 356.
anchor::MockSigilAnchorClient::set_topology
Set the full topology snapshot.
#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn set_topology(&self, snapshot: serde_json::Value) -> Result<(), AnchorError>;Source line: 369.
anchor::MockSigilAnchorClient::anchor_for
Look up an anchor record by entry DID (for tests).
#[cfg(feature = "sigil")]
#[cfg(feature = "mock-anchor")]
pub fn anchor_for(&self, entry_did: &str) -> Result<Option<AnchorRecord>, AnchorError>;Source line: 375.
Source provenance
Source: mars-protocol/src/anchor.rs · SHA-256 01fe89586dcca37ad30197952dad161545b2d648d1e90aa403645af3fefe9f7a. Package overview.