slave (M1.5): derive the real QKC minor genesis block - #44
Open
syntrust wants to merge 4 commits into
Open
Conversation
…leaf The QuarkChain-side types the minor genesis block is built out of, ahead of deriving it. - qkc/types: MinorBlockMeta/MinorBlockHeader/MinorBlock with QKC serialization; TypedTransaction stays an opaque envelope, which is all a genesis body (empty) needs. XShardTxCursorInfo is a meta field. - qkc/state: the state trie leaf, mirroring pyquarkchain's _Account — per-token balances as a serialized blob and the owning address's full_shard_key as a fixed four-byte string, not a uint32, so leading zeros survive. The trie machinery underneath stays geth's. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
pyquarkchain treats an ALLOC entry with an explicit empty "code" as a contract allocation (nonce 1), which an absent code field is not. Decoding both into a nil Code erased that distinction and would change the genesis state root. Record presence separately and decide the field's presence by inspecting the decoded JSON object rather than substring-matching the raw input. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Turn a shard's configured allocation into state trie leaves and its root hash, splitting derivation from persistence the way geth's hashAlloc/flushAlloc do: GenesisAllocRoot answers what the state root is, CommitGenesisAlloc writes the nodes. Duplicate recipients are rejected rather than silently last-one-wins, and an allocation that is blank in pyquarkchain's terms produces no account at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…kchain CreateMinorBlock and ShardChainConfig sit next to CreateRootBlock, mirroring pyquarkchain's GenesisManager: GENESIS.ALLOC is materialized into the passed database and the resulting state root is sealed into the block's meta, which the header commits to. Passing an ephemeral database derives the block without persisting it. New validations: GENESIS.HEIGHT must be 0, a ROOT_HEIGHT > 0 shard is refused rather than stood on the wrong root linkage, and every ALLOC address must belong to the shard being created. ShardChainConfig is the EVM rule set a shard runs — Petersburg-only, with the chain id derived as BASE_ETH_CHAIN_ID + CHAIN_ID + 1 and a configured ETH_CHAIN_ID accepted only when consistent with it. It is kept out of the genesis block on purpose, as geth keeps its rule set out of the genesis identity. Pinned against pyquarkchain at three levels (state root, meta hash, block hash) for both singularity networks; regeneration recipe in qkc/config/singularity/README.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
syntrust
requested review from
blockchaindevsh,
iteyelmp,
ping-ke,
qizhou and
qzhodl
July 30, 2026 11:19
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.
Split out of #26 as its prerequisite: the pure derivation half of milestone 2
(design doc,
tracking #17).
qkc.CreateMinorBlockproduces a shard's QuarkChain minor genesisblock — the real block, byte-compatible with pyquarkchain, not a config
fingerprint. No storage and no shard lifecycle here; #26 stacks that on top.
What's here
qkc/types—MinorBlockHeader/MinorBlockMeta/MinorBlockwith QKCserialization. Transactions stay an opaque envelope; a genesis body is empty.
qkc/state— the QuarkChain state trie leaf: token-balances blob, and theowning address's
full_shard_keyas a fixed four-byte string rather than auint32, so leading zeros survive into the state root.
qkc/genesis_alloc.go—GENESIS.ALLOCmaterialization, split intoGenesisAllocRoot/CommitGenesisAllocas in geth'shashAlloc/flushAlloc.qkc/genesis.go—CreateMinorBlockandShardChainConfignext toCreateRootBlock, mirroring pyquarkchain'sGenesisManager. New validations:GENESIS.HEIGHT != 0,ROOT_HEIGHT != 0, ALLOC address ownership.qkc/config— an explicit emptycodein an ALLOC entry is a contractallocation (nonce 1) and no longer decodes the same as an absent one.
ShardChainConfighas no caller until #26; it ships here because it lives ingenesis.gonext to its tests.Tests
go build ./... && go test -race ./qkc/... ./cmd/slave/— green.create_minor_block()for mainnet+devnet pinned atthree levels: state root, meta hash, block hash (
qkc/testdata/, regenerationrecipe in
qkc/config/singularity/README.md).HEIGHT/ROOT_HEIGHT, foreign-shard ALLOC, unknownshard, duplicate ALLOC recipients, inconsistent
ETH_CHAIN_ID, chain-idoverflow; empty-code round trip; derivation determinism and extra-data cloning.
🤖 Generated with Claude Code