feat(kernel): implement deterministic in-memory ledger - #10
Merged
Conversation
Implement the accepted transfer-result ordering, checked monetary writes, fee routing, self-transfer handling, and internal invariant failures behind a kernel-private helper. Reproduce the frozen ledger scenario and assert conservation and failure atomicity across all result codes.\n\nProtocol behavior follows ADR 0006 and ledger-transition-v1 without compatibility changes.\n\nRefs #8
Narrow version-one genesis to 21,844 accounts so its 46-byte prefix and 48-byte entries remain within the accepted 1,048,576-byte canonical-object limit. Clarify that strict Ed25519 canonicality and equation failures collapse to INVALID_SIGNATURE after the chain check.\n\nThe existing canonical fixture bytes and transition meaning are unchanged.\n\nRefs #8
Parse exact version-one genesis bytes with bounded account counts, ordered identifiers, checked supply conservation, and domain-separated chain IDs. Cover malformed, parameter, ordering, overflow, and 21,844/21,845 size boundaries under the full compiler and sanitizer matrix.\n\nRefs #8
Implement checked state conservation, ordered RFC 9162-style state and transaction trees, exact receipt and block-header encodings, and validated block identifiers. Reproduce every frozen commitment and exercise Merkle power-of-two and 65,535-leaf boundaries under all compiler and sanitizer presets.\n\nRefs #8
Add distinct protocol digest types and an owning public ledger that loads canonical genesis, enforces exact block height and input bounds, executes admitted transfers against tentative state, and publishes canonical receipts and commitments at one no-throw commit point. Cover frozen outputs, public error boundaries, ordering, duplicates, resource limits, failure precedence, determinism, and ownership semantics across the full compiler and sanitizer matrix. Document adapter lifetimes and operational exception handling. Refs #8
Add 9,000 deterministic invariant scenarios with exact success-state comparison and first-error precedence, plus an independent standard-library Python model and public C++ runner. The fixed SplitMix64-v1 corpus checks 10,000 nonempty randomized sequences and 11 directed sequences after every successful block, including admission and execution outcomes, typed and encoded receipts, full state, roots, headers, and block IDs. Random coverage is enforced independently. Refs #8
Run the unchanged primitive vectors through the production hash, signature, admission, Bech32m address, and commitment paths. Add bounded Clang libFuzzer smoke targets for admission, address decoding, and genesis loading under ASan and UBSan. The generic commitment path now reproduces the specified zero-supply empty-state root; canonical genesis continues to require nonzero supply. Refs #8
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.
Outcome
Implements the accepted version-one in-memory C++20 ledger kernel end to end:
Closes #8.
Scope and effects
The kernel remains an in-memory, single-native-asset application-state authority. It adds no persistence, RPC, networking, consensus adapter, deployment surface, public asset creation, or post-genesis issuance.
Consensus-visible behavior implements the already accepted v1 specifications. The normative primitive and ledger-transition vector files are unchanged. Account, chain, transaction, state-root, transaction-root, and block identifiers are distinct C++ types without changing their canonical 32-byte representations. Address text is an input/display boundary only and never enters ledger state.
The generic commitment path reproduces the specified zero-supply empty-state primitive vector; canonical genesis continues to require nonzero supply and at least one funded account. Cryptographic arithmetic remains isolated behind pinned libsodium 1.0.22.
Verification
All repository entry-point presets passed from this branch:
PROTOCOL_STACK_PRESET=gcc-debug tools/verify.sh— 12/12 CTest tests;PROTOCOL_STACK_PRESET=gcc-sanitizers tools/verify.sh— 12/12 with ASan+UBSan;PROTOCOL_STACK_PRESET=clang-debug tools/verify.sh— 12/12;PROTOCOL_STACK_PRESET=clang-sanitizers tools/verify.sh— 15/15 with ASan+UBSan and three fixed-seed 512-run libFuzzer smokes.Additional evidence:
c00e85ff9798ea907700e898113923b10411161c9bf2ba8c71fadec93a1b95a6and474bc322de153731f90506a29ae49cc5858197bfeefcfe11f91be36c6d4008d9;git diff --checkpassed;Specifications and decisions
docs/specifications/protocol-primitives-v1.mddocs/specifications/ledger-transition-v1.mddocs/decisions/0004-protocol-primitives-v1.mddocs/decisions/0005-reproducible-cpp-toolchain.mddocs/decisions/0006-ledger-transition-v1.mddocs/architecture/ledger-kernel.mdKnown limitations and follow-up
This PR deliberately stops at the in-memory kernel. The next M1 dependency is a replaceable persistent-state adapter with atomic commit, reopen, replay, snapshot, corruption, and crash-recovery evidence. Long-running fuzz campaigns remain separate from the bounded CI smoke sessions.