Execute economy-transition-v6 against a version-six ledger - #181
Merged
Conversation
… ledger The codec had no ledger, so it could not resolve an acting escrow, order the shared envelope checks, charge a fee, advance a nonce, or commit a root. This adds the state those need and the ten transitions that read no cycle assignment. A version-six state is a version-one state plus one ordered economy map, and the account map is keyed by escrow identifier with no second copy of a balance, which is what makes the first structural invariant checkable by comparing two key sets. Every conservation and structural check is an equality, because a bound would admit a defect that lost a term. Two derived orders from ADR 0045 are implemented where a reader will look for them rather than only in the ADR. DEBIT_OVERFLOW is returned inside envelope check 8, because check 8 tests the same sum kind 1's own step 5 tests and evaluating it afterwards would leave check 8 undefined on a sum that does not fit u64 and make code 7 unreachable. An unrequested confirmation field is refused at execution with UNAUTHORIZED, because the predicate reads a stored posture that admission cannot see and the result-code space has no MALFORMED_TRANSACTION. Kinds 2, 3, 4, and 5 read or write a cycle assignment and the version-three settlement is not in the kernel yet, so dispatch refuses to execute them rather than inventing a result. No conforming chain can run them until that lands. No cryptography is performed in the transition layer: the caller supplies a verifier, so a test exercises every UNAUTHORIZED path against a recorded table and production supplies the version-one strict Ed25519 check. Refs #180
…in C++ Requirement 11 for execution: the kernel runs five of the six recorded scenarios transaction for transaction and compares 394 of the 512 vectors in test-vectors/economy-transition-v6-execution.txt against what it derives. Nothing here computes a second set of expected values. Reproducing a recorded outcome means rebuilding the exact bytes that produced it. A transaction identifier is a digest over the signed bytes, so the fixture issues signature stand-ins in the model's own order, and an adopted signature consumes a number even though it was not issued -- getting that wrong was caught by a transaction root, which is the check working. Four checks reach a third source rather than a second opinion of the execution file: the ordered transaction tree and the accepted transfer against protocol-primitives-v1, the block header and identifier against ledger-transition-v1, the ten channel caps and five legs against founder-economy-manifest-v2, and the referral leg against economy-transition-v3. A coverage guard fails if any vector in a claimed section is never consulted, and it was demonstrated to fail when one check is removed. The three sections it defers -- block, cycle, ordering -- are named rather than skipped silently, and it fails if they ever become empty. The RFC 9162 tree is now one implementation serving the economy tree, the accounts tree, and version one's transaction tree, each pinned by a different accepted vector file. Refs #180
…eaches A mutation probe found this the honest way. Making signer_revoke accept a signer assigned to a different escrow changed nothing any recorded vector observes, so that refusal had no evidence behind it at all. Three kinds -- escrow create, escrow delete, and direct issue -- appear in no scenario either, and four shared envelope conditions are never exercised. These checks derive their own expectations rather than comparing against a vector file, because no vector records them. That is the opposite of the rule the scenario checks follow, which is why they live in their own translation unit: a reader must never have to wonder which kind of evidence an assertion carries. Covered: kind 13's four resolution conditions and its writes; kind 14's target and fee refusals, including the two that share ESCROW_NOT_EMPTY for different reasons, and the signer entries a deletion removes; the signer limit at sixteen and the cross-escrow revocation the probe found; kind 6 refusing every acting key across all three reserved channels; and FEE_LIMIT_TOO_LOW, EXPIRED, NONCE_EXHAUSTED, NONCE_MISMATCH, and SIGNER_NOT_FOUND. Every refusal is additionally checked to leave the state root unchanged, so failed-transition atomicity is proved for each condition rather than only for the refusals a recorded block happens to contain. Each hand-built fixture is asserted to be a conserved state first, because a fixture that no sequence of transitions could reach would make every result over it meaningless. The probe was re-run against these checks and now fails closed. Refs #180
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #180.
M3.10c put version six's byte and derivation surface into the kernel. A codec has no ledger, so it could not resolve an acting escrow, order the shared envelope checks, charge a fee, advance a nonce, or commit a state root. This adds the ledger and the ten transitions that read no cycle assignment.
What executes now
Admission, escrow resolution under both authorization schemes, the shared envelope checks in version one's order, ordered block execution with failed-transition atomicity, and kinds 1, 6, 10, 13, 14, 15, 16, 17, 18, and 19.
What deliberately does not
Kinds 2, 3, 4, and 5 read or write a cycle assignment, and the version-three settlement that derives one is not in the kernel. Dispatch refuses to execute them rather than answering wrongly — an implementation that cannot execute a transaction has no result to report, so it fails the block loudly instead of inventing a refusal. No conforming chain can run those four kinds until the settlement slice lands.
Two derived orders are implemented where a reader will look
ADR 0045 derived both; each now carries its reasoning in the code rather than only in the ADR.
DEBIT_OVERFLOWis returned inside envelope check 8. Check 8 testsamount + fixed_fee, which is the same sum kind 1's own step 5 tests; evaluating it afterwards leaves check 8 undefined on a sum that does not fitu64and makes code 7 unreachable in a version whose specification lists exactly three unreachable frozen codes and does not list it.UNAUTHORIZED. The specification places it at admission and namesMALFORMED_TRANSACTION; the predicate reads a stored posture admission cannot see, and the result-code space has no such name.One recorded divergence from version one survives intact:
INSUFFICIENT_BALANCEprecedesZERO_AMOUNTfor kind 1, so a zero-amount transfer from an escrow that cannot pay the fee answers differently under the two versions.Evidence
394 of the 512 vectors in
test-vectors/economy-transition-v6-execution.txtare reproduced — every vector in theconstruction,genesis,registration,millionth,recovery,compatibility,posture,derived, anddeterminismsections. The remaining 118 areblock,cycle, andordering, which are the boundary block and the settlement it derives.Nothing derives a second set of expected values. Four checks reach a third source rather than a second opinion of the execution file: the ordered transaction tree and the accepted version-one transfer against
protocol-primitives-v1.txt, the block header and block identifier againstledger-transition-v1.txt, the ten channel caps and five base-permission legs againstfounder-economy-manifest-v2.txt, and the referral leg againsteconomy-transition-v3.txt.A coverage guard fails if any vector in a claimed section is never consulted, and it was demonstrated to fail — removing one
fee_poolcomparison producesvector compatibility.fee_pool was never consulted. It also fails if the three deferred sections ever become empty, so the slice boundary is itself checkable.Probes
Nine mutation probes; seven caught. Two are reported rather than buried:
signer_revokeaccept a signer assigned to a different escrow changes nothing the recorded trace observes. That rejection condition, and kinds 13, 14, and 6 entirely, are unexercised by the vectors. Recorded as a known coverage gap for direct kernel tests rather than claimed as checked.Caught probes include the shared debit omitting a transfer's amount, the overflow test removed, the unrequested-confirmation refusal dropped, the relaxation predicate weakened to require all three fields, registration charging a fee, the airdrop bound admitting one more identity, the balance check skipping zero-amount transfers, and a transfer creating its recipient instead of refusing.
Local verification
Both compilers with the project's exact flags, and Clang with address and undefined-behaviour sanitizers, against the scratch-libsodium harness. Clang caught a portability bug GCC accepted — capturing a structured binding by reference in a lambda, which C++20 does not permit — in three places. It is fixed and both compilers now agree. The 142 Python model tests for version six still pass, and the target-registration guard passes.
The full matrix runs on this exact commit.