diff --git a/txpool/packets.go b/txpool/packets.go index f1047186e..fc1a7f6ba 100644 --- a/txpool/packets.go +++ b/txpool/packets.go @@ -133,6 +133,9 @@ func ParseGetPooledTransactions65(payload []byte, pos int, hashbuf []byte) (hash } return hashes, pos, nil } + +// == Pooled transactions == + func EncodePooledTransactions66(txsRlp [][]byte, requestId uint64, encodeBuf []byte) []byte { pos := 0 txsRlpLen := 0 @@ -171,3 +174,53 @@ func EncodePooledTransactions65(txsRlp [][]byte, encodeBuf []byte) []byte { _ = pos return encodeBuf } + +func ParsePooledTransactions65(payload []byte, pos int, ctx *TxParseContext, txSlots *TxSlots) (newPos int, err error) { + pos, _, err = rlp.List(payload, pos) + if err != nil { + return 0, err + } + + for i := range txSlots.txs { + if txSlots.txs[i] == nil { + txSlots.txs[i] = &TxSlot{} + } + } + for i := 0; pos != len(payload); i++ { + txSlots.Growth(i) + pos, err = ctx.ParseTransaction(payload, pos, txSlots.txs[i], txSlots.senders.At(i)) + if err != nil { + return 0, err + } + } + return pos, nil +} + +func ParsePooledTransactions66(payload []byte, pos int, ctx *TxParseContext, txSlots *TxSlots) (requestID uint64, newPos int, err error) { + pos, _, err = rlp.List(payload, pos) + if err != nil { + return requestID, 0, err + } + pos, requestID, err = rlp.U64(payload, pos) + if err != nil { + return requestID, 0, err + } + pos, _, err = rlp.List(payload, pos) + if err != nil { + return requestID, 0, err + } + + for i := range txSlots.txs { + if txSlots.txs[i] == nil { + txSlots.txs[i] = &TxSlot{} + } + } + for i := 0; pos != len(payload); i++ { + txSlots.Growth(i) + pos, err = ctx.ParseTransaction(payload, pos, txSlots.txs[i], txSlots.senders.At(i)) + if err != nil { + return requestID, 0, err + } + } + return requestID, pos, nil +} diff --git a/txpool/types.go b/txpool/types.go index 439dfb90d..9ca5d40d2 100644 --- a/txpool/types.go +++ b/txpool/types.go @@ -106,6 +106,17 @@ func (s TxSlots) Valid() error { return nil } +var addressesGrowth = make([]byte, 20) + +func (s *TxSlots) Growth(targetSize int) { + for len(s.txs) < targetSize { + s.txs = append(s.txs, &TxSlot{}) + } + for s.senders.Len() < targetSize { + s.senders = append(s.senders, addressesGrowth...) + } +} + const ( LegacyTxType int = 0 AccessListTxType int = 1 diff --git a/txpool/types_test.go b/txpool/types_test.go index 7306eb87a..549e90099 100644 --- a/txpool/types_test.go +++ b/txpool/types_test.go @@ -21,6 +21,7 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -89,3 +90,22 @@ func TestParseTransactionRLP(t *testing.T) { }) } } + +func TestTxSlotsGrowth(t *testing.T) { + assert := assert.New(t) + s := &TxSlots{} + s.Growth(11) + assert.Equal(11, len(s.txs)) + assert.Equal(11, s.senders.Len()) + s.Growth(23) + assert.Equal(23, len(s.txs)) + assert.Equal(23, s.senders.Len()) + + s = &TxSlots{txs: make([]*TxSlot, 20), senders: make(Addresses, 20*20)} + s.Growth(20) + assert.Equal(20, len(s.txs)) + assert.Equal(20, s.senders.Len()) + s.Growth(23) + assert.Equal(23, len(s.txs)) + assert.Equal(23, s.senders.Len()) +}