@@ -2,6 +2,7 @@ package multinode
22
33import (
44 "context"
5+ "encoding/json"
56 "fmt"
67 "testing"
78
@@ -425,3 +426,60 @@ func TestTransactionSender_SendTransaction_aggregateTxResults(t *testing.T) {
425426func newSendTxResult (err error ) sendTxResult [any ] {
426427 return sendTxResult [any ]{error : err }
427428}
429+
430+ func TestLoggableSendTxResults (t * testing.T ) {
431+ t .Parallel ()
432+
433+ // Input reconstructed from an observed production invariant violation log:
434+ // 1 node returned Successful (code 1), 2 nodes returned Unknown (code 5)
435+ // with "RPC call failed: TX_REPLAY_ATTACK", triggering "got success and severe error".
436+ replayAttackErr := errors .New ("RPC call failed: TX_REPLAY_ATTACK" )
437+ input := sendTxResults [any ]{
438+ Successful : {
439+ {res : nil , code : Successful , error : nil },
440+ },
441+ Unknown : {
442+ {res : nil , code : Unknown , error : replayAttackErr },
443+ {res : nil , code : Unknown , error : replayAttackErr },
444+ },
445+ }
446+
447+ got := loggableSendTxResults (input )
448+
449+ require .Equal (t , map [SendTxReturnCode ][]map [string ]any {
450+ Successful : {
451+ {"res" : nil , "code" : Successful , "error" : "" },
452+ },
453+ Unknown : {
454+ {"res" : nil , "code" : Unknown , "error" : "RPC call failed: TX_REPLAY_ATTACK" },
455+ {"res" : nil , "code" : Unknown , "error" : "RPC call failed: TX_REPLAY_ATTACK" },
456+ },
457+ }, got )
458+
459+ b , err := json .Marshal (got )
460+ require .NoError (t , err )
461+ require .JSONEq (t ,
462+ `{
463+ "Successful":[
464+ {
465+ "code":"Successful",
466+ "error":"",
467+ "res":null
468+ }
469+ ],
470+ "Unknown":[
471+ {
472+ "code":"Unknown",
473+ "error":"RPC call failed: TX_REPLAY_ATTACK",
474+ "res":null
475+ },
476+ {
477+ "code":"Unknown",
478+ "error":"RPC call failed: TX_REPLAY_ATTACK",
479+ "res":null
480+ }
481+ ]
482+ }` ,
483+ string (b ),
484+ )
485+ }
0 commit comments