rpc: test sendrawtransaction trailing byte rejection
What changed, and why it matters
This commit only adds a new unit test. It does not change any production code. The test verifies that the sendrawtransaction RPC already rejects transaction hex strings that have extra trailing bytes after a valid transaction. Because no actual behavior of the live software is changed, this patch by itself does not create or fix a security issue.
No action required. Treat as routine test coverage. If reviewing a related series of commits, confirm that the production-code change that enforces this rejection is present in a preceding or accompanying commit.
Security signals we found
Strict deserialization of raw transactions is a desirable defensive property
The test confirms trailing bytes are rejected, which can prevent certain malleability or parsing-confusion issues
No production code is changed in this commit
Evidence from the diff
The diff adds TestHandleSendRawTransactionRejectsTrailingBytes and a helper requireRPCErrorCode in rpcserver_test.go. The test constructs a sendrawtransaction command with txHex1 plus an extra 0x00 byte, mocks the mempool so it should never be invoked, and asserts that handleSendRawTransaction returns btcjson.ErrRPCDeserialization with a nil result. This is a regression test for existing deserialization strictness; it does not modify the implementation of handleSendRawTransaction or any decoding path.
Changed components
rpcserver_test.goInspect captured patch +32 / −0
diff --git a/rpcserver_test.go b/rpcserver_test.go
index 2e291da..12c2d66 100644
--- a/rpcserver_test.go
+++ b/rpcserver_test.go
@@ -10,6 +10,7 @@ import (
"github.com/btcsuite/btcd/chainhash/v2"
"github.com/btcsuite/btcd/mempool"
"github.com/btcsuite/btcd/wire/v2"
+ "github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)
@@ -67,6 +68,37 @@ func TestHandleTestMempoolAcceptFailDecode(t *testing.T) {
}
}
+// requireRPCErrorCode asserts that the error is an RPC error with the expected
+// error code.
+func requireRPCErrorCode(t *testing.T, err error, code btcjson.RPCErrorCode) {
+ t.Helper()
+
+ require.Error(t, err)
+ rpcErr, ok := err.(*btcjson.RPCError)
+ require.True(t, ok)
+ require.Equal(t, code, rpcErr.Code)
+}
+
+// TestHandleSendRawTransactionRejectsTrailingBytes ensures sendrawtransaction
+// rejects byte strings that contain a valid transaction plus trailing data.
+func TestHandleSendRawTransactionRejectsTrailingBytes(t *testing.T) {
+ t.Parallel()
+
+ mm := &mempool.MockTxMempool{}
+ mm.On(
+ "ProcessTransaction", mock.Anything, false, false, mempool.Tag(0),
+ ).Return(nil, errors.New("mempool should not be reached")).Maybe()
+
+ s := &rpcServer{cfg: rpcserverConfig{
+ TxMemPool: mm,
+ }}
+ cmd := btcjson.NewSendRawTransactionCmd(txHex1+"00", nil)
+
+ result, err := handleSendRawTransaction(s, cmd, make(chan struct{}))
+ 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 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.