github.com/ledgerwatch/erigon-lib@v1.0.0/types/txn_packets_test.go (about) 1 /* 2 Copyright 2021 The Erigon contributors 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package types 18 19 import ( 20 "fmt" 21 "strconv" 22 "testing" 23 24 "github.com/holiman/uint256" 25 "github.com/stretchr/testify/require" 26 27 "github.com/ledgerwatch/erigon-lib/common/hexutility" 28 ) 29 30 var hashParseTests = []struct { 31 payloadStr string 32 hashStr string 33 expectedErr bool 34 }{ 35 {payloadStr: "a0595e27a835cd79729ff1eeacec3120eeb6ed1464a04ec727aaca734ead961328", hashStr: "595e27a835cd79729ff1eeacec3120eeb6ed1464a04ec727aaca734ead961328", expectedErr: false}, 36 } 37 38 func TestParseHash(t *testing.T) { 39 for i, tt := range hashParseTests { 40 t.Run(strconv.Itoa(i), func(t *testing.T) { 41 require := require.New(t) 42 var hashBuf [32]byte 43 payload := hexutility.MustDecodeHex(tt.payloadStr) 44 _, parseEnd, err := ParseHash(payload, 0, hashBuf[:0]) 45 require.Equal(tt.expectedErr, err != nil) 46 require.Equal(len(payload), parseEnd) 47 require.Equal(hexutility.MustDecodeHex(tt.hashStr), hashBuf[:]) 48 }) 49 } 50 } 51 52 var hashEncodeTests = []struct { 53 payloadStr string 54 hashesStr string 55 hashCount int 56 expectedErr bool 57 }{ 58 {payloadStr: "e1a0595e27a835cd79729ff1eeacec3120eeb6ed1464a04ec727aaca734ead961328", 59 hashesStr: "595e27a835cd79729ff1eeacec3120eeb6ed1464a04ec727aaca734ead961328", hashCount: 1, expectedErr: false}, 60 {hashesStr: fmt.Sprintf("%x", toHashes(1, 2, 3)), 61 payloadStr: "f863a00100000000000000000000000000000000000000000000000000000000000000a00200000000000000000000000000000000000000000000000000000000000000a00300000000000000000000000000000000000000000000000000000000000000", hashCount: 3, expectedErr: false}, 62 } 63 64 func TestEncodeHash(t *testing.T) { 65 for i, tt := range hashEncodeTests { 66 t.Run(strconv.Itoa(i), func(t *testing.T) { 67 require := require.New(t) 68 var encodeBuf []byte 69 encodeBuf = EncodeHashes(hexutility.MustDecodeHex(tt.hashesStr), encodeBuf) 70 require.Equal(hexutility.MustDecodeHex(tt.payloadStr), encodeBuf) 71 }) 72 } 73 } 74 75 var gpt66EncodeTests = []struct { 76 payloadStr string 77 hashesStr string 78 hashCount int 79 requestID uint64 80 expectedErr bool 81 }{ 82 {payloadStr: "e68306f854e1a0595e27a835cd79729ff1eeacec3120eeb6ed1464a04ec727aaca734ead961328", 83 hashesStr: "595e27a835cd79729ff1eeacec3120eeb6ed1464a04ec727aaca734ead961328", hashCount: 1, requestID: 456788, expectedErr: false}, 84 } 85 86 // TestEncodeGPT66 tests the encoding of GetPoolTransactions66 packet 87 func TestEncodeGPT66(t *testing.T) { 88 for i, tt := range gpt66EncodeTests { 89 t.Run(strconv.Itoa(i), func(t *testing.T) { 90 require := require.New(t) 91 var encodeBuf []byte 92 var err error 93 encodeBuf, err = EncodeGetPooledTransactions66(hexutility.MustDecodeHex(tt.hashesStr), tt.requestID, encodeBuf) 94 require.Equal(tt.expectedErr, err != nil) 95 require.Equal(hexutility.MustDecodeHex(tt.payloadStr), encodeBuf) 96 if err != nil { 97 return 98 } 99 requestID, hashes, _, err := ParseGetPooledTransactions66(encodeBuf, 0, nil) 100 require.Equal(tt.expectedErr, err != nil) 101 require.Equal(tt.requestID, requestID) 102 require.Equal(hexutility.MustDecodeHex(tt.hashesStr), hashes) 103 }) 104 } 105 } 106 107 var ptp66EncodeTests = []struct { 108 txs [][]byte 109 encoded string 110 requestID uint64 111 chainID uint64 112 expectedErr bool 113 }{ 114 { 115 txs: [][]byte{ 116 hexutility.MustDecodeHex("02f870051b8477359400847735940a82520894c388750a661cc0b99784bab2c55e1f38ff91643b861319718a500080c080a028bf802cf4be66f51ab0570fa9fc06365c1b816b8a7ffe40bc05f9a0d2d12867a012c2ce1fc908e7a903b750388c8c2ae82383a476bc345b7c2826738fc321fcab"), 117 }, 118 encoded: "f88088a4e61e8ad32f4845f875b87302f870051b8477359400847735940a82520894c388750a661cc0b99784bab2c55e1f38ff91643b861319718a500080c080a028bf802cf4be66f51ab0570fa9fc06365c1b816b8a7ffe40bc05f9a0d2d12867a012c2ce1fc908e7a903b750388c8c2ae82383a476bc345b7c2826738fc321fcab", requestID: 11882218248461043781, expectedErr: false, chainID: 5, 119 }, 120 { 121 txs: [][]byte{ 122 hexutility.MustDecodeHex("f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10"), 123 hexutility.MustDecodeHex("f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb"), 124 }, 125 encoded: "f8d7820457f8d2f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", requestID: 1111, expectedErr: false, chainID: 1, 126 }, 127 } 128 129 func TestPooledTransactionsPacket(t *testing.T) { 130 b := hexutility.MustDecodeHex("e317e1a084a64018534279c4d3f05ea8cc7c9bfaa6f72d09c1d0a5f3be337e8b9226a680") 131 requestID, out, pos, err := ParseGetPooledTransactions66(b, 0, nil) 132 require.NoError(t, err) 133 require.Equal(t, uint64(23), requestID) 134 require.Equal(t, hexutility.MustDecodeHex("84a64018534279c4d3f05ea8cc7c9bfaa6f72d09c1d0a5f3be337e8b9226a680"), out) 135 require.Equal(t, 36, pos) 136 } 137 138 func TestPooledTransactionsPacket66(t *testing.T) { 139 for i, tt := range ptp66EncodeTests { 140 t.Run(strconv.Itoa(i), func(t *testing.T) { 141 require := require.New(t) 142 var encodeBuf []byte 143 encodeBuf = EncodePooledTransactions66(tt.txs, tt.requestID, encodeBuf) 144 require.Equal(tt.encoded, fmt.Sprintf("%x", encodeBuf)) 145 146 ctx := NewTxParseContext(*uint256.NewInt(tt.chainID)) 147 slots := &TxSlots{} 148 requestID, _, err := ParsePooledTransactions66(encodeBuf, 0, ctx, slots, nil) 149 require.NoError(err) 150 require.Equal(tt.requestID, requestID) 151 require.Equal(len(tt.txs), len(slots.Txs)) 152 for i, txn := range tt.txs { 153 require.Equal(fmt.Sprintf("%x", txn), fmt.Sprintf("%x", slots.Txs[i].Rlp)) 154 } 155 }) 156 } 157 for i, tt := range ptp66EncodeTests { 158 t.Run("reject_all_"+strconv.Itoa(i), func(t *testing.T) { 159 require := require.New(t) 160 var encodeBuf []byte 161 encodeBuf = EncodePooledTransactions66(tt.txs, tt.requestID, encodeBuf) 162 require.Equal(tt.encoded, fmt.Sprintf("%x", encodeBuf)) 163 164 chainID := uint256.NewInt(tt.chainID) 165 ctx := NewTxParseContext(*chainID) 166 slots := &TxSlots{} 167 requestID, _, err := ParsePooledTransactions66(encodeBuf, 0, ctx, slots, func(bytes []byte) error { return ErrRejected }) 168 require.NoError(err) 169 require.Equal(tt.requestID, requestID) 170 require.Equal(0, len(slots.Txs)) 171 require.Equal(0, slots.Senders.Len()) 172 require.Equal(0, len(slots.IsLocal)) 173 }) 174 } 175 } 176 177 var tpEncodeTests = []struct { 178 txs [][]byte 179 encoded string 180 chainID uint64 181 expectedErr bool 182 }{ 183 { 184 txs: [][]byte{ 185 hexutility.MustDecodeHex("02f870051b8477359400847735940a82520894c388750a661cc0b99784bab2c55e1f38ff91643b861319718a500080c080a028bf802cf4be66f51ab0570fa9fc06365c1b816b8a7ffe40bc05f9a0d2d12867a012c2ce1fc908e7a903b750388c8c2ae82383a476bc345b7c2826738fc321fcab"), 186 }, 187 encoded: "f875b87302f870051b8477359400847735940a82520894c388750a661cc0b99784bab2c55e1f38ff91643b861319718a500080c080a028bf802cf4be66f51ab0570fa9fc06365c1b816b8a7ffe40bc05f9a0d2d12867a012c2ce1fc908e7a903b750388c8c2ae82383a476bc345b7c2826738fc321fcab", expectedErr: false, chainID: 5, 188 }, 189 { 190 txs: [][]byte{ 191 hexutility.MustDecodeHex("f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10"), 192 hexutility.MustDecodeHex("f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb"), 193 }, 194 encoded: "f8d2f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", expectedErr: false, chainID: 1, 195 }, 196 } 197 198 func TestTransactionsPacket(t *testing.T) { 199 for i, tt := range tpEncodeTests { 200 t.Run(strconv.Itoa(i), func(t *testing.T) { 201 require := require.New(t) 202 var encodeBuf []byte 203 encodeBuf = EncodeTransactions(tt.txs, encodeBuf) 204 require.Equal(tt.encoded, fmt.Sprintf("%x", encodeBuf)) 205 206 ctx := NewTxParseContext(*uint256.NewInt(tt.chainID)) 207 slots := &TxSlots{} 208 _, err := ParseTransactions(encodeBuf, 0, ctx, slots, nil) 209 require.NoError(err) 210 require.Equal(len(tt.txs), len(slots.Txs)) 211 for i, txn := range tt.txs { 212 require.Equal(fmt.Sprintf("%x", txn), fmt.Sprintf("%x", slots.Txs[i].Rlp)) 213 } 214 }) 215 } 216 for i, tt := range tpEncodeTests { 217 t.Run("reject_all_"+strconv.Itoa(i), func(t *testing.T) { 218 require := require.New(t) 219 var encodeBuf []byte 220 encodeBuf = EncodeTransactions(tt.txs, encodeBuf) 221 require.Equal(tt.encoded, fmt.Sprintf("%x", encodeBuf)) 222 223 chainID := uint256.NewInt(tt.chainID) 224 ctx := NewTxParseContext(*chainID) 225 slots := &TxSlots{} 226 _, err := ParseTransactions(encodeBuf, 0, ctx, slots, func(bytes []byte) error { return ErrRejected }) 227 require.NoError(err) 228 require.Equal(0, len(slots.Txs)) 229 require.Equal(0, slots.Senders.Len()) 230 require.Equal(0, len(slots.IsLocal)) 231 }) 232 } 233 }