What changed, and why it matters
This commit only adds a new test to the btcd blockchain package. The test verifies that when the software starts up, it rejects a stored 'best block' whose saved bytes contain extra trailing data after the valid block. It does not change any production code, so by itself it cannot introduce or fix a runtime security issue. It is a regression test that documents expected behavior already enforced elsewhere.
No security action required. Treat as normal test coverage improvement. If reviewing a related patch series, verify that the production code change enforcing the 'trailing bytes' error is present in a separate commit.
Security signals we found
Regression test for strict deserialization of stored best block bytes
No production code changes
No vulnerability fix or behavior change in runtime code
Evidence from the diff
The diff adds TestInitChainStateRejectsTrailingBestBlockBytes in blockchain/chainio_test.go. The test builds a block, appends a trailing 0x00 byte, processes the block, then calls New() to initialize chain state and asserts that startup returns an error containing ‘trailing bytes’. No production logic is modified. The test imports btcutil/v2 and txscript/v2 and uses strings.Contains for the error assertion.
Changed components
blockchain/chainio_test.goInspect captured patch +49 / −0
diff --git a/blockchain/chainio_test.go b/blockchain/chainio_test.go
index 6620f0c..272bf61 100644
--- a/blockchain/chainio_test.go
+++ b/blockchain/chainio_test.go
@@ -9,9 +9,12 @@ import (
"errors"
"math/big"
"reflect"
+ "strings"
"testing"
+ "github.com/btcsuite/btcd/btcutil/v2"
"github.com/btcsuite/btcd/database"
+ "github.com/btcsuite/btcd/txscript/v2"
"github.com/btcsuite/btcd/wire/v2"
)
@@ -37,6 +40,52 @@ func TestErrNotInMainChain(t *testing.T) {
}
}
+// TestInitChainStateRejectsTrailingBestBlockBytes ensures startup rejects a
+// stored best block whose bytes contain a valid block plus trailing data.
+func TestInitChainStateRejectsTrailingBestBlockBytes(t *testing.T) {
+ chain, params, teardown := utxoCacheTestChain(
+ "TestInitChainStateRejectsTrailingBestBlockBytes")
+ defer teardown()
+
+ tip := btcutil.NewBlock(params.GenesisBlock)
+ tip.SetHeight(0)
+
+ block, _, err := newBlock(chain, tip, nil)
+ if err != nil {
+ t.Fatalf("failed to build block: %v", err)
+ }
+
+ var serialized bytes.Buffer
+ err = block.MsgBlock().Serialize(&serialized)
+ if err != nil {
+ t.Fatalf("failed to serialize block: %v", err)
+ }
+
+ trailingBytes := append([]byte(nil), serialized.Bytes()...)
+ trailingBytes = append(trailingBytes, 0x00)
+ trailingBlock := btcutil.NewBlockFromBlockAndBytes(
+ block.MsgBlock(), trailingBytes,
+ )
+
+ _, _, err = chain.ProcessBlock(trailingBlock, BFNone)
+ if err != nil {
+ t.Fatalf("failed to process block: %v", err)
+ }
+
+ _, err = New(&Config{
+ DB: chain.db,
+ ChainParams: params,
+ TimeSource: NewMedianTime(),
+ SigCache: txscript.NewSigCache(1000),
+ })
+ if err == nil {
+ t.Fatal("expected trailing best block bytes to fail startup")
+ }
+ if !strings.Contains(err.Error(), "trailing bytes") {
+ t.Fatalf("expected trailing byte error, got: %v", err)
+ }
+}
+
// TestStxoSerialization ensures serializing and deserializing spent transaction
// output entries works as expected.
func TestStxoSerialization(t *testing.T) {
Why this scored 12/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.