This document maps the currently implemented DataKey storage used by
contracts/escrow/src/lib.rs. A fuller key-by-key reference, including
declared-but-unused keys, is tracked in
#342.
These participant indexes are append-only: every create_contract appends the new id to the appropriate index vectors.
The contract list readers (list_contracts_by_participant) are therefore consistent with contract creation order.
| Key | Value | Written by |
|---|---|---|
Initialized |
bool |
initialize |
Admin |
Address |
initialize |
Paused |
bool |
pause, unpause, emergency controls |
Emergency |
bool |
emergency controls |
Contract(id) |
EscrowContractData |
create/deposit/release/reputation/cancel |
NextContractId |
u32 |
create_contract |
ReputationIssued(id) |
bool |
issue_reputation |
PendingReputationCredits(address) |
u32 |
final release, issue_reputation |
Reputation(address) |
ReputationRecord |
issue_reputation |
Finalization(id) |
FinalizationRecord |
finalize_contract |
ReadinessChecklist |
ReadinessChecklist |
initialize and emergency controls |
ClientContracts(address) |
Vec<u32> |
create_contract |
FreelancerContracts(address) |
Vec<u32> |
create_contract |
These keys are declared in types.rs but no public entrypoint currently uses
them as a complete feature:
MilestoneApprovalsPendingClientMigrationProtocolFeeBpsAccumulatedProtocolFees
Protocol fee implementation is tracked in #313 and #314.
release_milestone sets milestone.released = true inside the persisted
Vec<Milestone> stored under (DataKey::Contract(id), "milestones").
summarize_contract (called by finalize_contract) derives
released_milestone_count by iterating that same vector and counting
ms.released == true. There is no separate DataKey::MilestoneReleased
key — that variant was removed in fix [#416] because it was never written,
causing released_milestone_count to always report zero in finalization
summaries.
Read and write path are now identical: the milestone vector is the sole authority for released state.
PendingReputation(Address)/ReputationIssued(u32)- Description: Bookkeeping indices capturing un-issued tokens and completion certificates for network participants.
- Storage Lifespan:
Persistent. Preserved explicitly to guarantee deterministic chronological processing when users harvest pending system values.
NextContractId is the monotonic counter used by create_contract to assign
unique, gap-free ids. The allocation path in
contracts/escrow/src/create_contract.rs upholds the following invariants:
-
Single allocation per create.
next_contract_idis called exactly once percreate_contractinvocation. The first call reads the counter and checks the target slot; there is no second call that could shadow the first or trigger a double collision check. -
Atomic counter advance.
bump_next_contract_idwritesid + 1to persistent storage only after the contract and milestone entries have been persisted. If the write fails, the counter is not advanced. -
Overflow protection.
bump_next_contract_iduseschecked_add(1). If the counter is alreadyu32::MAX, the function panics withError::ContractIdOverflowbefore writing anything. The counter is left unchanged. -
Collision protection.
next_contract_idreads the candidate id and immediately checks whether aContractentry already exists at that key. If one does, it panics withError::ContractIdCollision. The counter is left unchanged. -
Sequential, gap-free ids. Because the counter starts at
1and is advanced by exactly 1 on every successful create, allocated ids form a contiguous sequence1, 2, 3, …. Id0is never issued and is reserved as a sentinel "not found" value for off-chain indexers. -
No id reuse. Once a
Contract(id)entry is written to persistent storage it is never deleted by any existing entrypoint, so the collision check innext_contract_idpermanently blocks reuse of that id.
These invariants are verified by the test suite in
contracts/escrow/src/test/contract_id_allocation.rs.
- Contract ids are monotonically assigned from
NextContractId. - Milestone amounts and participant addresses are immutable after creation.
total_deposited,released_amount, andrefunded_amountare checked after balance-changing operations.- A milestone release flag can move from absent/false to true only once.
- Reputation issuance is guarded by
ReputationIssued(contract_id).