diff --git a/txpool/packets.go b/txpool/packets.go index 1295e21ed..2f824f85b 100644 --- a/txpool/packets.go +++ b/txpool/packets.go @@ -129,7 +129,12 @@ func EncodePooledTransactions66(txsRlp [][]byte, requestId uint64, encodeBuf []b pos := 0 txsRlpLen := 0 for i := range txsRlp { - txsRlpLen += len(txsRlp[i]) + _, _, isLegacy, _ := rlp.Prefix(txsRlp[i], 0) + if isLegacy { + txsRlpLen += len(txsRlp[i]) + } else { + txsRlpLen += rlp.StringLen(len(txsRlp[i])) + } } dataLen := rlp.U64Len(requestId) + rlp.ListPrefixLen(txsRlpLen) + txsRlpLen @@ -140,8 +145,13 @@ func EncodePooledTransactions66(txsRlp [][]byte, requestId uint64, encodeBuf []b pos += rlp.EncodeU64(requestId, encodeBuf[pos:]) pos += rlp.EncodeListPrefix(txsRlpLen, encodeBuf[pos:]) for i := range txsRlp { - copy(encodeBuf[pos:], txsRlp[i]) - pos += len(txsRlp[i]) + _, _, isLegacy, _ := rlp.Prefix(txsRlp[i], 0) + if isLegacy { + copy(encodeBuf[pos:], txsRlp[i]) + pos += len(txsRlp[i]) + } else { + pos += rlp.EncodeString(txsRlp[i], encodeBuf[pos:]) + } } _ = pos return encodeBuf @@ -150,15 +160,25 @@ func EncodePooledTransactions65(txsRlp [][]byte, encodeBuf []byte) []byte { pos := 0 dataLen := 0 for i := range txsRlp { - dataLen += len(txsRlp[i]) + _, _, isLegacy, _ := rlp.Prefix(txsRlp[i], 0) + if isLegacy { + dataLen += len(txsRlp[i]) + } else { + dataLen += rlp.StringLen(len(txsRlp[i])) + } } encodeBuf = common.EnsureEnoughSize(encodeBuf, rlp.ListPrefixLen(dataLen)+dataLen) // Length Prefix for the entire structure pos += rlp.EncodeListPrefix(dataLen, encodeBuf[pos:]) for i := range txsRlp { - copy(encodeBuf[pos:], txsRlp[i]) - pos += len(txsRlp[i]) + _, _, isLegacy, _ := rlp.Prefix(txsRlp[i], 0) + if isLegacy { + copy(encodeBuf[pos:], txsRlp[i]) + pos += len(txsRlp[i]) + } else { + pos += rlp.EncodeString(txsRlp[i], encodeBuf[pos:]) + } } _ = pos return encodeBuf @@ -203,6 +223,13 @@ func ParsePooledTransactions66(payload []byte, pos int, ctx *TxParseContext, txS for i := 0; p < len(payload); i++ { txSlots.Resize(uint(i + 1)) txSlots.txs[i] = &TxSlot{} + if payload[p] > 0xb7 && payload[p] < 0xF8 { + dataPos, _, err := rlp.String(payload, p) + if err != nil { + return 0, 0, err + } + p = dataPos + } p, err = ctx.ParseTransaction(payload, p, txSlots.txs[i], txSlots.senders.At(i)) if err != nil { if errors.Is(err, ErrRejected) { diff --git a/txpool/packets_test.go b/txpool/packets_test.go index 2a2f6a4bb..736d8840a 100644 --- a/txpool/packets_test.go +++ b/txpool/packets_test.go @@ -22,6 +22,7 @@ import ( "strconv" "testing" + "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/common/u256" "github.com/stretchr/testify/require" ) @@ -115,14 +116,22 @@ var ptp66EncodeTests = []struct { txs [][]byte encoded string requestId uint64 + chainID uint64 expectedErr bool }{ + { + txs: [][]byte{ + decodeHex("02f870051b8477359400847735940a82520894c388750a661cc0b99784bab2c55e1f38ff91643b861319718a500080c080a028bf802cf4be66f51ab0570fa9fc06365c1b816b8a7ffe40bc05f9a0d2d12867a012c2ce1fc908e7a903b750388c8c2ae82383a476bc345b7c2826738fc321fcab"), + }, + encoded: "f88088a4e61e8ad32f4845f875b87302f870051b8477359400847735940a82520894c388750a661cc0b99784bab2c55e1f38ff91643b861319718a500080c080a028bf802cf4be66f51ab0570fa9fc06365c1b816b8a7ffe40bc05f9a0d2d12867a012c2ce1fc908e7a903b750388c8c2ae82383a476bc345b7c2826738fc321fcab", requestId: 11882218248461043781, expectedErr: false, chainID: 5, + }, { txs: [][]byte{ decodeHex("f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10"), decodeHex("f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb"), }, - encoded: "f8d7820457f8d2f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", requestId: 1111, expectedErr: false}, + encoded: "f8d7820457f8d2f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", requestId: 1111, expectedErr: false, chainID: 1, + }, } func TestPooledTransactionsPacket(t *testing.T) { @@ -141,14 +150,15 @@ func TestPooledTransactionsPacket66(t *testing.T) { encodeBuf = EncodePooledTransactions66(tt.txs, tt.requestId, encodeBuf) require.Equal(tt.encoded, fmt.Sprintf("%x", encodeBuf)) - ctx := NewTxParseContext(*u256.N1) + ctx := NewTxParseContext(*uint256.NewInt(tt.chainID)) slots := &TxSlots{} requestId, _, err := ParsePooledTransactions66(encodeBuf, 0, ctx, slots) require.NoError(err) require.Equal(tt.requestId, requestId) require.Equal(len(tt.txs), len(slots.txs)) - require.Equal(fmt.Sprintf("%x", tt.txs[0]), fmt.Sprintf("%x", slots.txs[0].rlp)) - require.Equal(fmt.Sprintf("%x", tt.txs[1]), fmt.Sprintf("%x", slots.txs[1].rlp)) + for i, txn := range tt.txs { + require.Equal(fmt.Sprintf("%x", txn), fmt.Sprintf("%x", slots.txs[i].rlp)) + } }) } for i, tt := range ptp66EncodeTests {