From ead8ba7a828b8c03589c7d6f3e53c805af7708aa Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 23 Aug 2026 00:55:06 -0500 Subject: [PATCH] blockchain: Always check size and merkle root. This modifies the assumevalid fast add path used during initial sync to also check the block size and merkle roots. These checks are now negligible in terms of the overall sync time since the hashing has been significantly optimized and retaining them prevents certain classes of potential harassment during initial sync. --- internal/blockchain/validate.go | 43 +++++++++++++++------------------ 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/internal/blockchain/validate.go b/internal/blockchain/validate.go index aff8abd1e9..a591c806b8 100644 --- a/internal/blockchain/validate.go +++ b/internal/blockchain/validate.go @@ -1922,15 +1922,12 @@ func (b *BlockChain) checkMerkleRoots(block *wire.MsgBlock, prevNode *blockNode) // The flags modify the behavior of this function as follows: // // BFFastAdd: -// - The max block size is not checked -// - The calculated merkle root(s) of the transaction trees are not checked -// against the associated entries in the header // - Transactions are not checked to see if they are finalized // - The included votes, revocations, and treasury spend transactions are // not verified to be allowed // -// The flags are also passed to checkBlockHeaderContext. See its documentation -// for how the flags modify its behavior. +// The flags are also passed to [BlockChain.checkBlockHeaderContext]. See its +// documentation for how the flags modify its behavior. func (b *BlockChain) checkBlockContext(block *dcrutil.Block, prevNode *blockNode, flags BehaviorFlags) error { // The genesis block is valid by definition. if prevNode == nil { @@ -2216,26 +2213,26 @@ func (b *BlockChain) checkBlockContext(block *dcrutil.Block, prevNode *blockNode } } + // A block must not exceed the maximum allowed size as defined by the + // network parameters and the current status of any consensus votes to + // change it when serialized. + maxBlockSize := b.maxBlockSize(prevNode) + serializedSize := int64(block.MsgBlock().Header.Size) + if serializedSize > maxBlockSize { + str := fmt.Sprintf("serialized block is too big - got %d, max %d", + serializedSize, maxBlockSize) + return ruleError(ErrBlockTooBig, str) + } + + // The calculated merkle root(s) of the transaction trees must match the + // associated entries in the header. + err = b.checkMerkleRoots(block.MsgBlock(), prevNode) + if err != nil { + return err + } + fastAdd := flags&BFFastAdd == BFFastAdd if !fastAdd { - // A block must not exceed the maximum allowed size as defined by the - // network parameters and the current status of any hard fork votes to - // change it when serialized. - maxBlockSize := b.maxBlockSize(prevNode) - serializedSize := int64(block.MsgBlock().Header.Size) - if serializedSize > maxBlockSize { - str := fmt.Sprintf("serialized block is too big - got %d, max %d", - serializedSize, maxBlockSize) - return ruleError(ErrBlockTooBig, str) - } - - // The calculated merkle root(s) of the transaction trees must match - // the associated entries in the header. - err = b.checkMerkleRoots(block.MsgBlock(), prevNode) - if err != nil { - return err - } - // Switch to using the past median time of the block prior to the block // being checked for all checks related to lock times once the stake // vote for the agenda is active.