Skip to content
Lars Kuhtz edited this page Dec 5, 2023 · 11 revisions

Overview

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. (This property will be relaxed in the future with the introduction of shallow nodes.)

    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.

Block Header Validation

We distinguish between intrinsic and inductive properties. Intrinsic properties are properties of just a single block header and don't depend on the chain context. Inductive properties relate the block header to its context in a chain and are established inductively with respect to the parent header and the adjacent parent headers.

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.

Block Header Validation Failures

All block header validation failures are defined in Chainweb.BlockHeader.Validation.

For validation failures we distinguish between definite and ephemeral failures.

Definite block validation failures are independent of any external context. A block for which validation fails with one of these failures must be discarded.

No node on the Chainweb network should propgate blocks with these failures. If a block that causes a definite validation failure is receveived from a Chainweb node, that Chainweb node should be blacklisted or removed from the peer database.

Ephemaral block validation failures depend on a local context and validation may succeed in the future. In case of 'BlockInTheFuture' validation will eventually succeed.

Block Header Validation Properties

Context Definite Failure Property Description
block IncorrectGenesisParent 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.
block IncorrectGenesisTarget 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.
block IncorrectHash prop_block_hash The block hash of the block header is the result of computing the hash for the block.
block IncorrectPow prop_block_pow The POW hash of the block header is smaller than the target.
block BlockInTheFuture prop_block_current The creation time of the block header is smaller or equal the current time.
block InvalidFeatureFlags prop_block_featureFlags The feature flags of the block are all zero.
block AdjacentChainMismatch prop_block_adjacent_chainIds The block uses the correct set of adjacent chainIds for the chain graph for the Chainweb version.
block MissingPayload cf. note below The payload of the block exists. This property is enforced indirectly in Pact service as part of payload validation.
block IncorrectPayloadHash cf. note below The payload hash matchs the payload hash that results from payload validation
parent IncorrectHeight prop_block_height The height of the genesis block header is 0 and the block height of the parent header plus one, otherwise.
parent VersionMismatch prop_block_chainwebVersion The chainweb version of the header equals the version of the parent header.
parent IncorrectWeight prop_block_weight The weight of the block header is difficulty of the POW target of the header plus the weight of the parent header.
parent ChainMismatch prop_block_chainId The chain id of the block header equals the chain id of the parent header.
parent MissingParent validateBlockParentExists The referenced parent header exists.
parent IncorrectEpoch prop_block_epoch The epoch start time of the first block of an epoch equals the block creation time of the parent block. For all other blocks the epoch start time equals the epoch start time of the parent block.
parents IncorrectTarget prop_block_target The target of the first block of an epoch is the adjusted target of the previous epoch. For all other blocks the target equals the target of the parent block.
parents CreatedBeforeParent prop_block_creationTime The creation time of the block header is strictly larger than the creation time of all parent headers.
parents AdjacentParentChainMismatch prop_block_adjacent_parents Adjacent parent hashes reference blocks on their respective chain.
parents InvalidAdjacentVersion prop_block_adjacent_parents_version The chainweb version of all adjancent parents match the version of the validated header.
parents MissingAdjacentParent validateAllParentsExist All referenced adjacent parent headers exist.
cut InvalidBraiding cf. note below The braiding property is enforced in the cut merge algorithm , namely in monotonicCutExtension. The property that is checked in the cut validation is stronger than the braiding property that we could check as block validation (which is the property that is described in the chainweb paper), but we would have to look back 2 steps in history.

Notes

  • IncorrectPayloadHash: The payload hash matches the payload hash computed from the PayloadWithOutputs data structure that results from calling pact validation with the PayloadData of the block for the parent hash of the block.

    The match of the payload hashes is checked in PactExecutionService

  • 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.

    It is enforced in the cut merge algorithm , namely in monotonicCutExtension. The property that is checked in cut validation is stronger than the braiding property (which is described in the Chainweb white paper).

    To enforce it as part of block header validation one would have to look back 2 steps in history.

  • 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.

Cut Validation

This is enforced by the cut merging code, in particular in the function joinIntoHeavier, which calls tryMonotonicCutExtension

In particular it is guaranteed that

  1. block headers are from the ChainGraph of the Cut,
  2. the result of joining two cuts is a cut, and
  3. the result of joining to cuts has valid braiding.

Payload Validation

Pact Service

The following list is incomplete.

  1. 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?)

  2. 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.

  3. Chain id matches the chain id of the block

  4. Chainweb version matches the version of the block

TODO: timing validation, a continuation/x-chain mint is executed at most once, merkle validation, max block gas limit, processing timeouts, gas processing, coinbase properties, signature validation, txhash validation, etc.

Pact service transaction validation is implemented in Chainweb.Pact.PactService.ExecBlock.validateChainwebTxs. It is called in

execBlock is called by execValidateBlock and in fastForward during replay.

validateChainwebTxs is called for all transactions in a block before Pact validation of the transaction in a block. It includes the following checks:

  • checkUnique (assert that a tx hasn't been executed before),
  • checkTxHash (assert tht the tx hash is computed correctly),
  • checkTxSigs (assert that all signatures are correct),
  • checkTimes (assert that creation time and ttl of the transaction are valid and match the local pact time),
  • checkCompile (assert that the transaction code can be compiled)
  • doByGas (this check is skipped for execBlock. TODO: why? because it is done later during tx evaluation?)

TODO:

  • details of timing check
  • max gas limit
  • resulting payload hash
  • chainweb version
  • chain id
  • merkle proofs / verify-spv

Pact

TODO: refer to pact documentation. describe how pact execution flags and pact version is guaranteed and checked.

Implementation

For each block header in the block header db it is guaranteed that

  1. the block satisfies all block validation properties,
  2. the parent header exists in the block header db,
  3. all adjacent parent headers exist the block header dbs of their respective chains, and
  4. the payload for the payload hash exists in the payload db.

For each cut in the cut db it is guaranteed that

  1. each block header in the cut exists in the block header db and
  2. the blocks in the cut satisfy the Chainweb braiding properties.

TODO: describe guarantees of the pact database.

Mempool

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.