What changed, and why it matters
This commit changes how raw transactions submitted to the Bitcoin node via RPC are decoded. It switches from a lenient decoder to a stricter one that validates the transaction more thoroughly before accepting it. The likely effect is to prevent malformed or non-standard transactions from being processed, which could otherwise cause node errors or unexpected behavior.
Treat as a low-to-moderate hardening patch. Review whether the stricter decoder rejects any previously valid transaction encodings to avoid breaking RPC clients. No immediate incident response is indicated, but operators should ensure compatibility after upgrading.
Security signals we found
Stricter deserialization of user-supplied raw transaction data
Change in RPC input validation path (sendrawtransaction)
Potential denial-of-service or mempool corruption risk from malformed transactions mitigated
Evidence from the diff
In handleSendRawTransaction, the code previously deserialized the hex transaction into a wire.MsgTx using msgTx.Deserialize(bytes.NewReader(serializedTx)), then wrapped it with btcutil.NewTx(&msgTx). The patch replaces this with btcutil.NewTxFromBytes(serializedTx). The new function performs stricter deserialization checks, rejecting transactions that the previous lenient decoder might have accepted. This is a hardening change in the RPC transaction submission path.
Changed components
rpcserver.gohandleSendRawTransactionRPC sendrawtransaction endpointInspect captured patch +1 / −3
diff --git a/rpcserver.go b/rpcserver.go
index 3a481aa..35c7f52 100644
--- a/rpcserver.go
+++ b/rpcserver.go
@@ -3441,8 +3441,7 @@ func handleSendRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan st
if err != nil {
return nil, rpcDecodeHexError(hexStr)
}
- var msgTx wire.MsgTx
- err = msgTx.Deserialize(bytes.NewReader(serializedTx))
+ tx, err := btcutil.NewTxFromBytes(serializedTx)
if err != nil {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCDeserialization,
@@ -3451,7 +3450,6 @@ func handleSendRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan st
}
// Use 0 for the tag to represent local node.
- tx := btcutil.NewTx(&msgTx)
acceptedTxs, err := s.cfg.TxMemPool.ProcessTransaction(tx, false, false, 0)
if err != nil {
// When the error is a rule error, it means the transaction was
Why this scored 49/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.