Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
02eb48a
feat: start of work
QuantumExplorer Feb 9, 2026
e4c1cf0
transactions
QuantumExplorer Feb 10, 2026
a4ad035
more work
QuantumExplorer Feb 10, 2026
f27fe8e
more work
QuantumExplorer Feb 10, 2026
0a833ef
more work
QuantumExplorer Feb 10, 2026
cf9fafa
more work
QuantumExplorer Feb 10, 2026
ce10a55
more work
QuantumExplorer Feb 10, 2026
f2c238a
more work
QuantumExplorer Feb 11, 2026
d72958a
more work
QuantumExplorer Feb 11, 2026
5c34e02
more work
QuantumExplorer Feb 11, 2026
fc3ef9b
more work
QuantumExplorer Feb 11, 2026
048c3aa
more work
QuantumExplorer Feb 11, 2026
58056fb
more work
QuantumExplorer Feb 11, 2026
99342bc
more work
QuantumExplorer Feb 12, 2026
0f5c1fe
more work
QuantumExplorer Feb 12, 2026
404891d
more work
QuantumExplorer Feb 16, 2026
06f3295
Merge branch 'v3.1-dev' into feat/zk
QuantumExplorer Feb 16, 2026
b92b6fe
more work
QuantumExplorer Feb 17, 2026
c83730b
more work
QuantumExplorer Feb 17, 2026
ecd5804
more work
QuantumExplorer Feb 17, 2026
66c8230
more work
QuantumExplorer Feb 17, 2026
58f9a7d
fix encrypted notes
QuantumExplorer Feb 18, 2026
c817f70
more work
QuantumExplorer Feb 18, 2026
24df230
more work
QuantumExplorer Feb 18, 2026
aa9af75
more work
QuantumExplorer Feb 18, 2026
220fb79
more work
QuantumExplorer Feb 19, 2026
737d6c2
work on nullifiers
QuantumExplorer Feb 23, 2026
a4c4871
more work
QuantumExplorer Feb 23, 2026
1a08a9a
more work
QuantumExplorer Feb 24, 2026
506ee63
Merge branch 'v3.1-dev' into feat/zk
QuantumExplorer Feb 24, 2026
4f2b77b
more work
QuantumExplorer Feb 24, 2026
4d7b9be
small fix
QuantumExplorer Feb 24, 2026
34da9a1
more work
QuantumExplorer Feb 25, 2026
7313bc0
more work
QuantumExplorer Feb 25, 2026
ed89b5b
more work
QuantumExplorer Feb 25, 2026
7a2ef75
Merge branch 'v3.1-dev' into feat/zk
QuantumExplorer Feb 25, 2026
24fea3c
more work
QuantumExplorer Feb 25, 2026
415ee8b
more work
QuantumExplorer Feb 25, 2026
1f94fe2
more work
QuantumExplorer Feb 25, 2026
ca9dd7e
more work
QuantumExplorer Feb 25, 2026
4aa8b93
fix
QuantumExplorer Feb 25, 2026
48aa2d4
more work
QuantumExplorer Feb 26, 2026
eacf972
more work
QuantumExplorer Feb 26, 2026
e0ffccd
more work
QuantumExplorer Feb 27, 2026
813736b
more work
QuantumExplorer Mar 1, 2026
e6e24cc
more work
QuantumExplorer Mar 2, 2026
048218c
Merge branch 'v3.1-dev' into feat/zk
QuantumExplorer Mar 4, 2026
acd1949
fixes
QuantumExplorer Mar 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
599 changes: 573 additions & 26 deletions Cargo.lock

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,35 @@ key-wallet = { git = "https://github.com/dashpay/rust-dashcore", rev = "0bc6592b
key-wallet-manager = { git = "https://github.com/dashpay/rust-dashcore", rev = "0bc6592bd41037ffc532d813d4c0828bea7cf882" }
dashcore-rpc = { git = "https://github.com/dashpay/rust-dashcore", rev = "0bc6592bd41037ffc532d813d4c0828bea7cf882" }

# Optimize heavy crypto crates even in dev/test builds so that
# Halo 2 proof generation and verification run at near-release speed.
# Without this, ZK operations are 10-100x slower (debug field arithmetic).
[profile.dev.package.halo2_proofs]
opt-level = 3
[profile.dev.package.halo2_gadgets]
opt-level = 3
[profile.dev.package.halo2_poseidon]
opt-level = 3
[profile.dev.package.orchard]
opt-level = 3
[profile.dev.package.pasta_curves]
opt-level = 3
[profile.dev.package.grovedb-commitment-tree]
opt-level = 3

[profile.test.package.halo2_proofs]
opt-level = 3
[profile.test.package.halo2_gadgets]
opt-level = 3
[profile.test.package.halo2_poseidon]
opt-level = 3
[profile.test.package.orchard]
opt-level = 3
[profile.test.package.pasta_curves]
opt-level = 3
[profile.test.package.grovedb-commitment-tree]
opt-level = 3

[workspace.package]

version = "3.1.0-dev.1"
Expand Down
1 change: 1 addition & 0 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- [Validation Pipeline](state-transitions/validation-pipeline.md)
- [Transform Into Action](state-transitions/transform-into-action.md)
- [Drive Operations](state-transitions/drive-operations.md)
- [Return Proofs](state-transitions/return-proofs.md)

# Fees

Expand Down
182 changes: 182 additions & 0 deletions book/src/state-transitions/return-proofs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
# Return Proofs

After a state transition is confirmed in a block, clients can request a **return proof** —
a GroveDB Merkle proof demonstrating that the expected state changes were actually applied.
This lets light clients verify execution without trusting the node.

## How It Works

The flow is:

1. Client broadcasts a state transition via DAPI.
2. Client calls `waitForStateTransitionResult` with `prove: true`.
3. The node waits for the transition to be included in a block.
4. Drive deserializes the transition and calls `prove_state_transition()`.
5. This builds a `PathQuery` describing which GroveDB paths/keys the transition affected.
6. GroveDB generates a Merkle proof covering exactly those paths.
7. The proof is returned to the client in the response.

The client then calls `verify_state_transition_was_executed_with_proof()` to check the
proof against the known app hash (root hash). If verification succeeds, the client receives
a `StateTransitionProofResult` containing the verified data.

## Key Design Decisions

- **Minimal proofs.** Only the paths/keys affected by the transition are included, not the
entire state tree. This keeps proofs small.
- **Type-specific.** Each transition type proves different data — an identity create proves
the full identity, while a top-up only proves the new balance.
- **On-demand.** Proofs are generated after confirmation, not during validation.
- **Batch limitation.** Batch transitions (documents/tokens) currently support proofs only
for single-transition batches.
- **Limits removed.** All `PathQuery` limits are set to `None` before proof generation to
ensure the full result set is included.

## What Each Transition Proves

### Identity Transitions

| Transition | What's Proved | Verified Result |
|---|---|---|
| **IdentityCreate** | Full identity: data, balance, nonce, all public keys | `VerifiedIdentity(Identity)` |
| **IdentityTopUp** | Balance and revision only | `VerifiedPartialIdentity { balance, revision }` |
| **IdentityCreditWithdrawal** | Balance only | `VerifiedPartialIdentity { balance }` |
| **IdentityUpdate** | All public keys | `VerifiedPartialIdentity { loaded_public_keys }` |
| **IdentityCreditTransfer** | Sender balance + recipient balance | `VerifiedBalanceTransfer(sender, recipient)` |

The proof generation uses these Drive query helpers:

- `Drive::full_identity_query()` — identity tree + balance + nonce + all key subtree
- `Drive::revision_and_balance_path_query()` — just balance and revision elements
- `Drive::identity_balance_query()` — just the balance element
- `Drive::identity_all_keys_query()` — identity key subtree

For **IdentityCreditTransfer**, the sender and recipient balance queries are merged into
a single `PathQuery` via `PathQuery::merge()`.

### Identity + Address Transitions

| Transition | What's Proved | Verified Result |
|---|---|---|
| **IdentityCreditTransferToAddresses** | Identity balance/revision + recipient address balances | `VerifiedIdentityWithAddressInfos` |
| **IdentityCreateFromAddresses** | Full identity + all input/output address balances | `VerifiedIdentityFullWithAddressInfos` |
| **IdentityTopUpFromAddresses** | Identity balance/revision + input/output address balances | `VerifiedIdentityWithAddressInfos` |

These combine `Drive::revision_and_balance_path_query()` (or `full_identity_query()` for
create) with `Drive::balances_for_clear_addresses_query()`, merged into a single proof.

### Address Fund Transitions

| Transition | What's Proved | Verified Result |
|---|---|---|
| **AddressFundsTransfer** | All input + output address balances | `VerifiedAddressInfos` |
| **AddressFundingFromAssetLock** | All input + output address balances | `VerifiedAddressInfos` |
| **AddressCreditWithdrawal** | Input addresses + output address balance | `VerifiedAddressInfos` |

All use `Drive::balances_for_clear_addresses_query()`. Each address entry in the proof
contains its nonce and credit balance, allowing the client to verify post-transition
balances.

### Data Contract Transitions

| Transition | What's Proved | Verified Result |
|---|---|---|
| **DataContractCreate** | The contract itself | `VerifiedDataContract(DataContract)` |
| **DataContractUpdate** | The updated contract | `VerifiedDataContract(DataContract)` |

The query depends on whether the contract keeps history:
- Historical: `Drive::fetch_historical_contracts_query()`
- Non-historical: `Drive::fetch_non_historical_contracts_query()`

Verification reconstructs the contract from the proof and compares it field-by-field
against the state transition's contract data via `first_mismatch()`.

### Document Transitions (via Batch)

| Operation | What's Proved | Verified Result |
|---|---|---|
| **Create** | The created document | `VerifiedDocuments({ id: Some(doc) })` |
| **Replace** | The replaced document | `VerifiedDocuments({ id: Some(doc) })` |
| **Delete** | Absence of the document | `VerifiedDocuments({ id: None })` |
| **Transfer** | The document (with new owner) | `VerifiedDocuments({ id: Some(doc) })` |
| **UpdatePrice** | The document (with new price) | `VerifiedDocuments({ id: Some(doc) })` |
| **Purchase** | The document (with new owner) | `VerifiedDocuments({ id: Some(doc) })` |

All document operations use `SingleDocumentDriveQuery` to construct the path query.
For creates with prefunded voting balances, the query uses `Contested` status to look
up the document in the contested index tree instead of the regular document tree.

Verification checks:
- **Create/Replace:** Reconstructs the expected document from the transition and compares
fields (ignoring time-based fields and transient fields).
- **Delete:** Asserts the document is absent from the proof.
- **Transfer/Purchase:** Verifies the document's `owner_id` matches the expected recipient.
- **UpdatePrice:** Verifies the document's `price` field matches the transition's price.

### Token Transitions (via Batch)

Token proof behavior depends on whether the token keeps historical documents for that
operation type. When history is enabled, the proof contains a historical document in the
token history contract. When disabled, the proof contains the raw state (balance, info, etc.).

| Operation | History Off | History On |
|---|---|---|
| **Mint** | Recipient token balance | Historical mint document |
| **Burn** | Owner token balance | Historical burn document |
| **Transfer** | Sender + recipient balances | Historical transfer document |
| **Freeze** | Frozen identity's token info | Historical freeze document |
| **Unfreeze** | Unfrozen identity's token info | Historical unfreeze document |
| **DirectPurchase** | Purchaser token balance | Historical purchase document |
| **SetPriceForDirectPurchase** | Token pricing schedule | Historical pricing document |
| **DestroyFrozenFunds** | Always historical document | — |
| **EmergencyAction** | Always historical document | — |
| **ConfigUpdate** | Always historical document | — |
| **Claim** | Always historical document | — |

**Group actions** add an extra layer: when a token transition uses group consensus
(multi-sig), the proof also includes the group action's signer and total power, plus the
action status (active vs closed). The verified result becomes one of the
`VerifiedTokenGroupAction*` variants.

### Masternode Vote

| Transition | What's Proved | Verified Result |
|---|---|---|
| **MasternodeVote** | The vote poll state for the specific vote | `VerifiedMasternodeVote(Vote)` |

Uses `IdentityBasedVoteDriveQuery` to construct the path query from the voter's ProTxHash
and the resource vote poll. Verification checks the vote exists and matches expectations.

### Shielded Transitions

| Transition | Proof Generation | Proof Verification |
|---|---|---|
| **Shield** | Not yet supported | Verifies input address balances (`VerifiedAddressInfos`) |
| **Unshield** | Not yet supported | Verifies output address balance (`VerifiedAddressInfos`) |
| **ShieldedTransfer** | Not yet supported | Verifies shielded pool total balance (`VerifiedShieldedPoolState`) |
| **ShieldFromAssetLock** | Not yet supported | Verifies shielded pool total balance (`VerifiedShieldedPoolState`) |
| **ShieldedWithdrawal** | Not yet supported | Verifies shielded pool total balance (`VerifiedShieldedPoolState`) |

Proof generation currently returns an error for all shielded transitions. The verification
side has been implemented in anticipation:

- **Shield** verifies the input platform address balances were debited.
- **Unshield** verifies the output platform address balance was credited.
- **ShieldedTransfer, ShieldFromAssetLock, ShieldedWithdrawal** verify the shielded credit
pool's `total_balance` SumItem, confirming the pool balance changed as expected.

Note that shielded proofs intentionally do **not** reveal which notes were created or spent
(that would break privacy). Only aggregate pool state or transparent address balances are
provable.

## Code Locations

| Component | Path |
|---|---|
| Proof generation | `rs-drive/src/prove/prove_state_transition/v0/mod.rs` |
| Proof verification | `rs-drive/src/verify/state_transition/verify_state_transition_was_executed_with_proof/v0/mod.rs` |
| Proof result enum | `rs-dpp/src/state_transition/proof_result.rs` |
| DAPI wait service | `rs-dapi/src/services/platform_service/wait_for_state_transition_result.rs` |
| ABCI query handler | `rs-drive-abci/src/query/proofs/v0/mod.rs` |
| Shielded pool verify | `rs-drive/src/verify/shielded/verify_shielded_pool_state/v0/mod.rs` |
| Address balance verify | `rs-drive/src/verify/address_funds/verify_addresses_infos/v0/mod.rs` |
Loading
Loading