-
Notifications
You must be signed in to change notification settings - Fork 97
Validation
There are different kinds of properties for Chainweb. The following is one possible classification of requirements for Chainweb.
-
Chainweb Consistency
No invalid blocks are included in the chain and no unintended hard forks happen.
All data that is authenticated is available, i.e. the hash can be checked.
All authenticated data satisfies all correctness constraints.
If this property is violated, the integrity of assets that are represented by the chain might be compromised (e.g. double spends, stolen funds, etc.). In worst case the chainweb version would have to be abandoned and new genesis headers for a new Chainweb version would have to be generated.
-
Consensus Availability
Nodes can perform validation of blocks.
Consensus exist across the network, but the block rate may be persistently below the acceptable target range or it might be even zero.
There are not forks of large sections of the network beyond the confirmation depth.
Bootstrap nodes are up and available for synchronization of cuts and chain data. Possibly in read-only mode.
-
Mining Availability
Mining of possibly empty blocks happens at target rate and consensus is established.
-
Transaction Processing Availability
Transactions (with sufficient gas) are processed and include in blocks up to the tx limit of blocks.
The reminder of this document is concerned only with Chainweb Consistency.
Most (pure) properties of block headers are implemented in the module Chainweb.BlockHeader.Validation. The module is well documented, and the code of most properties is short and easy to understand.
Intrinsic block header properties:
-
prop_block_difficulty
: The POW hash of the block header is smaller than the target. -
prop_block_hash
: The block hash of the block header is the result of computing the hash for the block. -
prop_pow_hash
: The POW hash of the block header is the result of computing the POW hash of the block. -
prop_block_genesis_parent
: A block header is the genesis block header of the chain and the Chainweb version of the block header if and only if the parent hash is the genesis parent hash of the respective chain and Chainweb version. -
prop_block_genesis_target
: If a block header is the genesis block header of the chain and the Chainweb version of the block header then the block target is the genesis block target of the respective chain and Chainweb version. -
prop_block_current
: The creation time of the block header is smaller or equal the current time.
Inductive block header properties:
-
prop_block_height
: the height of the genesis block header is 0 and the block height of the parent header plus one, otherwise. -
prop_block_target
: The target of the block is either the target of the parent or that target for the adjusted target for the first block in an epoch. -
prop_block_epoch
: The epoch time of the block is either the epoch time of the parent of the parent or the block creation time for the first block in an epoch. -
prop_payload_hash
: The payload hash matches the payload hash computed from thePayloadWithOutputs
data structure that results from calling pact validation with thePayloadData
of the block for the parent hash of the block.The match of the payload hashes is checked in PactExecutionService
Intrinsic:
-
prop_block_adjacent_chains
: There is an adjacent parent entry for each adjacent chain of the chain of the block header for the Chainweb version of the block header.This is also checked each time a block header is decoded.
Inductive:
-
prop_block_adjacent_chainId
: -
prop_block_adjacent_chainwebVersion
: -
prop_block_adjacent_creationTime
:
Existence of adjacent parent hashes is guaranteed by the dependency resolution code
Braiding is implied by cut validation, which provides a stronger guarantee. In particular each block that is part of a cut satisfies the braiding invariant.
There is a TODO for adding the additional (but currently not strictly needed) guarantee that all block headers in the block header database have a valid braiding.
prop_pow_hash
prop_block_target
prop_block_epoch
prop_block_current
Not explicitly checked but covered by other validation
-
prop_block_adjacent_chains
(covered by adjacent parent validation) -
prop_block_adjacent_chainId
(covered by adjacent parent validation + chain properties) -
prop_block_adjacent_chainwebVersion
(covered by adjacent parent validation + chain properties) -
prop_block_adjacent_creationTime
(covered by adjacent parent validation + chain properties)
This is enforced by the cut merging code, in particular in the function
joinIntoHeavier
, which calls
tryMonotonicCutExtension
In particular it is guaranteed that
- block headers are from the ChainGraph of the Cut,
- the result of joining two cuts is a cut, and
- the result of joining to cuts has valid braiding.
The following list is incomplete.
-
Each transaction hash is unique (Question: the pact documentation states that each transaction nonce is unique which is a strictly stronger property. Is this needed?)
-
Outputs correspond to the pact semantics for the respective pact version on on the chain for the given block. I.e. the db state at the beginning of the transaction is the db state at the end of the previous transaction.
-
Chain id is matches the chain id of the block
-
Chainweb version matches the version of the block
For each block header in the block header db it is guaranteed that
- the block satisfies all block validation properties,
- the parent header exists in the block header db,
- all adjacent parent headers exist the block header dbs of their respective chains, and
- the payload for the payload hash exists in the payload db.
For each cut in the cut db it is guaranteed that
- each block header in the cut exists in the block header db and
- the blocks in the cut satisfy the Chainweb braiding properties.
TODO: describe guarantees of the pact database.
The behavior of the Mempool should not be relevant for Chainweb Consistency as defined above. Block validation and Pact validation in particular should not make any assumptions about the soundness of transactions in the Mempool. Any transaction in the Mempool must be fully validated when it is inserted into a block in the context of that block.
For performance reasons, and in order to provide Transaction Processing Availability the Mempool should perform wellformedness checks on transactions and avoid spending resources on not well formed transactions by failing fast and early. But this isn't a requirement for Chainweb Consistency.