What changed, and why it matters
This commit only adds a new test to btcd. The test checks that a specific Bitcoin RPC command, used when miners propose new blocks, correctly rejects block data that has extra junk bytes tacked onto the end. The commit itself does not change the actual production code behavior; it only verifies that the existing rejection works. The test was likely added because a similar trailing-byte bug was fixed elsewhere and the developers wanted to make sure this code path was also protected.
No immediate action is required; this is a test-only change. Reviewers may want to confirm that the production handler already rejects trailing bytes in all code paths and that the test passes. If the test was added in response to a prior bug, ensure the fix is complete and backported if applicable.
Security signals we found
Trailing-byte deserialization test for block proposal RPC
Defensive assertion that malformed input returns ErrRPCDeserialization rather than reaching chain state
Pattern consistent with prior tests for sendrawtransaction and decoderawtransaction trailing-byte rejection
Evidence from the diff
The diff adds a unit test in rpcserver_test.go: TestHandleGetBlockTemplateProposalRejectsTrailingBytes. It serializes the mainnet genesis block, appends a trailing 0x00 byte, encodes the result as hex, and passes it as the Data field of a btcjson.TemplateRequest with Mode=’proposal’ to handleGetBlockTemplateProposal. The test asserts the handler returns btcjson.ErrRPCDeserialization and a nil result, and uses a deferred recover() to ensure the handler does not panic or reach chain state. No production code is modified.
Changed components
rpcserver_test.gohandleGetBlockTemplateProposal RPC handler (test coverage only)Inspect captured patch +33 / −0
diff --git a/rpcserver_test.go b/rpcserver_test.go
index a54a425..529d76b 100644
--- a/rpcserver_test.go
+++ b/rpcserver_test.go
@@ -1,12 +1,14 @@
package main
import (
+ "bytes"
"encoding/hex"
"errors"
"testing"
"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/btcutil/v2"
+ "github.com/btcsuite/btcd/chaincfg/v2"
"github.com/btcsuite/btcd/chainhash/v2"
"github.com/btcsuite/btcd/mempool"
"github.com/btcsuite/btcd/wire/v2"
@@ -79,6 +81,17 @@ func requireRPCErrorCode(t *testing.T, err error, code btcjson.RPCErrorCode) {
require.Equal(t, code, rpcErr.Code)
}
+// blockHexWithTrailingByte serializes a valid block and appends one extra byte.
+func blockHexWithTrailingByte(t *testing.T) string {
+ t.Helper()
+
+ var block bytes.Buffer
+ err := chaincfg.MainNetParams.GenesisBlock.Serialize(&block)
+ require.NoError(t, err)
+
+ return hex.EncodeToString(append(block.Bytes(), 0x00))
+}
+
// TestHandleSendRawTransactionRejectsTrailingBytes ensures sendrawtransaction
// rejects byte strings that contain a valid transaction plus trailing data.
func TestHandleSendRawTransactionRejectsTrailingBytes(t *testing.T) {
@@ -114,6 +127,26 @@ func TestHandleDecodeRawTransactionRejectsTrailingBytes(t *testing.T) {
require.Nil(t, result)
}
+// TestHandleGetBlockTemplateProposalRejectsTrailingBytes ensures proposal mode
+// rejects byte strings that contain a valid block plus trailing data.
+func TestHandleGetBlockTemplateProposalRejectsTrailingBytes(t *testing.T) {
+ t.Parallel()
+
+ defer func() {
+ recovered := recover()
+ require.Nil(t, recovered, "handler reached chain state")
+ }()
+
+ request := &btcjson.TemplateRequest{
+ Mode: "proposal",
+ Data: blockHexWithTrailingByte(t),
+ }
+
+ result, err := handleGetBlockTemplateProposal(&rpcServer{}, request)
+ requireRPCErrorCode(t, err, btcjson.ErrRPCDeserialization)
+ require.Nil(t, result)
+}
+
var (
// TODO(yy): make a `btctest` package and move these testing txns there
// so they be used in other tests.
Why this scored 18/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.