Block
A block kernel consists of a header, body, and an appendix.
The block header has constant size and consists of:
version
the version of the Neptune protocolheight
the block height represented as aBFieldElement
prev_block_digest
the hash of the block's predecessortimestamp
when the block was foundnonce
randomness for proof-of-workcumulative_proof_of_work
approximate number of hashes computed in the block's entire lineagedifficulty
approximate number of hashes required to find a blockguesser_digest
the lock prevents any but the guesser from spending guesser fees.
The block body holds the variable-size data, consisting of:
transaction_kernel
every block contains one transaction, which represents the merger of all broadcasted transactions that the miner decided to confirm.mutator_set_accumulator
the mutator set is the data structure that holds the UTXOs. It is simultaneously an accumulator (giving rise to a compact representation and compact membership proofs) and an anonymity architecture (so that outputs from one transactions cannot be linked to inputs to another).lock_free_mmr_accumulator
the data structure holding lock-free UTXOsblock_mmr_accumulator
the peaks of a Merkle mountain range that contains all historical blocks in the current block's line.
The block appendix consists of a list of claims. The block program verifies the truth of all of these claims. The appendix can be extended in future soft forks.
Besides the kernel, blocks also contain proofs. The block proof is a STARK proof of correct execution of the BlockProgram
, which validates a subset of the validity rules below. In addition to that, it validates all claims listed in the appendix.
Validity
Note: this section describes the validity rules for blocks at some future point when we have succinctness, not the current validity rules (although there is a significant overlap).
A block is valid if (any of):
- a) it is the genesis block
- b) the incremental validity conditions are satisfied
- c) it lives in the
block_mmr_accumulator
of a block that is valid.
A: Genesis Block
The genesis block is hardcoded in the source code, see genesis_block
in block/mod.rs
.
B: Incremental Validity
A block is incrementally valid if (all of):
- a) the transaction is valid
- b) the transaction's coinbase conforms with the block subsidy schedule
- c) all the inputs in the transaction either live in the lock-free UTXO MMR or have at least one index that is absent from the mutator set SWBF
- d) the
mutator_set_accumulator
results from applying all removal records and then all addition records to the previous block'smutator_set_accumulator
- e) the
block_mmr_accumulator
results from appending the previous block's hash to the previous block'sblock_mmr_accumulator
- f) there is an ancestor block
luca
of the current block such that for each uncle blockuncle
uncle
is validluca
is an ancestor ofuncle
- neither
luca
nor any of the blocks betweenluca
and the current block listuncle
as an uncle block
- g) the
version
matches that of its predecessor or is member of a predefined list of exceptions - h) the
height
is one greater than that of its predecessor - i) the
timestamp
is greater than that of its predecssor - j) the network statistics trackers are updated correctly
- k) the variable network parameters are updated correctly.
C: Mmr Membership
A block is valid if it lives in the block_mmr_accumulator
of a valid block. This feature ensures several things.
- It is possible to prove that one block is an ancestor of another.
- Archival nodes do not need to store old block proofs; storing the most recent block proof suffices.
- Non-tip blocks can be quickly verified to be valid and, if the receiver is synchronized to the tip, canonical as well.
- In case of reorganization, storing the now-abandoned tip proof continues to suffice to establish the validity of shared blocks. (That said, an archival node should prove canonicity of shared blocks also, and to do this he must synchronize and download all blocks on the new fork.)
Confirmability
A block is confirmable if (all of):
- a) it is valid
- b) its timestamp is less than 5 minutes into the future
- c) its size is less than the
MAX_BLOCK_SIZE
inBFieldElement
s - d) its hash is less than the previous block's
target_difficulty
.
Confirmability is not something that can be proven. It must be checked explicitly by the node upon receiving the block.
Canonicity
A block is canonical if it lives on the chain with the most cumulative proof-of-work. However, the fork chain rule is only evaluated if an incoming block has a different height than the current block.