Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ edition = "2021"
# the ROOT manifest (`[workspace.package].version`), so it MUST be set here for a
# release to fire (§3.6). The library crates (dig-node-core/dig-runtime/dig-wallet)
# keep their own independent versions — only the released binary tracks the workspace version.
version = "0.252.2"
version = "0.252.3"

# Release hardening, matching digstore: keep integer-overflow checks ON in release.
# The node parses untrusted serialized input and does offset/length arithmetic over
Expand Down
11 changes: 11 additions & 0 deletions SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -8974,6 +8974,17 @@ a stolen bond.
so a node MUST bound the number of bonds it reads against a chain per locate, verifying in source
order and leaving the remainder at baseline.

**A `bonded` verdict MUST rest on AGREEMENT across independently drawn, concurrently-held untrusted
peers -- never on one source.** The §25.6 checks establish that a coin and its creating spend are
internally consistent; none of them establishes that the coin was ever on chain. A coin currying the
real, public $DIG CAT puzzle around an invented parent satisfies every one of them, so a verdict
taken from a single provider promotes a bond that does not exist, at no collateral cost to whoever
published it. The two reads that decide the verdict -- the coin record, and the spend that created
it -- MUST each be corroborated: below the corroboration floor, or on disagreement, the verdict is
`unverified` and MUST NOT be `bonded`. A node MUST NOT fall back to a single source when
corroboration is unavailable, because falling through to one endpoint exactly when the peers failed
to agree lets that endpoint overrule them.

The verification is performed in the ORDER §25.6 states, with one refinement that is normative: the
`advertises` binding is checked BEFORE the collateral magnitude. A node that has not censused the
epoch cannot price a bond, and checking magnitude first would make every verdict on such a node
Expand Down
15 changes: 13 additions & 2 deletions crates/dig-node-service/src/mirror/bond_verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,12 +392,23 @@ impl ChainBondVerifier {
claiming_peer_id: &str,
coin_id: [u8; 32],
) -> BondVerdict {
// Corroborated, never the router (dig-node#503). `chain_source` asks `api.coinset.org`
// first and consults this node's peers only when that read fails -- its own `ProviderInfo`
// says `trustless: false` -- so a `Bonded` verdict taken from it rests on ONE source's
// word. Every check below is internal consistency of a coin and its creating spend, and
// all of them pass on a coin curried around an invented parent that was never on mainnet.
// Only chain MEMBERSHIP disproves that, and membership is what a single endpoint cannot
// settle.
//
// No fallback here, deliberately: `corroborated_chain_source` errs rather than handing
// back the router, and this reads that as `Unverified`. Falling back would let one
// endpoint overrule the peers exactly when they failed to agree.
//
// Re-read per call rather than held from bring-up, matching the mirror pass: a transport
// built once would make a node that started offline one that never verifies again.
Comment thread
MichaelTaylor3d marked this conversation as resolved.
let Ok(source) = self
.chain
.chain_source(tokio::runtime::Handle::current())
.await
.corroborated_chain_source(tokio::runtime::Handle::current())
else {
return BondVerdict::Unverified;
};
Expand Down
Loading
Loading