
Copyright © 2026 Toby Sharp
toby@hornetnode.org
Below is an auto-generated rendering of Hornet’s declarative specification of Bitcoin block validity. It lists the semantic invariants that together determine whether a block is consensus-valid, with links to the corresponding Hornet validation functions that realize those invariants in executable form.
| ID | Rule | Function |
|---|---|---|
| Header Rules | ||
| H01 | A header MUST reference the hash of a valid parent block. | ValidatePreviousHash |
| H02 | A header's hash MUST achieve its own proof-of-work target. | ValidateProofOfWork |
| H03 | A header's proof-of-work target MUST satisfy the difficulty adjustment formula for the timechain. | ValidateDifficultyAdjustment |
| H04 | A header timestamp MUST be strictly greater than the median of its 11 ancestors' timestamps. | ValidateMedianTimePast |
| H05 | A header timestamp MUST be less than or equal to network-adjusted time plus 2 hours. | ValidateTimestampCurrent |
| H06 | A header's version number MUST NOT have been retired by any activated soft fork. | ValidateVersion |
| Local Rules | ||
| L01 | A block MUST contain at least one transaction. | ValidateNonEmpty |
| L02 | A block’s Merkle root field MUST equal the unique Merkle root of its transactions. | ValidateMerkleRoot |
| L03 | A block’s serialized size excluding witness flags and data MUST NOT exceed 1,000,000 bytes. | ValidateOriginalSizeLimit |
| L04 | A block's first transaction MUST be its only coinbase transaction. | ValidateCoinbase |
| L05 | The total legacy signature-operation count over all input and output scripts MUST NOT exceed 20,000. | ValidateSignatureOps |
| L06 | A transaction MUST contain at least one input. | ValidateInputCount |
| L07 | A transaction MUST contain at least one output. | ValidateOutputCount |
| L08 | A transaction's serialized size excluding witness flags and data MUST NOT exceed 1,000,000 bytes. | ValidateTransactionSize |
| L09 | All transaction output amounts MUST be non-negative. | ValidateOutputsNonNegative |
| L10 | The sum of a transaction's output amounts MUST NOT exceed 21,000,000 coins. | ValidateOutputsSum |
| L11 | A transaction's inputs MUST NOT contain duplicate outpoints. | ValidateUniqueInputs |
| L12 | A coinbase transaction's sig script size MUST be between 2 and 100 bytes inclusive. | ValidateCoinbaseSignatureSize |
| L13 | A non-coinbase transaction's inputs MUST have non-null previous outputs. | ValidateInputsPrevout |
| Contextual Rules | ||
| C01 | All transactions in the block MUST be final given the block height and locktime rules. | ValidateTransactionFinality |
| C02 | A pre-SegWit block MUST NOT contain any witness data. | ValidateNoWitnessPreSegwit |
| C03 | A block’s total weight MUST NOT exceed 4,000,000 weight units. | ValidateBlockWeight |
| C04 | From BIP34: The coinbase transaction’s sig script MUST begin by pushing the block height. | ValidateCoinbaseHeight |
| C05 | From BIP141: A block containing witness data MUST contain a witness commitment. | ValidateWitnessCommitment |
| C06 | From BIP141: A post-Segwit block containing a witness commitment MUST contain a witness nonce. | ValidateWitnessNonce |
| C07 | From BIP141: A post-SegWit block containing a witness commitment MUST commit to its witness Merkle root and nonce. | ValidateWitnessMerkle |
| Spending Rules | ||
| S01 | Transaction outputs MUST NOT give rise to duplicates of existing unspent outpoints (BIP30). | ValidateOutPointsUnique |
| S02 | A transaction input MUST reference a previous transaction output that remains unspent. | ValidateInputPrevoutsUnspent |
| S03 | The total signature-operation cost over all transactions MUST NOT exceed 80,000. | ValidateSigOpCosts |
| S04 | The total amount in coinbase outputs MUST NOT exceed the block reward. | ValidateBlockSubsidy |
| S05 | The sum of output values in a transaction MUST NOT exceed the sum of all input values being spent. | ValidateOutputsAtMostInputs |
| S06 | A non-coinbase input MUST satisfy the spent output's locking script. | ValidateScripts |
| S07 | From BIP68: Each input that signals a relative lock-time interval MUST have reached relative finality. | ValidateSequenceLocks |
| S08 | Coinbase outputs MUST NOT be spent before 100 blocks after their creation. | ValidateCoinbaseMaturity |
| Term | Definition |
|---|---|
| Block | A block comprises a header and an ordered sequence of transactions. |
| Genesis | The genesis block is the first block in the Bitcoin timechain. |
| Header | A header is a structured set of fields over the first 80 bytes in a block. |
| Timechain | A timechain is a tree of validated blocks. |
| Proof of Work | A 256-bit hash must be found that does not exceed a given target value. |
| Coinbase | The coinbase transaction is the first in a block. It creates new outputs and spends no previous outputs. |
| Outpoint | An outpoint identifies a previous output by its transaction's hash and its output index. |
| Witness | Witness data is segregated transaction input data committed separately under SegWit rules. |
| Signature Operation | A signature operation is a script accounting unit associated with signature-checking opcodes. |
| BIP34 | The coinbase height soft fork is active from block height 227,931. |
| BIP68 | The sequence locks soft fork is active from block height 419,328. |
| BIP141 | The SegWit soft fork is active from block height 481,824. |