github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/jsonrpc/endpoints_eth_test.go (about) 1 package jsonrpc 2 3 import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "math/big" 8 "strings" 9 "testing" 10 "time" 11 12 "github.com/0xPolygon/supernets2-node/encoding" 13 "github.com/0xPolygon/supernets2-node/hex" 14 "github.com/0xPolygon/supernets2-node/jsonrpc/types" 15 "github.com/0xPolygon/supernets2-node/pool" 16 "github.com/0xPolygon/supernets2-node/state" 17 "github.com/0xPolygon/supernets2-node/state/runtime" 18 "github.com/ethereum/go-ethereum" 19 "github.com/ethereum/go-ethereum/accounts/abi/bind" 20 "github.com/ethereum/go-ethereum/common" 21 ethTypes "github.com/ethereum/go-ethereum/core/types" 22 "github.com/ethereum/go-ethereum/crypto" 23 "github.com/ethereum/go-ethereum/rpc" 24 "github.com/ethereum/go-ethereum/trie" 25 "github.com/gorilla/websocket" 26 "github.com/jackc/pgx/v4" 27 "github.com/stretchr/testify/assert" 28 "github.com/stretchr/testify/mock" 29 "github.com/stretchr/testify/require" 30 ) 31 32 var ( 33 latest = "latest" 34 blockNumOne = big.NewInt(1) 35 blockNumOneUint64 = blockNumOne.Uint64() 36 blockNumTen = big.NewInt(10) 37 blockNumTenUint64 = blockNumTen.Uint64() 38 addressArg = common.HexToAddress("0x123") 39 keyArg = common.HexToHash("0x123") 40 blockHash = common.HexToHash("0x82ba516e76a4bfaba6d1d95c8ccde96e353ce3c683231d011021f43dee7b2d95") 41 blockRoot = common.HexToHash("0xce3c683231d011021f43dee7b2d9582ba516e76a4bfaba6d1d95c8ccde96e353") 42 nilUint64 *uint64 43 ) 44 45 func TestBlockNumber(t *testing.T) { 46 s, m, c := newSequencerMockedServer(t) 47 defer s.Stop() 48 49 type testCase struct { 50 Name string 51 ExpectedResult uint64 52 ExpectedError interface{} 53 SetupMocks func(m *mocksWrapper) 54 } 55 56 testCases := []testCase{ 57 { 58 Name: "get block number successfully", 59 ExpectedError: nil, 60 ExpectedResult: blockNumTen.Uint64(), 61 SetupMocks: func(m *mocksWrapper) { 62 m.DbTx. 63 On("Commit", context.Background()). 64 Return(nil). 65 Once() 66 67 m.State. 68 On("BeginStateTransaction", context.Background()). 69 Return(m.DbTx, nil). 70 Once() 71 72 m.State. 73 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 74 Return(blockNumTen.Uint64(), nil). 75 Once() 76 }, 77 }, 78 { 79 Name: "failed to get block number", 80 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get the last block number from state"), 81 ExpectedResult: 0, 82 SetupMocks: func(m *mocksWrapper) { 83 m.DbTx. 84 On("Rollback", context.Background()). 85 Return(nil). 86 Once() 87 88 m.State. 89 On("BeginStateTransaction", context.Background()). 90 Return(m.DbTx, nil). 91 Once() 92 93 m.State. 94 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 95 Return(uint64(0), errors.New("failed to get last block number")). 96 Once() 97 }, 98 }, 99 } 100 101 for _, testCase := range testCases { 102 t.Run(testCase.Name, func(t *testing.T) { 103 tc := testCase 104 tc.SetupMocks(m) 105 106 result, err := c.BlockNumber(context.Background()) 107 assert.Equal(t, testCase.ExpectedResult, result) 108 109 if err != nil || testCase.ExpectedError != nil { 110 if expectedErr, ok := testCase.ExpectedError.(*types.RPCError); ok { 111 rpcErr := err.(rpc.Error) 112 assert.Equal(t, expectedErr.ErrorCode(), rpcErr.ErrorCode()) 113 assert.Equal(t, expectedErr.Error(), rpcErr.Error()) 114 } else { 115 assert.Equal(t, testCase.ExpectedError, err) 116 } 117 } 118 }) 119 } 120 } 121 122 func TestCall(t *testing.T) { 123 s, m, _ := newSequencerMockedServer(t) 124 defer s.Stop() 125 126 type testCase struct { 127 name string 128 params []interface{} 129 expectedResult []byte 130 expectedError interface{} 131 setupMocks func(Config, *mocksWrapper, *testCase) 132 } 133 134 testCases := []*testCase{ 135 { 136 name: "Transaction with all information from a block with EIP-1898", 137 params: []interface{}{ 138 types.TxArgs{ 139 From: state.HexToAddressPtr("0x1"), 140 To: state.HexToAddressPtr("0x2"), 141 Gas: types.ArgUint64Ptr(24000), 142 GasPrice: types.ArgBytesPtr(big.NewInt(1).Bytes()), 143 Value: types.ArgBytesPtr(big.NewInt(2).Bytes()), 144 Data: types.ArgBytesPtr([]byte("data")), 145 }, 146 map[string]interface{}{ 147 types.BlockNumberKey: hex.EncodeBig(blockNumOne), 148 }, 149 }, 150 expectedResult: []byte("hello world"), 151 expectedError: nil, 152 setupMocks: func(c Config, m *mocksWrapper, testCase *testCase) { 153 nonce := uint64(7) 154 m.DbTx.On("Commit", context.Background()).Return(nil).Once() 155 m.State.On("BeginStateTransaction", context.Background()).Return(m.DbTx, nil).Once() 156 txArgs := testCase.params[0].(types.TxArgs) 157 txMatchBy := mock.MatchedBy(func(tx *ethTypes.Transaction) bool { 158 gasPrice := big.NewInt(0).SetBytes(*txArgs.GasPrice) 159 value := big.NewInt(0).SetBytes(*txArgs.Value) 160 match := tx != nil && 161 tx.To().Hex() == txArgs.To.Hex() && 162 tx.Gas() == uint64(*txArgs.Gas) && 163 tx.GasPrice().Uint64() == gasPrice.Uint64() && 164 tx.Value().Uint64() == value.Uint64() && 165 hex.EncodeToHex(tx.Data()) == hex.EncodeToHex(*txArgs.Data) && 166 tx.Nonce() == nonce 167 return match 168 }) 169 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumOne, Root: blockRoot}) 170 m.State.On("GetL2BlockByNumber", context.Background(), blockNumOneUint64, m.DbTx).Return(block, nil).Once() 171 m.State.On("GetNonce", context.Background(), *txArgs.From, blockRoot).Return(nonce, nil).Once() 172 m.State. 173 On("ProcessUnsignedTransaction", context.Background(), txMatchBy, *txArgs.From, &blockNumOneUint64, true, m.DbTx). 174 Return(&runtime.ExecutionResult{ReturnValue: testCase.expectedResult}, nil). 175 Once() 176 }, 177 }, 178 { 179 name: "Transaction with all information from block by hash with EIP-1898", 180 params: []interface{}{ 181 types.TxArgs{ 182 From: state.HexToAddressPtr("0x1"), 183 To: state.HexToAddressPtr("0x2"), 184 Gas: types.ArgUint64Ptr(24000), 185 GasPrice: types.ArgBytesPtr(big.NewInt(1).Bytes()), 186 Value: types.ArgBytesPtr(big.NewInt(2).Bytes()), 187 Data: types.ArgBytesPtr([]byte("data")), 188 }, 189 map[string]interface{}{ 190 types.BlockHashKey: blockHash.String(), 191 }, 192 }, 193 expectedResult: []byte("hello world"), 194 expectedError: nil, 195 setupMocks: func(c Config, m *mocksWrapper, testCase *testCase) { 196 nonce := uint64(7) 197 m.DbTx.On("Commit", context.Background()).Return(nil).Once() 198 m.State.On("BeginStateTransaction", context.Background()).Return(m.DbTx, nil).Once() 199 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumOne, Root: blockRoot}) 200 m.State. 201 On("GetL2BlockByHash", context.Background(), blockHash, m.DbTx). 202 Return(block, nil).Once() 203 txArgs := testCase.params[0].(types.TxArgs) 204 txMatchBy := mock.MatchedBy(func(tx *ethTypes.Transaction) bool { 205 gasPrice := big.NewInt(0).SetBytes(*txArgs.GasPrice) 206 value := big.NewInt(0).SetBytes(*txArgs.Value) 207 return tx != nil && 208 tx.To().Hex() == txArgs.To.Hex() && 209 tx.Gas() == uint64(*txArgs.Gas) && 210 tx.GasPrice().Uint64() == gasPrice.Uint64() && 211 tx.Value().Uint64() == value.Uint64() && 212 hex.EncodeToHex(tx.Data()) == hex.EncodeToHex(*txArgs.Data) && 213 tx.Nonce() == nonce 214 }) 215 m.State.On("GetNonce", context.Background(), *txArgs.From, blockRoot).Return(nonce, nil).Once() 216 m.State. 217 On("ProcessUnsignedTransaction", context.Background(), txMatchBy, *txArgs.From, &blockNumOneUint64, true, m.DbTx). 218 Return(&runtime.ExecutionResult{ReturnValue: testCase.expectedResult}, nil). 219 Once() 220 }, 221 }, 222 { 223 name: "Transaction with all information from latest block", 224 params: []interface{}{ 225 types.TxArgs{ 226 From: state.HexToAddressPtr("0x1"), 227 To: state.HexToAddressPtr("0x2"), 228 Gas: types.ArgUint64Ptr(24000), 229 GasPrice: types.ArgBytesPtr(big.NewInt(1).Bytes()), 230 Value: types.ArgBytesPtr(big.NewInt(2).Bytes()), 231 Data: types.ArgBytesPtr([]byte("data")), 232 }, 233 latest, 234 }, 235 expectedResult: []byte("hello world"), 236 expectedError: nil, 237 setupMocks: func(c Config, m *mocksWrapper, testCase *testCase) { 238 nonce := uint64(7) 239 m.DbTx.On("Commit", context.Background()).Return(nil).Once() 240 m.State.On("BeginStateTransaction", context.Background()).Return(m.DbTx, nil).Once() 241 m.State.On("GetLastL2BlockNumber", context.Background(), m.DbTx).Return(blockNumOne.Uint64(), nil).Once() 242 txArgs := testCase.params[0].(types.TxArgs) 243 txMatchBy := mock.MatchedBy(func(tx *ethTypes.Transaction) bool { 244 gasPrice := big.NewInt(0).SetBytes(*txArgs.GasPrice) 245 value := big.NewInt(0).SetBytes(*txArgs.Value) 246 match := tx != nil && 247 tx.To().Hex() == txArgs.To.Hex() && 248 tx.Gas() == uint64(*txArgs.Gas) && 249 tx.GasPrice().Uint64() == gasPrice.Uint64() && 250 tx.Value().Uint64() == value.Uint64() && 251 hex.EncodeToHex(tx.Data()) == hex.EncodeToHex(*txArgs.Data) && 252 tx.Nonce() == nonce 253 return match 254 }) 255 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumOne, Root: blockRoot}) 256 m.State.On("GetL2BlockByNumber", context.Background(), blockNumOneUint64, m.DbTx).Return(block, nil).Once() 257 m.State.On("GetNonce", context.Background(), *txArgs.From, blockRoot).Return(nonce, nil).Once() 258 m.State. 259 On("ProcessUnsignedTransaction", context.Background(), txMatchBy, *txArgs.From, nilUint64, true, m.DbTx). 260 Return(&runtime.ExecutionResult{ReturnValue: testCase.expectedResult}, nil). 261 Once() 262 }, 263 }, 264 { 265 name: "Transaction with all information from block by hash", 266 params: []interface{}{ 267 types.TxArgs{ 268 From: state.HexToAddressPtr("0x1"), 269 To: state.HexToAddressPtr("0x2"), 270 Gas: types.ArgUint64Ptr(24000), 271 GasPrice: types.ArgBytesPtr(big.NewInt(1).Bytes()), 272 Value: types.ArgBytesPtr(big.NewInt(2).Bytes()), 273 Data: types.ArgBytesPtr([]byte("data")), 274 }, 275 blockHash.String(), 276 }, 277 expectedResult: []byte("hello world"), 278 expectedError: nil, 279 setupMocks: func(c Config, m *mocksWrapper, testCase *testCase) { 280 nonce := uint64(7) 281 m.DbTx.On("Commit", context.Background()).Return(nil).Once() 282 m.State.On("BeginStateTransaction", context.Background()).Return(m.DbTx, nil).Once() 283 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumTen, Root: blockRoot}) 284 m.State. 285 On("GetL2BlockByHash", context.Background(), blockHash, m.DbTx). 286 Return(block, nil).Once() 287 txArgs := testCase.params[0].(types.TxArgs) 288 txMatchBy := mock.MatchedBy(func(tx *ethTypes.Transaction) bool { 289 gasPrice := big.NewInt(0).SetBytes(*txArgs.GasPrice) 290 value := big.NewInt(0).SetBytes(*txArgs.Value) 291 return tx != nil && 292 tx.To().Hex() == txArgs.To.Hex() && 293 tx.Gas() == uint64(*txArgs.Gas) && 294 tx.GasPrice().Uint64() == gasPrice.Uint64() && 295 tx.Value().Uint64() == value.Uint64() && 296 hex.EncodeToHex(tx.Data()) == hex.EncodeToHex(*txArgs.Data) && 297 tx.Nonce() == nonce 298 }) 299 m.State.On("GetNonce", context.Background(), *txArgs.From, blockRoot).Return(nonce, nil).Once() 300 m.State. 301 On("ProcessUnsignedTransaction", context.Background(), txMatchBy, *txArgs.From, &blockNumTenUint64, true, m.DbTx). 302 Return(&runtime.ExecutionResult{ReturnValue: testCase.expectedResult}, nil). 303 Once() 304 }, 305 }, 306 { 307 name: "Transaction with all information from block by number", 308 params: []interface{}{ 309 types.TxArgs{ 310 From: state.HexToAddressPtr("0x1"), 311 To: state.HexToAddressPtr("0x2"), 312 Gas: types.ArgUint64Ptr(24000), 313 GasPrice: types.ArgBytesPtr(big.NewInt(1).Bytes()), 314 Value: types.ArgBytesPtr(big.NewInt(2).Bytes()), 315 Data: types.ArgBytesPtr([]byte("data")), 316 }, 317 "0xa", 318 }, 319 expectedResult: []byte("hello world"), 320 expectedError: nil, 321 setupMocks: func(c Config, m *mocksWrapper, testCase *testCase) { 322 nonce := uint64(7) 323 m.DbTx.On("Commit", context.Background()).Return(nil).Once() 324 m.State.On("BeginStateTransaction", context.Background()).Return(m.DbTx, nil).Once() 325 txArgs := testCase.params[0].(types.TxArgs) 326 txMatchBy := mock.MatchedBy(func(tx *ethTypes.Transaction) bool { 327 gasPrice := big.NewInt(0).SetBytes(*txArgs.GasPrice) 328 value := big.NewInt(0).SetBytes(*txArgs.Value) 329 return tx != nil && 330 tx.To().Hex() == txArgs.To.Hex() && 331 tx.Gas() == uint64(*txArgs.Gas) && 332 tx.GasPrice().Uint64() == gasPrice.Uint64() && 333 tx.Value().Uint64() == value.Uint64() && 334 hex.EncodeToHex(tx.Data()) == hex.EncodeToHex(*txArgs.Data) && 335 tx.Nonce() == nonce 336 }) 337 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumTen, Root: blockRoot}) 338 m.State.On("GetL2BlockByNumber", context.Background(), blockNumTenUint64, m.DbTx).Return(block, nil).Once() 339 m.State.On("GetNonce", context.Background(), *txArgs.From, blockRoot).Return(nonce, nil).Once() 340 m.State. 341 On("ProcessUnsignedTransaction", context.Background(), txMatchBy, *txArgs.From, &blockNumTenUint64, true, m.DbTx). 342 Return(&runtime.ExecutionResult{ReturnValue: testCase.expectedResult}, nil). 343 Once() 344 }, 345 }, 346 { 347 name: "Transaction without from and gas from latest block", 348 params: []interface{}{ 349 types.TxArgs{ 350 To: state.HexToAddressPtr("0x2"), 351 GasPrice: types.ArgBytesPtr(big.NewInt(0).Bytes()), 352 Value: types.ArgBytesPtr(big.NewInt(2).Bytes()), 353 Data: types.ArgBytesPtr([]byte("data")), 354 }, 355 latest, 356 }, 357 expectedResult: []byte("hello world"), 358 expectedError: nil, 359 setupMocks: func(c Config, m *mocksWrapper, testCase *testCase) { 360 blockHeader := ðTypes.Header{GasLimit: s.Config.MaxCumulativeGasUsed} 361 m.DbTx.On("Commit", context.Background()).Return(nil).Once() 362 m.State.On("BeginStateTransaction", context.Background()).Return(m.DbTx, nil).Once() 363 m.State.On("GetLastL2BlockNumber", context.Background(), m.DbTx).Return(blockNumOne.Uint64(), nil).Once() 364 m.State.On("GetL2BlockHeaderByNumber", context.Background(), blockNumOne.Uint64(), m.DbTx).Return(blockHeader, nil).Once() 365 txArgs := testCase.params[0].(types.TxArgs) 366 txMatchBy := mock.MatchedBy(func(tx *ethTypes.Transaction) bool { 367 gasPrice := big.NewInt(0).SetBytes(*txArgs.GasPrice) 368 value := big.NewInt(0).SetBytes(*txArgs.Value) 369 hasTx := tx != nil 370 gasMatch := tx.Gas() == blockHeader.GasLimit 371 toMatch := tx.To().Hex() == txArgs.To.Hex() 372 gasPriceMatch := tx.GasPrice().Uint64() == gasPrice.Uint64() 373 valueMatch := tx.Value().Uint64() == value.Uint64() 374 dataMatch := hex.EncodeToHex(tx.Data()) == hex.EncodeToHex(*txArgs.Data) 375 return hasTx && gasMatch && toMatch && gasPriceMatch && valueMatch && dataMatch 376 }) 377 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumOne, Root: blockRoot}) 378 m.State.On("GetL2BlockByNumber", context.Background(), blockNumOneUint64, m.DbTx).Return(block, nil).Once() 379 m.State. 380 On("ProcessUnsignedTransaction", context.Background(), txMatchBy, common.HexToAddress(DefaultSenderAddress), nilUint64, true, m.DbTx). 381 Return(&runtime.ExecutionResult{ReturnValue: testCase.expectedResult}, nil). 382 Once() 383 }, 384 }, 385 { 386 name: "Transaction without from and gas from pending block", 387 params: []interface{}{ 388 types.TxArgs{ 389 To: state.HexToAddressPtr("0x2"), 390 GasPrice: types.ArgBytesPtr(big.NewInt(0).Bytes()), 391 Value: types.ArgBytesPtr(big.NewInt(2).Bytes()), 392 Data: types.ArgBytesPtr([]byte("data")), 393 }, 394 "pending", 395 }, 396 expectedResult: []byte("hello world"), 397 expectedError: nil, 398 setupMocks: func(c Config, m *mocksWrapper, testCase *testCase) { 399 blockHeader := ðTypes.Header{GasLimit: s.Config.MaxCumulativeGasUsed} 400 m.DbTx.On("Commit", context.Background()).Return(nil).Once() 401 m.State.On("BeginStateTransaction", context.Background()).Return(m.DbTx, nil).Once() 402 m.State.On("GetLastL2BlockNumber", context.Background(), m.DbTx).Return(blockNumOne.Uint64(), nil).Once() 403 m.State.On("GetL2BlockHeaderByNumber", context.Background(), blockNumOne.Uint64(), m.DbTx).Return(blockHeader, nil).Once() 404 txArgs := testCase.params[0].(types.TxArgs) 405 txMatchBy := mock.MatchedBy(func(tx *ethTypes.Transaction) bool { 406 gasPrice := big.NewInt(0).SetBytes(*txArgs.GasPrice) 407 value := big.NewInt(0).SetBytes(*txArgs.Value) 408 hasTx := tx != nil 409 gasMatch := tx.Gas() == blockHeader.GasLimit 410 toMatch := tx.To().Hex() == txArgs.To.Hex() 411 gasPriceMatch := tx.GasPrice().Uint64() == gasPrice.Uint64() 412 valueMatch := tx.Value().Uint64() == value.Uint64() 413 dataMatch := hex.EncodeToHex(tx.Data()) == hex.EncodeToHex(*txArgs.Data) 414 return hasTx && gasMatch && toMatch && gasPriceMatch && valueMatch && dataMatch 415 }) 416 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumOne, Root: blockRoot}) 417 m.State.On("GetL2BlockByNumber", context.Background(), blockNumOneUint64, m.DbTx).Return(block, nil).Once() 418 m.State. 419 On("ProcessUnsignedTransaction", context.Background(), txMatchBy, common.HexToAddress(DefaultSenderAddress), nilUint64, true, m.DbTx). 420 Return(&runtime.ExecutionResult{ReturnValue: testCase.expectedResult}, nil). 421 Once() 422 }, 423 }, 424 { 425 name: "Transaction without from and gas and failed to get block header", 426 params: []interface{}{ 427 types.TxArgs{ 428 To: state.HexToAddressPtr("0x2"), 429 GasPrice: types.ArgBytesPtr(big.NewInt(0).Bytes()), 430 Value: types.ArgBytesPtr(big.NewInt(2).Bytes()), 431 Data: types.ArgBytesPtr([]byte("data")), 432 }, 433 latest, 434 }, 435 expectedResult: nil, 436 expectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get block header"), 437 setupMocks: func(c Config, m *mocksWrapper, testCase *testCase) { 438 m.DbTx.On("Rollback", context.Background()).Return(nil).Once() 439 m.State.On("BeginStateTransaction", context.Background()).Return(m.DbTx, nil).Once() 440 m.State.On("GetLastL2BlockNumber", context.Background(), m.DbTx).Return(blockNumOne.Uint64(), nil).Once() 441 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumOne, Root: blockRoot}) 442 m.State.On("GetL2BlockByNumber", context.Background(), blockNumOneUint64, m.DbTx).Return(block, nil).Once() 443 m.State.On("GetL2BlockHeaderByNumber", context.Background(), blockNumOne.Uint64(), m.DbTx).Return(nil, errors.New("failed to get block header")).Once() 444 }, 445 }, 446 { 447 name: "Transaction with all information but failed to process unsigned transaction", 448 params: []interface{}{ 449 types.TxArgs{ 450 From: state.HexToAddressPtr("0x1"), 451 To: state.HexToAddressPtr("0x2"), 452 Gas: types.ArgUint64Ptr(24000), 453 GasPrice: types.ArgBytesPtr(big.NewInt(1).Bytes()), 454 Value: types.ArgBytesPtr(big.NewInt(2).Bytes()), 455 Data: types.ArgBytesPtr([]byte("data")), 456 }, 457 latest, 458 }, 459 expectedResult: nil, 460 expectedError: types.NewRPCError(types.DefaultErrorCode, "failed to process unsigned transaction"), 461 setupMocks: func(c Config, m *mocksWrapper, testCase *testCase) { 462 nonce := uint64(7) 463 m.DbTx.On("Rollback", context.Background()).Return(nil).Once() 464 m.State.On("BeginStateTransaction", context.Background()).Return(m.DbTx, nil).Once() 465 m.State.On("GetLastL2BlockNumber", context.Background(), m.DbTx).Return(blockNumOne.Uint64(), nil).Once() 466 txArgs := testCase.params[0].(types.TxArgs) 467 txMatchBy := mock.MatchedBy(func(tx *ethTypes.Transaction) bool { 468 gasPrice := big.NewInt(0).SetBytes(*txArgs.GasPrice) 469 value := big.NewInt(0).SetBytes(*txArgs.Value) 470 hasTx := tx != nil 471 gasMatch := tx.Gas() == uint64(*txArgs.Gas) 472 toMatch := tx.To().Hex() == txArgs.To.Hex() 473 gasPriceMatch := tx.GasPrice().Uint64() == gasPrice.Uint64() 474 valueMatch := tx.Value().Uint64() == value.Uint64() 475 dataMatch := hex.EncodeToHex(tx.Data()) == hex.EncodeToHex(*txArgs.Data) 476 nonceMatch := tx.Nonce() == nonce 477 return hasTx && gasMatch && toMatch && gasPriceMatch && valueMatch && dataMatch && nonceMatch 478 }) 479 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumOne, Root: blockRoot}) 480 m.State.On("GetL2BlockByNumber", context.Background(), blockNumOneUint64, m.DbTx).Return(block, nil).Once() 481 m.State.On("GetNonce", context.Background(), *txArgs.From, blockRoot).Return(nonce, nil).Once() 482 m.State. 483 On("ProcessUnsignedTransaction", context.Background(), txMatchBy, *txArgs.From, nilUint64, true, m.DbTx). 484 Return(&runtime.ExecutionResult{Err: errors.New("failed to process unsigned transaction")}, nil). 485 Once() 486 }, 487 }, 488 { 489 name: "Transaction with all information but reverted to process unsigned transaction", 490 params: []interface{}{ 491 types.TxArgs{ 492 From: state.HexToAddressPtr("0x1"), 493 To: state.HexToAddressPtr("0x2"), 494 Gas: types.ArgUint64Ptr(24000), 495 GasPrice: types.ArgBytesPtr(big.NewInt(1).Bytes()), 496 Value: types.ArgBytesPtr(big.NewInt(2).Bytes()), 497 Data: types.ArgBytesPtr([]byte("data")), 498 }, 499 latest, 500 }, 501 expectedResult: nil, 502 expectedError: types.NewRPCError(types.RevertedErrorCode, "execution reverted"), 503 setupMocks: func(c Config, m *mocksWrapper, testCase *testCase) { 504 nonce := uint64(7) 505 m.DbTx.On("Rollback", context.Background()).Return(nil).Once() 506 m.State.On("BeginStateTransaction", context.Background()).Return(m.DbTx, nil).Once() 507 m.State.On("GetLastL2BlockNumber", context.Background(), m.DbTx).Return(blockNumOne.Uint64(), nil).Once() 508 txArgs := testCase.params[0].(types.TxArgs) 509 txMatchBy := mock.MatchedBy(func(tx *ethTypes.Transaction) bool { 510 gasPrice := big.NewInt(0).SetBytes(*txArgs.GasPrice) 511 value := big.NewInt(0).SetBytes(*txArgs.Value) 512 hasTx := tx != nil 513 gasMatch := tx.Gas() == uint64(*txArgs.Gas) 514 toMatch := tx.To().Hex() == txArgs.To.Hex() 515 gasPriceMatch := tx.GasPrice().Uint64() == gasPrice.Uint64() 516 valueMatch := tx.Value().Uint64() == value.Uint64() 517 dataMatch := hex.EncodeToHex(tx.Data()) == hex.EncodeToHex(*txArgs.Data) 518 nonceMatch := tx.Nonce() == nonce 519 return hasTx && gasMatch && toMatch && gasPriceMatch && valueMatch && dataMatch && nonceMatch 520 }) 521 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumOne, Root: blockRoot}) 522 m.State.On("GetL2BlockByNumber", context.Background(), blockNumOneUint64, m.DbTx).Return(block, nil).Once() 523 m.State.On("GetNonce", context.Background(), *txArgs.From, blockRoot).Return(nonce, nil).Once() 524 m.State. 525 On("ProcessUnsignedTransaction", context.Background(), txMatchBy, *txArgs.From, nilUint64, true, m.DbTx). 526 Return(&runtime.ExecutionResult{Err: runtime.ErrExecutionReverted}, nil). 527 Once() 528 }, 529 }, 530 } 531 532 for _, testCase := range testCases { 533 t.Run(testCase.name, func(t *testing.T) { 534 testCase.setupMocks(s.Config, m, testCase) 535 536 res, err := s.JSONRPCCall("eth_call", testCase.params...) 537 require.NoError(t, err) 538 539 if testCase.expectedResult != nil { 540 require.NotNil(t, res.Result) 541 require.Nil(t, res.Error) 542 543 var s string 544 err = json.Unmarshal(res.Result, &s) 545 require.NoError(t, err) 546 547 result, err := hex.DecodeHex(s) 548 require.NoError(t, err) 549 550 assert.Equal(t, testCase.expectedResult, result) 551 } 552 553 if testCase.expectedError != nil { 554 expectedErr := testCase.expectedError.(*types.RPCError) 555 assert.Equal(t, expectedErr.ErrorCode(), res.Error.Code) 556 assert.Equal(t, expectedErr.Error(), res.Error.Message) 557 } 558 }) 559 } 560 } 561 562 func TestChainID(t *testing.T) { 563 s, _, c := newSequencerMockedServer(t) 564 defer s.Stop() 565 566 chainID, err := c.ChainID(context.Background()) 567 require.NoError(t, err) 568 569 assert.Equal(t, s.ChainID(), chainID.Uint64()) 570 } 571 572 func TestEstimateGas(t *testing.T) { 573 s, m, _ := newSequencerMockedServer(t) 574 defer s.Stop() 575 576 type testCase struct { 577 name string 578 params []interface{} 579 expectedResult *uint64 580 expectedError interface{} 581 setupMocks func(Config, *mocksWrapper, *testCase) 582 } 583 584 testCases := []testCase{ 585 { 586 name: "Transaction with all information", 587 params: []interface{}{ 588 types.TxArgs{ 589 From: state.HexToAddressPtr("0x1"), 590 To: state.HexToAddressPtr("0x2"), 591 Gas: types.ArgUint64Ptr(24000), 592 GasPrice: types.ArgBytesPtr(big.NewInt(1).Bytes()), 593 Value: types.ArgBytesPtr(big.NewInt(2).Bytes()), 594 Data: types.ArgBytesPtr([]byte("data")), 595 }, 596 }, 597 expectedResult: ptrUint64(100), 598 setupMocks: func(c Config, m *mocksWrapper, testCase *testCase) { 599 nonce := uint64(7) 600 txArgs := testCase.params[0].(types.TxArgs) 601 txMatchBy := mock.MatchedBy(func(tx *ethTypes.Transaction) bool { 602 if tx == nil { 603 return false 604 } 605 606 gasPrice := big.NewInt(0).SetBytes(*txArgs.GasPrice) 607 value := big.NewInt(0).SetBytes(*txArgs.Value) 608 609 matchTo := tx.To().Hex() == txArgs.To.Hex() 610 matchGasPrice := tx.GasPrice().Uint64() == gasPrice.Uint64() 611 matchValue := tx.Value().Uint64() == value.Uint64() 612 matchData := hex.EncodeToHex(tx.Data()) == hex.EncodeToHex(*txArgs.Data) 613 matchNonce := tx.Nonce() == nonce 614 return matchTo && matchGasPrice && matchValue && matchData && matchNonce 615 }) 616 617 m.DbTx.On("Commit", context.Background()).Return(nil).Once() 618 m.State.On("BeginStateTransaction", context.Background()).Return(m.DbTx, nil).Once() 619 620 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumTen, Root: blockRoot}) 621 m.State.On("GetLastL2Block", context.Background(), m.DbTx).Return(block, nil).Once() 622 623 m.State. 624 On("GetNonce", context.Background(), *txArgs.From, blockRoot). 625 Return(nonce, nil). 626 Once() 627 m.State. 628 On("EstimateGas", txMatchBy, *txArgs.From, nilUint64, m.DbTx). 629 Return(*testCase.expectedResult, nil, nil). 630 Once() 631 }, 632 }, 633 { 634 name: "Transaction without from and gas", 635 params: []interface{}{ 636 types.TxArgs{ 637 To: state.HexToAddressPtr("0x2"), 638 GasPrice: types.ArgBytesPtr(big.NewInt(0).Bytes()), 639 Value: types.ArgBytesPtr(big.NewInt(2).Bytes()), 640 Data: types.ArgBytesPtr([]byte("data")), 641 }, 642 }, 643 expectedResult: ptrUint64(100), 644 setupMocks: func(c Config, m *mocksWrapper, testCase *testCase) { 645 nonce := uint64(0) 646 txArgs := testCase.params[0].(types.TxArgs) 647 txMatchBy := mock.MatchedBy(func(tx *ethTypes.Transaction) bool { 648 if tx == nil { 649 return false 650 } 651 652 gasPrice := big.NewInt(0).SetBytes(*txArgs.GasPrice) 653 value := big.NewInt(0).SetBytes(*txArgs.Value) 654 matchTo := tx.To().Hex() == txArgs.To.Hex() 655 matchGasPrice := tx.GasPrice().Uint64() == gasPrice.Uint64() 656 matchValue := tx.Value().Uint64() == value.Uint64() 657 matchData := hex.EncodeToHex(tx.Data()) == hex.EncodeToHex(*txArgs.Data) 658 matchNonce := tx.Nonce() == nonce 659 return matchTo && matchGasPrice && matchValue && matchData && matchNonce 660 }) 661 662 m.DbTx.On("Commit", context.Background()).Return(nil).Once() 663 m.State.On("BeginStateTransaction", context.Background()).Return(m.DbTx, nil).Once() 664 665 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumTen, Root: blockRoot}) 666 m.State.On("GetLastL2Block", context.Background(), m.DbTx).Return(block, nil).Once() 667 668 m.State. 669 On("EstimateGas", txMatchBy, common.HexToAddress(DefaultSenderAddress), nilUint64, m.DbTx). 670 Return(*testCase.expectedResult, nil, nil). 671 Once() 672 }, 673 }, 674 } 675 676 for _, testCase := range testCases { 677 t.Run(testCase.name, func(t *testing.T) { 678 tc := testCase 679 tc.setupMocks(s.Config, m, &tc) 680 681 res, err := s.JSONRPCCall("eth_estimateGas", testCase.params...) 682 require.NoError(t, err) 683 684 if testCase.expectedResult != nil { 685 require.NotNil(t, res.Result) 686 require.Nil(t, res.Error) 687 688 var s string 689 err = json.Unmarshal(res.Result, &s) 690 require.NoError(t, err) 691 692 result := hex.DecodeUint64(s) 693 694 assert.Equal(t, *testCase.expectedResult, result) 695 } 696 697 if testCase.expectedError != nil { 698 expectedErr := testCase.expectedError.(*types.RPCError) 699 assert.Equal(t, expectedErr.ErrorCode(), res.Error.Code) 700 assert.Equal(t, expectedErr.Error(), res.Error.Message) 701 } 702 }) 703 } 704 } 705 706 func TestGasPrice(t *testing.T) { 707 s, m, c := newSequencerMockedServer(t) 708 defer s.Stop() 709 710 testCases := []struct { 711 name string 712 gasPrice uint64 713 error error 714 expectedGasPrice uint64 715 }{ 716 {"GasPrice nil", 0, nil, 0}, 717 {"GasPrice with value", 50, nil, 50}, 718 {"failed to get gas price", 50, errors.New("failed to get gas price"), 0}, 719 } 720 721 for _, testCase := range testCases { 722 t.Run(testCase.name, func(t *testing.T) { 723 m.Pool. 724 On("GetGasPrice", context.Background()). 725 Return(testCase.gasPrice, testCase.error). 726 Once() 727 728 gasPrice, err := c.SuggestGasPrice(context.Background()) 729 require.NoError(t, err) 730 assert.Equal(t, testCase.expectedGasPrice, gasPrice.Uint64()) 731 }) 732 } 733 } 734 735 func TestGetBalance(t *testing.T) { 736 s, m, _ := newSequencerMockedServer(t) 737 defer s.Stop() 738 739 type testCase struct { 740 name string 741 balance *big.Int 742 params []interface{} 743 expectedBalance uint64 744 expectedError *types.RPCError 745 setupMocks func(m *mocksWrapper, t *testCase) 746 } 747 748 testCases := []testCase{ 749 { 750 name: "get balance but failed to get latest block number", 751 balance: big.NewInt(1000), 752 params: []interface{}{ 753 addressArg.String(), 754 }, 755 expectedBalance: 0, 756 expectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get the last block number from state"), 757 setupMocks: func(m *mocksWrapper, t *testCase) { 758 m.DbTx. 759 On("Rollback", context.Background()). 760 Return(nil). 761 Once() 762 763 m.State. 764 On("BeginStateTransaction", context.Background()). 765 Return(m.DbTx, nil). 766 Once() 767 768 m.State. 769 On("GetLastL2Block", context.Background(), m.DbTx). 770 Return(nil, errors.New("failed to get last block number")).Once() 771 }, 772 }, 773 { 774 name: "get balance for block nil", 775 params: []interface{}{ 776 addressArg.String(), 777 }, 778 balance: big.NewInt(1000), 779 expectedBalance: 1000, 780 expectedError: nil, 781 setupMocks: func(m *mocksWrapper, t *testCase) { 782 m.DbTx. 783 On("Commit", context.Background()). 784 Return(nil). 785 Once() 786 787 m.State. 788 On("BeginStateTransaction", context.Background()). 789 Return(m.DbTx, nil). 790 Once() 791 792 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumTen, Root: blockRoot}) 793 m.State. 794 On("GetLastL2Block", context.Background(), m.DbTx). 795 Return(block, nil).Once() 796 797 m.State. 798 On("GetBalance", context.Background(), addressArg, blockRoot). 799 Return(t.balance, nil). 800 Once() 801 }, 802 }, 803 { 804 name: "get balance for block by hash with EIP-1898", 805 params: []interface{}{ 806 addressArg.String(), 807 map[string]interface{}{ 808 types.BlockHashKey: blockHash.String(), 809 }, 810 }, 811 balance: big.NewInt(1000), 812 expectedBalance: 1000, 813 expectedError: nil, 814 setupMocks: func(m *mocksWrapper, t *testCase) { 815 m.DbTx. 816 On("Commit", context.Background()). 817 Return(nil). 818 Once() 819 820 m.State. 821 On("BeginStateTransaction", context.Background()). 822 Return(m.DbTx, nil). 823 Once() 824 825 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumTen, Root: blockRoot}) 826 m.State. 827 On("GetL2BlockByHash", context.Background(), blockHash, m.DbTx). 828 Return(block, nil). 829 Once() 830 831 m.State. 832 On("GetBalance", context.Background(), addressArg, blockRoot). 833 Return(t.balance, nil). 834 Once() 835 }, 836 }, 837 { 838 name: "get balance for not found result", 839 params: []interface{}{ 840 addressArg.String(), 841 }, 842 balance: big.NewInt(1000), 843 expectedBalance: 0, 844 expectedError: nil, 845 setupMocks: func(m *mocksWrapper, t *testCase) { 846 m.DbTx. 847 On("Commit", context.Background()). 848 Return(nil). 849 Once() 850 851 m.State. 852 On("BeginStateTransaction", context.Background()). 853 Return(m.DbTx, nil). 854 Once() 855 856 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumTen, Root: blockRoot}) 857 m.State.On("GetLastL2Block", context.Background(), m.DbTx).Return(block, nil).Once() 858 859 m.State. 860 On("GetBalance", context.Background(), addressArg, blockRoot). 861 Return(big.NewInt(0), state.ErrNotFound). 862 Once() 863 }, 864 }, 865 { 866 name: "get balance with state failure", 867 params: []interface{}{ 868 addressArg.String(), 869 }, 870 balance: big.NewInt(1000), 871 expectedBalance: 0, 872 expectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get balance from state"), 873 setupMocks: func(m *mocksWrapper, t *testCase) { 874 m.DbTx. 875 On("Rollback", context.Background()). 876 Return(nil). 877 Once() 878 879 m.State. 880 On("BeginStateTransaction", context.Background()). 881 Return(m.DbTx, nil). 882 Once() 883 884 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumTen, Root: blockRoot}) 885 m.State.On("GetLastL2Block", context.Background(), m.DbTx).Return(block, nil).Once() 886 887 m.State. 888 On("GetBalance", context.Background(), addressArg, blockRoot). 889 Return(nil, errors.New("failed to get balance")). 890 Once() 891 }, 892 }, 893 } 894 895 for _, testCase := range testCases { 896 t.Run(testCase.name, func(t *testing.T) { 897 tc := testCase 898 testCase.setupMocks(m, &tc) 899 900 res, err := s.JSONRPCCall("eth_getBalance", tc.params...) 901 require.NoError(t, err) 902 903 if tc.expectedBalance != 0 { 904 require.NotNil(t, res.Result) 905 require.Nil(t, res.Error) 906 907 var balanceStr string 908 err = json.Unmarshal(res.Result, &balanceStr) 909 require.NoError(t, err) 910 911 balance := new(big.Int) 912 balance.SetString(balanceStr, 0) 913 assert.Equal(t, tc.expectedBalance, balance.Uint64()) 914 } 915 916 if tc.expectedError != nil { 917 assert.Equal(t, tc.expectedError.ErrorCode(), res.Error.Code) 918 assert.Equal(t, tc.expectedError.Error(), res.Error.Message) 919 } 920 }) 921 } 922 } 923 924 func TestGetL2BlockByHash(t *testing.T) { 925 type testCase struct { 926 Name string 927 Hash common.Hash 928 ExpectedResult *ethTypes.Block 929 ExpectedError interface{} 930 SetupMocks func(*mocksWrapper, *testCase) 931 } 932 933 testCases := []testCase{ 934 { 935 Name: "Block not found", 936 Hash: common.HexToHash("0x123"), 937 ExpectedResult: nil, 938 ExpectedError: ethereum.NotFound, 939 SetupMocks: func(m *mocksWrapper, tc *testCase) { 940 m.DbTx. 941 On("Commit", context.Background()). 942 Return(nil). 943 Once() 944 945 m.State. 946 On("BeginStateTransaction", context.Background()). 947 Return(m.DbTx, nil). 948 Once() 949 950 m.State. 951 On("GetL2BlockByHash", context.Background(), tc.Hash, m.DbTx). 952 Return(nil, state.ErrNotFound) 953 }, 954 }, 955 { 956 Name: "Failed get block from state", 957 Hash: common.HexToHash("0x234"), 958 ExpectedResult: nil, 959 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get block by hash from state"), 960 SetupMocks: func(m *mocksWrapper, tc *testCase) { 961 m.DbTx. 962 On("Rollback", context.Background()). 963 Return(nil). 964 Once() 965 966 m.State. 967 On("BeginStateTransaction", context.Background()). 968 Return(m.DbTx, nil). 969 Once() 970 971 m.State. 972 On("GetL2BlockByHash", context.Background(), tc.Hash, m.DbTx). 973 Return(nil, errors.New("failed to get block from state")). 974 Once() 975 }, 976 }, 977 { 978 Name: "get block successfully", 979 Hash: common.HexToHash("0x345"), 980 ExpectedResult: ethTypes.NewBlock( 981 ðTypes.Header{Number: big.NewInt(1), UncleHash: ethTypes.EmptyUncleHash, Root: ethTypes.EmptyRootHash}, 982 []*ethTypes.Transaction{ethTypes.NewTransaction(1, common.Address{}, big.NewInt(1), 1, big.NewInt(1), []byte{})}, 983 nil, 984 []*ethTypes.Receipt{ethTypes.NewReceipt([]byte{}, false, uint64(0))}, 985 &trie.StackTrie{}, 986 ), 987 ExpectedError: nil, 988 SetupMocks: func(m *mocksWrapper, tc *testCase) { 989 block := ethTypes.NewBlock(ethTypes.CopyHeader(tc.ExpectedResult.Header()), tc.ExpectedResult.Transactions(), tc.ExpectedResult.Uncles(), []*ethTypes.Receipt{ethTypes.NewReceipt([]byte{}, false, uint64(0))}, &trie.StackTrie{}) 990 991 m.DbTx. 992 On("Commit", context.Background()). 993 Return(nil). 994 Once() 995 996 m.State. 997 On("BeginStateTransaction", context.Background()). 998 Return(m.DbTx, nil). 999 Once() 1000 1001 m.State. 1002 On("GetL2BlockByHash", context.Background(), tc.Hash, m.DbTx). 1003 Return(block, nil). 1004 Once() 1005 }, 1006 }, 1007 } 1008 1009 s, m, c := newSequencerMockedServer(t) 1010 defer s.Stop() 1011 1012 for _, testCase := range testCases { 1013 t.Run(testCase.Name, func(t *testing.T) { 1014 tc := testCase 1015 testCase.SetupMocks(m, &tc) 1016 1017 result, err := c.BlockByHash(context.Background(), tc.Hash) 1018 1019 if result != nil || tc.ExpectedResult != nil { 1020 assert.Equal(t, tc.ExpectedResult.Number().Uint64(), result.Number().Uint64()) 1021 assert.Equal(t, len(tc.ExpectedResult.Transactions()), len(result.Transactions())) 1022 assert.Equal(t, tc.ExpectedResult.Hash(), result.Hash()) 1023 } 1024 1025 if err != nil || tc.ExpectedError != nil { 1026 if expectedErr, ok := tc.ExpectedError.(*types.RPCError); ok { 1027 rpcErr := err.(rpc.Error) 1028 assert.Equal(t, expectedErr.ErrorCode(), rpcErr.ErrorCode()) 1029 assert.Equal(t, expectedErr.Error(), rpcErr.Error()) 1030 } else { 1031 assert.Equal(t, tc.ExpectedError, err) 1032 } 1033 } 1034 }) 1035 } 1036 } 1037 1038 func TestGetL2BlockByNumber(t *testing.T) { 1039 type testCase struct { 1040 Name string 1041 Number *big.Int 1042 ExpectedResult *ethTypes.Block 1043 ExpectedError interface{} 1044 SetupMocks func(*mocksWrapper, *testCase) 1045 } 1046 1047 testCases := []testCase{ 1048 { 1049 Name: "Block not found", 1050 Number: big.NewInt(123), 1051 ExpectedResult: nil, 1052 ExpectedError: ethereum.NotFound, 1053 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1054 m.DbTx. 1055 On("Commit", context.Background()). 1056 Return(nil). 1057 Once() 1058 1059 m.State. 1060 On("BeginStateTransaction", context.Background()). 1061 Return(m.DbTx, nil). 1062 Once() 1063 1064 m.State. 1065 On("GetL2BlockByNumber", context.Background(), tc.Number.Uint64(), m.DbTx). 1066 Return(nil, state.ErrNotFound) 1067 }, 1068 }, 1069 { 1070 Name: "get specific block successfully", 1071 Number: big.NewInt(345), 1072 ExpectedResult: ethTypes.NewBlock( 1073 ðTypes.Header{Number: big.NewInt(1), UncleHash: ethTypes.EmptyUncleHash, Root: ethTypes.EmptyRootHash}, 1074 []*ethTypes.Transaction{ethTypes.NewTransaction(1, common.Address{}, big.NewInt(1), 1, big.NewInt(1), []byte{})}, 1075 nil, 1076 []*ethTypes.Receipt{ethTypes.NewReceipt([]byte{}, false, uint64(0))}, 1077 &trie.StackTrie{}, 1078 ), 1079 ExpectedError: nil, 1080 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1081 block := ethTypes.NewBlock(ethTypes.CopyHeader(tc.ExpectedResult.Header()), tc.ExpectedResult.Transactions(), 1082 tc.ExpectedResult.Uncles(), []*ethTypes.Receipt{ethTypes.NewReceipt([]byte{}, false, uint64(0))}, &trie.StackTrie{}) 1083 1084 m.DbTx. 1085 On("Commit", context.Background()). 1086 Return(nil). 1087 Once() 1088 1089 m.State. 1090 On("BeginStateTransaction", context.Background()). 1091 Return(m.DbTx, nil). 1092 Once() 1093 1094 m.State. 1095 On("GetL2BlockByNumber", context.Background(), tc.Number.Uint64(), m.DbTx). 1096 Return(block, nil). 1097 Once() 1098 }, 1099 }, 1100 { 1101 Name: "get latest block successfully", 1102 Number: nil, 1103 ExpectedResult: ethTypes.NewBlock( 1104 ðTypes.Header{Number: big.NewInt(2), UncleHash: ethTypes.EmptyUncleHash, Root: ethTypes.EmptyRootHash}, 1105 []*ethTypes.Transaction{ethTypes.NewTransaction(1, common.Address{}, big.NewInt(1), 1, big.NewInt(1), []byte{})}, 1106 nil, 1107 []*ethTypes.Receipt{ethTypes.NewReceipt([]byte{}, false, uint64(0))}, 1108 &trie.StackTrie{}, 1109 ), 1110 ExpectedError: nil, 1111 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1112 m.DbTx. 1113 On("Commit", context.Background()). 1114 Return(nil). 1115 Once() 1116 1117 m.State. 1118 On("BeginStateTransaction", context.Background()). 1119 Return(m.DbTx, nil). 1120 Once() 1121 1122 m.State. 1123 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 1124 Return(tc.ExpectedResult.Number().Uint64(), nil). 1125 Once() 1126 1127 m.State. 1128 On("GetL2BlockByNumber", context.Background(), tc.ExpectedResult.Number().Uint64(), m.DbTx). 1129 Return(tc.ExpectedResult, nil). 1130 Once() 1131 }, 1132 }, 1133 { 1134 Name: "get latest block fails to compute block number", 1135 Number: nil, 1136 ExpectedResult: nil, 1137 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get the last block number from state"), 1138 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1139 m.DbTx. 1140 On("Rollback", context.Background()). 1141 Return(nil). 1142 Once() 1143 1144 m.State. 1145 On("BeginStateTransaction", context.Background()). 1146 Return(m.DbTx, nil). 1147 Once() 1148 1149 m.State. 1150 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 1151 Return(uint64(0), errors.New("failed to get last block number")). 1152 Once() 1153 }, 1154 }, 1155 { 1156 Name: "get latest block fails to load block by number", 1157 Number: nil, 1158 ExpectedResult: nil, 1159 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "couldn't load block from state by number 1"), 1160 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1161 m.DbTx. 1162 On("Rollback", context.Background()). 1163 Return(nil). 1164 Once() 1165 1166 m.State. 1167 On("BeginStateTransaction", context.Background()). 1168 Return(m.DbTx, nil). 1169 Once() 1170 1171 m.State. 1172 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 1173 Return(uint64(1), nil). 1174 Once() 1175 1176 m.State. 1177 On("GetL2BlockByNumber", context.Background(), uint64(1), m.DbTx). 1178 Return(nil, errors.New("failed to load block by number")). 1179 Once() 1180 }, 1181 }, 1182 { 1183 Name: "get pending block successfully", 1184 Number: big.NewInt(-1), 1185 ExpectedResult: ethTypes.NewBlock(ðTypes.Header{Number: big.NewInt(2)}, nil, nil, nil, &trie.StackTrie{}), 1186 ExpectedError: nil, 1187 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1188 lastBlockHeader := ethTypes.CopyHeader(tc.ExpectedResult.Header()) 1189 lastBlockHeader.Number.Sub(lastBlockHeader.Number, big.NewInt(1)) 1190 lastBlock := ethTypes.NewBlock(lastBlockHeader, nil, nil, nil, &trie.StackTrie{}) 1191 1192 expectedResultHeader := ethTypes.CopyHeader(tc.ExpectedResult.Header()) 1193 expectedResultHeader.ParentHash = lastBlock.Hash() 1194 tc.ExpectedResult = ethTypes.NewBlock(expectedResultHeader, nil, nil, nil, &trie.StackTrie{}) 1195 1196 m.DbTx. 1197 On("Commit", context.Background()). 1198 Return(nil). 1199 Once() 1200 1201 m.State. 1202 On("BeginStateTransaction", context.Background()). 1203 Return(m.DbTx, nil). 1204 Once() 1205 1206 m.State. 1207 On("GetLastL2Block", context.Background(), m.DbTx). 1208 Return(lastBlock, nil). 1209 Once() 1210 }, 1211 }, 1212 { 1213 Name: "get pending block fails", 1214 Number: big.NewInt(-1), 1215 ExpectedResult: nil, 1216 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "couldn't load last block from state to compute the pending block"), 1217 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1218 m.DbTx. 1219 On("Rollback", context.Background()). 1220 Return(nil). 1221 Once() 1222 1223 m.State. 1224 On("BeginStateTransaction", context.Background()). 1225 Return(m.DbTx, nil). 1226 Once() 1227 1228 m.State. 1229 On("GetLastL2Block", context.Background(), m.DbTx). 1230 Return(nil, errors.New("failed to load last block")). 1231 Once() 1232 }, 1233 }, 1234 } 1235 1236 s, m, c := newSequencerMockedServer(t) 1237 defer s.Stop() 1238 1239 for _, testCase := range testCases { 1240 t.Run(testCase.Name, func(t *testing.T) { 1241 tc := testCase 1242 testCase.SetupMocks(m, &tc) 1243 1244 result, err := c.BlockByNumber(context.Background(), tc.Number) 1245 1246 if result != nil || tc.ExpectedResult != nil { 1247 expectedResultJSON, _ := json.Marshal(tc.ExpectedResult.Header()) 1248 resultJSON, _ := json.Marshal(result.Header()) 1249 1250 expectedResultJSONStr := string(expectedResultJSON) 1251 resultJSONStr := string(resultJSON) 1252 1253 assert.JSONEq(t, expectedResultJSONStr, resultJSONStr) 1254 assert.Equal(t, tc.ExpectedResult.Number().Uint64(), result.Number().Uint64()) 1255 assert.Equal(t, len(tc.ExpectedResult.Transactions()), len(result.Transactions())) 1256 assert.Equal(t, tc.ExpectedResult.Hash(), result.Hash()) 1257 } 1258 1259 if err != nil || tc.ExpectedError != nil { 1260 if expectedErr, ok := tc.ExpectedError.(*types.RPCError); ok { 1261 rpcErr := err.(rpc.Error) 1262 assert.Equal(t, expectedErr.ErrorCode(), rpcErr.ErrorCode()) 1263 assert.Equal(t, expectedErr.Error(), rpcErr.Error()) 1264 } else { 1265 assert.Equal(t, tc.ExpectedError, err) 1266 } 1267 } 1268 }) 1269 } 1270 } 1271 1272 func TestGetUncleByBlockHashAndIndex(t *testing.T) { 1273 s, _, _ := newSequencerMockedServer(t) 1274 defer s.Stop() 1275 1276 res, err := s.JSONRPCCall("eth_getUncleByBlockHashAndIndex", common.HexToHash("0x123").Hex(), "0x1") 1277 require.NoError(t, err) 1278 1279 assert.Equal(t, float64(1), res.ID) 1280 assert.Equal(t, "2.0", res.JSONRPC) 1281 assert.Nil(t, res.Error) 1282 1283 var result interface{} 1284 err = json.Unmarshal(res.Result, &result) 1285 require.NoError(t, err) 1286 1287 assert.Nil(t, result) 1288 } 1289 1290 func TestGetUncleByBlockNumberAndIndex(t *testing.T) { 1291 s, _, _ := newSequencerMockedServer(t) 1292 defer s.Stop() 1293 1294 res, err := s.JSONRPCCall("eth_getUncleByBlockNumberAndIndex", "0x123", "0x1") 1295 require.NoError(t, err) 1296 1297 assert.Equal(t, float64(1), res.ID) 1298 assert.Equal(t, "2.0", res.JSONRPC) 1299 assert.Nil(t, res.Error) 1300 1301 var result interface{} 1302 err = json.Unmarshal(res.Result, &result) 1303 require.NoError(t, err) 1304 1305 assert.Nil(t, result) 1306 } 1307 1308 func TestGetUncleCountByBlockHash(t *testing.T) { 1309 s, _, _ := newSequencerMockedServer(t) 1310 defer s.Stop() 1311 1312 res, err := s.JSONRPCCall("eth_getUncleCountByBlockHash", common.HexToHash("0x123")) 1313 require.NoError(t, err) 1314 1315 assert.Equal(t, float64(1), res.ID) 1316 assert.Equal(t, "2.0", res.JSONRPC) 1317 assert.Nil(t, res.Error) 1318 1319 var result types.ArgUint64 1320 err = json.Unmarshal(res.Result, &result) 1321 require.NoError(t, err) 1322 1323 assert.Equal(t, uint64(0), uint64(result)) 1324 } 1325 1326 func TestGetUncleCountByBlockNumber(t *testing.T) { 1327 s, _, _ := newSequencerMockedServer(t) 1328 defer s.Stop() 1329 1330 res, err := s.JSONRPCCall("eth_getUncleCountByBlockNumber", "0x123") 1331 require.NoError(t, err) 1332 1333 assert.Equal(t, float64(1), res.ID) 1334 assert.Equal(t, "2.0", res.JSONRPC) 1335 assert.Nil(t, res.Error) 1336 1337 var result types.ArgUint64 1338 err = json.Unmarshal(res.Result, &result) 1339 require.NoError(t, err) 1340 1341 assert.Equal(t, uint64(0), uint64(result)) 1342 } 1343 1344 func TestGetCode(t *testing.T) { 1345 s, m, _ := newSequencerMockedServer(t) 1346 defer s.Stop() 1347 1348 type testCase struct { 1349 Name string 1350 Params []interface{} 1351 ExpectedResult []byte 1352 ExpectedError interface{} 1353 1354 SetupMocks func(m *mocksWrapper, tc *testCase) 1355 } 1356 1357 testCases := []testCase{ 1358 { 1359 Name: "failed to identify the block", 1360 Params: []interface{}{ 1361 addressArg.String(), 1362 }, 1363 ExpectedResult: nil, 1364 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get the last block number from state"), 1365 1366 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1367 m.DbTx. 1368 On("Rollback", context.Background()). 1369 Return(nil). 1370 Once() 1371 1372 m.State. 1373 On("BeginStateTransaction", context.Background()). 1374 Return(m.DbTx, nil). 1375 Once() 1376 1377 m.State. 1378 On("GetLastL2Block", context.Background(), m.DbTx). 1379 Return(nil, errors.New("failed to get last block number")). 1380 Once() 1381 }, 1382 }, 1383 { 1384 Name: "failed to get code", 1385 Params: []interface{}{ 1386 addressArg.String(), 1387 map[string]interface{}{types.BlockNumberKey: hex.EncodeBig(blockNumOne)}, 1388 }, 1389 ExpectedResult: nil, 1390 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get code"), 1391 1392 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1393 m.DbTx. 1394 On("Rollback", context.Background()). 1395 Return(nil). 1396 Once() 1397 1398 m.State. 1399 On("BeginStateTransaction", context.Background()). 1400 Return(m.DbTx, nil). 1401 Once() 1402 1403 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumOne, Root: blockRoot}) 1404 m.State.On("GetL2BlockByNumber", context.Background(), blockNumOne.Uint64(), m.DbTx).Return(block, nil).Once() 1405 1406 m.State. 1407 On("GetCode", context.Background(), addressArg, blockRoot). 1408 Return(nil, errors.New("failed to get code")). 1409 Once() 1410 }, 1411 }, 1412 { 1413 Name: "code not found", 1414 Params: []interface{}{ 1415 addressArg.String(), 1416 map[string]interface{}{types.BlockNumberKey: hex.EncodeBig(blockNumOne)}, 1417 }, 1418 ExpectedResult: []byte{}, 1419 ExpectedError: nil, 1420 1421 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1422 m.DbTx. 1423 On("Commit", context.Background()). 1424 Return(nil). 1425 Once() 1426 1427 m.State. 1428 On("BeginStateTransaction", context.Background()). 1429 Return(m.DbTx, nil). 1430 Once() 1431 1432 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumOne, Root: blockRoot}) 1433 m.State.On("GetL2BlockByNumber", context.Background(), blockNumOne.Uint64(), m.DbTx).Return(block, nil).Once() 1434 1435 m.State. 1436 On("GetCode", context.Background(), addressArg, blockRoot). 1437 Return(nil, state.ErrNotFound). 1438 Once() 1439 }, 1440 }, 1441 { 1442 Name: "get code successfully", 1443 Params: []interface{}{ 1444 addressArg.String(), 1445 map[string]interface{}{types.BlockNumberKey: hex.EncodeBig(blockNumOne)}, 1446 }, 1447 ExpectedResult: []byte{1, 2, 3}, 1448 ExpectedError: nil, 1449 1450 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1451 m.DbTx. 1452 On("Commit", context.Background()). 1453 Return(nil). 1454 Once() 1455 1456 m.State. 1457 On("BeginStateTransaction", context.Background()). 1458 Return(m.DbTx, nil). 1459 Once() 1460 1461 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumOne, Root: blockRoot}) 1462 m.State.On("GetL2BlockByNumber", context.Background(), blockNumOne.Uint64(), m.DbTx).Return(block, nil).Once() 1463 1464 m.State. 1465 On("GetCode", context.Background(), addressArg, blockRoot). 1466 Return(tc.ExpectedResult, nil). 1467 Once() 1468 }, 1469 }, 1470 { 1471 Name: "get code successfully by block hash with EIP-1898", 1472 Params: []interface{}{ 1473 addressArg.String(), 1474 map[string]interface{}{types.BlockHashKey: blockHash.String()}, 1475 }, 1476 ExpectedResult: []byte{1, 2, 3}, 1477 ExpectedError: nil, 1478 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1479 m.DbTx. 1480 On("Commit", context.Background()). 1481 Return(nil). 1482 Once() 1483 1484 m.State. 1485 On("BeginStateTransaction", context.Background()). 1486 Return(m.DbTx, nil). 1487 Once() 1488 1489 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumTen, Root: blockRoot}) 1490 m.State. 1491 On("GetL2BlockByHash", context.Background(), blockHash, m.DbTx). 1492 Return(block, nil). 1493 Once() 1494 1495 m.State. 1496 On("GetCode", context.Background(), addressArg, blockRoot). 1497 Return(tc.ExpectedResult, nil). 1498 Once() 1499 }, 1500 }, 1501 } 1502 1503 for _, testCase := range testCases { 1504 t.Run(testCase.Name, func(t *testing.T) { 1505 tc := testCase 1506 tc.SetupMocks(m, &tc) 1507 1508 res, err := s.JSONRPCCall("eth_getCode", tc.Params...) 1509 require.NoError(t, err) 1510 1511 if tc.ExpectedResult != nil { 1512 require.NotNil(t, res.Result) 1513 require.Nil(t, res.Error) 1514 1515 var codeStr string 1516 err = json.Unmarshal(res.Result, &codeStr) 1517 require.NoError(t, err) 1518 1519 code, err := hex.DecodeString(codeStr[2:]) 1520 require.NoError(t, err) 1521 assert.Equal(t, tc.ExpectedResult, code) 1522 } 1523 1524 if tc.ExpectedError != nil { 1525 if expectedErr, ok := tc.ExpectedError.(*types.RPCError); ok { 1526 assert.Equal(t, expectedErr.ErrorCode(), res.Error.Code) 1527 assert.Equal(t, expectedErr.Error(), res.Error.Message) 1528 } else { 1529 assert.Equal(t, tc.ExpectedError, err) 1530 } 1531 } 1532 }) 1533 } 1534 } 1535 1536 func TestGetStorageAt(t *testing.T) { 1537 s, m, _ := newSequencerMockedServer(t) 1538 defer s.Stop() 1539 1540 type testCase struct { 1541 Name string 1542 Params []interface{} 1543 ExpectedResult []byte 1544 ExpectedError *types.RPCError 1545 1546 SetupMocks func(m *mocksWrapper, tc *testCase) 1547 } 1548 1549 testCases := []testCase{ 1550 { 1551 Name: "failed to identify the block", 1552 Params: []interface{}{ 1553 addressArg.String(), 1554 keyArg.String(), 1555 }, 1556 ExpectedResult: nil, 1557 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get the last block number from state"), 1558 1559 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1560 m.DbTx. 1561 On("Rollback", context.Background()). 1562 Return(nil). 1563 Once() 1564 1565 m.State. 1566 On("BeginStateTransaction", context.Background()). 1567 Return(m.DbTx, nil). 1568 Once() 1569 1570 m.State. 1571 On("GetLastL2Block", context.Background(), m.DbTx). 1572 Return(nil, errors.New("failed to get last block number")). 1573 Once() 1574 }, 1575 }, 1576 { 1577 Name: "failed to get storage at", 1578 Params: []interface{}{ 1579 addressArg.String(), 1580 keyArg.String(), 1581 map[string]interface{}{ 1582 types.BlockNumberKey: hex.EncodeBig(blockNumOne), 1583 }, 1584 }, 1585 ExpectedResult: nil, 1586 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get storage value from state"), 1587 1588 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1589 m.DbTx. 1590 On("Rollback", context.Background()). 1591 Return(nil). 1592 Once() 1593 1594 m.State. 1595 On("BeginStateTransaction", context.Background()). 1596 Return(m.DbTx, nil). 1597 Once() 1598 1599 blockNumber := big.NewInt(1) 1600 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumber, Root: blockRoot}) 1601 m.State.On("GetL2BlockByNumber", context.Background(), blockNumber.Uint64(), m.DbTx).Return(block, nil).Once() 1602 1603 m.State. 1604 On("GetStorageAt", context.Background(), addressArg, keyArg.Big(), blockRoot). 1605 Return(nil, errors.New("failed to get storage at")). 1606 Once() 1607 }, 1608 }, 1609 { 1610 Name: "code not found", 1611 Params: []interface{}{ 1612 addressArg.String(), 1613 keyArg.String(), 1614 map[string]interface{}{ 1615 types.BlockNumberKey: hex.EncodeBig(blockNumOne), 1616 }, 1617 }, 1618 ExpectedResult: common.Hash{}.Bytes(), 1619 ExpectedError: nil, 1620 1621 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1622 m.DbTx. 1623 On("Commit", context.Background()). 1624 Return(nil). 1625 Once() 1626 1627 m.State. 1628 On("BeginStateTransaction", context.Background()). 1629 Return(m.DbTx, nil). 1630 Once() 1631 1632 blockNumber := big.NewInt(1) 1633 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumber, Root: blockRoot}) 1634 m.State.On("GetL2BlockByNumber", context.Background(), blockNumber.Uint64(), m.DbTx).Return(block, nil).Once() 1635 1636 m.State. 1637 On("GetStorageAt", context.Background(), addressArg, keyArg.Big(), blockRoot). 1638 Return(nil, state.ErrNotFound). 1639 Once() 1640 }, 1641 }, 1642 { 1643 Name: "get code successfully", 1644 Params: []interface{}{ 1645 addressArg.String(), 1646 keyArg.String(), 1647 map[string]interface{}{ 1648 types.BlockNumberKey: hex.EncodeBig(blockNumOne), 1649 }, 1650 }, 1651 ExpectedResult: common.BigToHash(big.NewInt(123)).Bytes(), 1652 ExpectedError: nil, 1653 1654 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1655 m.DbTx. 1656 On("Commit", context.Background()). 1657 Return(nil). 1658 Once() 1659 1660 m.State. 1661 On("BeginStateTransaction", context.Background()). 1662 Return(m.DbTx, nil). 1663 Once() 1664 1665 blockNumber := big.NewInt(1) 1666 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumber, Root: blockRoot}) 1667 m.State.On("GetL2BlockByNumber", context.Background(), blockNumber.Uint64(), m.DbTx).Return(block, nil).Once() 1668 1669 m.State. 1670 On("GetStorageAt", context.Background(), addressArg, keyArg.Big(), blockRoot). 1671 Return(big.NewInt(123), nil). 1672 Once() 1673 }, 1674 }, 1675 { 1676 Name: "get code by block hash successfully with EIP-1898", 1677 Params: []interface{}{ 1678 addressArg.String(), 1679 keyArg.String(), 1680 map[string]interface{}{ 1681 types.BlockHashKey: blockHash.String(), 1682 }, 1683 }, 1684 ExpectedResult: common.BigToHash(big.NewInt(123)).Bytes(), 1685 ExpectedError: nil, 1686 1687 SetupMocks: func(m *mocksWrapper, tc *testCase) { 1688 m.DbTx. 1689 On("Commit", context.Background()). 1690 Return(nil). 1691 Once() 1692 1693 m.State. 1694 On("BeginStateTransaction", context.Background()). 1695 Return(m.DbTx, nil). 1696 Once() 1697 1698 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumTen, Root: blockRoot}) 1699 m.State. 1700 On("GetL2BlockByHash", context.Background(), blockHash, m.DbTx). 1701 Return(block, nil). 1702 Once() 1703 1704 m.State. 1705 On("GetStorageAt", context.Background(), addressArg, keyArg.Big(), blockRoot). 1706 Return(big.NewInt(123), nil). 1707 Once() 1708 }, 1709 }, 1710 } 1711 1712 for _, testCase := range testCases { 1713 t.Run(testCase.Name, func(t *testing.T) { 1714 tc := testCase 1715 tc.SetupMocks(m, &tc) 1716 res, err := s.JSONRPCCall("eth_getStorageAt", tc.Params...) 1717 require.NoError(t, err) 1718 if tc.ExpectedResult != nil { 1719 require.NotNil(t, res.Result) 1720 require.Nil(t, res.Error) 1721 1722 var storage common.Hash 1723 err = json.Unmarshal(res.Result, &storage) 1724 require.NoError(t, err) 1725 assert.Equal(t, tc.ExpectedResult, storage.Bytes()) 1726 } 1727 1728 if tc.ExpectedError != nil { 1729 assert.Equal(t, tc.ExpectedError.ErrorCode(), res.Error.Code) 1730 assert.Equal(t, tc.ExpectedError.Error(), res.Error.Message) 1731 } 1732 }) 1733 } 1734 } 1735 1736 func TestGetCompilers(t *testing.T) { 1737 s, _, _ := newSequencerMockedServer(t) 1738 defer s.Stop() 1739 1740 res, err := s.JSONRPCCall("eth_getCompilers") 1741 require.NoError(t, err) 1742 1743 assert.Equal(t, float64(1), res.ID) 1744 assert.Equal(t, "2.0", res.JSONRPC) 1745 assert.Nil(t, res.Error) 1746 1747 var result []interface{} 1748 err = json.Unmarshal(res.Result, &result) 1749 require.NoError(t, err) 1750 1751 assert.Equal(t, 0, len(result)) 1752 } 1753 1754 func TestSyncing(t *testing.T) { 1755 s, m, c := newSequencerMockedServer(t) 1756 defer s.Stop() 1757 1758 type testCase struct { 1759 Name string 1760 ExpectedResult *ethereum.SyncProgress 1761 ExpectedError types.Error 1762 SetupMocks func(m *mocksWrapper, tc testCase) 1763 } 1764 1765 testCases := []testCase{ 1766 { 1767 Name: "failed to get last l2 block number", 1768 ExpectedResult: nil, 1769 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get last block number from state"), 1770 SetupMocks: func(m *mocksWrapper, tc testCase) { 1771 m.DbTx. 1772 On("Rollback", context.Background()). 1773 Return(nil). 1774 Once() 1775 1776 m.State. 1777 On("BeginStateTransaction", context.Background()). 1778 Return(m.DbTx, nil). 1779 Once() 1780 1781 m.State. 1782 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 1783 Return(uint64(0), errors.New("failed to get last l2 block number from state")). 1784 Once() 1785 }, 1786 }, 1787 { 1788 Name: "failed to get syncing information", 1789 ExpectedResult: nil, 1790 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get syncing info from state"), 1791 SetupMocks: func(m *mocksWrapper, tc testCase) { 1792 m.DbTx. 1793 On("Rollback", context.Background()). 1794 Return(nil). 1795 Once() 1796 1797 m.State. 1798 On("BeginStateTransaction", context.Background()). 1799 Return(m.DbTx, nil). 1800 Once() 1801 1802 m.State. 1803 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 1804 Return(uint64(10), nil). 1805 Once() 1806 1807 m.State. 1808 On("GetSyncingInfo", context.Background(), m.DbTx). 1809 Return(state.SyncingInfo{}, errors.New("failed to get syncing info from state")). 1810 Once() 1811 }, 1812 }, 1813 { 1814 Name: "get syncing information successfully while syncing", 1815 ExpectedResult: ðereum.SyncProgress{StartingBlock: 1, CurrentBlock: 2, HighestBlock: 3}, 1816 ExpectedError: nil, 1817 SetupMocks: func(m *mocksWrapper, tc testCase) { 1818 m.DbTx. 1819 On("Commit", context.Background()). 1820 Return(nil). 1821 Once() 1822 1823 m.State. 1824 On("BeginStateTransaction", context.Background()). 1825 Return(m.DbTx, nil). 1826 Once() 1827 1828 m.State. 1829 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 1830 Return(uint64(10), nil). 1831 Once() 1832 1833 m.State. 1834 On("GetSyncingInfo", context.Background(), m.DbTx). 1835 Return(state.SyncingInfo{InitialSyncingBlock: 1, CurrentBlockNumber: 2, LastBlockNumberSeen: 3, LastBlockNumberConsolidated: 3}, nil). 1836 Once() 1837 }, 1838 }, 1839 { 1840 Name: "get syncing information successfully when synced", 1841 ExpectedResult: nil, 1842 ExpectedError: nil, 1843 SetupMocks: func(m *mocksWrapper, tc testCase) { 1844 m.DbTx. 1845 On("Commit", context.Background()). 1846 Return(nil). 1847 Once() 1848 1849 m.State. 1850 On("BeginStateTransaction", context.Background()). 1851 Return(m.DbTx, nil). 1852 Once() 1853 1854 m.State. 1855 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 1856 Return(uint64(10), nil). 1857 Once() 1858 1859 m.State. 1860 On("GetSyncingInfo", context.Background(), m.DbTx). 1861 Return(state.SyncingInfo{InitialSyncingBlock: 1, CurrentBlockNumber: 1, LastBlockNumberSeen: 1, LastBlockNumberConsolidated: 1}, nil). 1862 Once() 1863 }, 1864 }, 1865 } 1866 1867 for _, testCase := range testCases { 1868 t.Run(testCase.Name, func(t *testing.T) { 1869 testCase.SetupMocks(m, testCase) 1870 result, err := c.SyncProgress(context.Background()) 1871 1872 if result != nil || testCase.ExpectedResult != nil { 1873 assert.Equal(t, testCase.ExpectedResult.StartingBlock, result.StartingBlock) 1874 assert.Equal(t, testCase.ExpectedResult.CurrentBlock, result.CurrentBlock) 1875 assert.Equal(t, testCase.ExpectedResult.HighestBlock, result.HighestBlock) 1876 } 1877 1878 if err != nil || testCase.ExpectedError != nil { 1879 if expectedErr, ok := testCase.ExpectedError.(*types.RPCError); ok { 1880 rpcErr := err.(rpc.Error) 1881 assert.Equal(t, expectedErr.ErrorCode(), rpcErr.ErrorCode()) 1882 assert.Equal(t, expectedErr.Error(), rpcErr.Error()) 1883 } else { 1884 assert.Equal(t, testCase.ExpectedError, err) 1885 } 1886 } 1887 }) 1888 } 1889 } 1890 1891 func TestGetTransactionL2onByBlockHashAndIndex(t *testing.T) { 1892 s, m, c := newSequencerMockedServer(t) 1893 defer s.Stop() 1894 1895 type testCase struct { 1896 Name string 1897 Hash common.Hash 1898 Index uint 1899 1900 ExpectedResult *ethTypes.Transaction 1901 ExpectedError interface{} 1902 SetupMocks func(m *mocksWrapper, tc testCase) 1903 } 1904 1905 testCases := []testCase{ 1906 { 1907 Name: "Get Tx Successfully", 1908 Hash: common.HexToHash("0x999"), 1909 Index: uint(1), 1910 ExpectedResult: ethTypes.NewTransaction(1, common.HexToAddress("0x111"), big.NewInt(2), 3, big.NewInt(4), []byte{5, 6, 7, 8}), 1911 ExpectedError: nil, 1912 SetupMocks: func(m *mocksWrapper, tc testCase) { 1913 tx := tc.ExpectedResult 1914 m.DbTx. 1915 On("Commit", context.Background()). 1916 Return(nil). 1917 Once() 1918 1919 m.State. 1920 On("BeginStateTransaction", context.Background()). 1921 Return(m.DbTx, nil). 1922 Once() 1923 1924 m.State. 1925 On("GetTransactionByL2BlockHashAndIndex", context.Background(), tc.Hash, uint64(tc.Index), m.DbTx). 1926 Return(tx, nil). 1927 Once() 1928 1929 receipt := ethTypes.NewReceipt([]byte{}, false, 0) 1930 receipt.BlockHash = common.Hash{} 1931 receipt.BlockNumber = big.NewInt(1) 1932 receipt.TransactionIndex = tc.Index 1933 1934 m.State. 1935 On("GetTransactionReceipt", context.Background(), tx.Hash(), m.DbTx). 1936 Return(receipt, nil). 1937 Once() 1938 }, 1939 }, 1940 { 1941 Name: "Tx not found", 1942 Hash: common.HexToHash("0x999"), 1943 Index: uint(1), 1944 ExpectedResult: nil, 1945 ExpectedError: ethereum.NotFound, 1946 SetupMocks: func(m *mocksWrapper, tc testCase) { 1947 m.DbTx. 1948 On("Commit", context.Background()). 1949 Return(nil). 1950 Once() 1951 1952 m.State. 1953 On("BeginStateTransaction", context.Background()). 1954 Return(m.DbTx, nil). 1955 Once() 1956 1957 m.State. 1958 On("GetTransactionByL2BlockHashAndIndex", context.Background(), tc.Hash, uint64(tc.Index), m.DbTx). 1959 Return(nil, state.ErrNotFound). 1960 Once() 1961 }, 1962 }, 1963 { 1964 Name: "Get Tx fail to get tx from state", 1965 Hash: common.HexToHash("0x999"), 1966 Index: uint(1), 1967 ExpectedResult: nil, 1968 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get transaction"), 1969 SetupMocks: func(m *mocksWrapper, tc testCase) { 1970 m.DbTx. 1971 On("Rollback", context.Background()). 1972 Return(nil). 1973 Once() 1974 1975 m.State. 1976 On("BeginStateTransaction", context.Background()). 1977 Return(m.DbTx, nil). 1978 Once() 1979 1980 m.State. 1981 On("GetTransactionByL2BlockHashAndIndex", context.Background(), tc.Hash, uint64(tc.Index), m.DbTx). 1982 Return(nil, errors.New("failed to get transaction by block and index from state")). 1983 Once() 1984 }, 1985 }, 1986 { 1987 Name: "Tx found but receipt not found", 1988 Hash: common.HexToHash("0x999"), 1989 Index: uint(1), 1990 ExpectedResult: nil, 1991 ExpectedError: ethereum.NotFound, 1992 SetupMocks: func(m *mocksWrapper, tc testCase) { 1993 tx := ethTypes.NewTransaction(0, common.Address{}, big.NewInt(0), 0, big.NewInt(0), []byte{}) 1994 m.DbTx. 1995 On("Commit", context.Background()). 1996 Return(nil). 1997 Once() 1998 1999 m.State. 2000 On("BeginStateTransaction", context.Background()). 2001 Return(m.DbTx, nil). 2002 Once() 2003 2004 m.State. 2005 On("GetTransactionByL2BlockHashAndIndex", context.Background(), tc.Hash, uint64(tc.Index), m.DbTx). 2006 Return(tx, nil). 2007 Once() 2008 2009 m.State. 2010 On("GetTransactionReceipt", context.Background(), tx.Hash(), m.DbTx). 2011 Return(nil, state.ErrNotFound). 2012 Once() 2013 }, 2014 }, 2015 { 2016 Name: "Get Tx fail to get tx receipt from state", 2017 Hash: common.HexToHash("0x999"), 2018 Index: uint(1), 2019 ExpectedResult: nil, 2020 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get transaction receipt"), 2021 SetupMocks: func(m *mocksWrapper, tc testCase) { 2022 tx := ethTypes.NewTransaction(0, common.Address{}, big.NewInt(0), 0, big.NewInt(0), []byte{}) 2023 m.DbTx. 2024 On("Rollback", context.Background()). 2025 Return(nil). 2026 Once() 2027 2028 m.State. 2029 On("BeginStateTransaction", context.Background()). 2030 Return(m.DbTx, nil). 2031 Once() 2032 2033 m.State. 2034 On("GetTransactionByL2BlockHashAndIndex", context.Background(), tc.Hash, uint64(tc.Index), m.DbTx). 2035 Return(tx, nil). 2036 Once() 2037 2038 m.State. 2039 On("GetTransactionReceipt", context.Background(), tx.Hash(), m.DbTx). 2040 Return(nil, errors.New("failed to get transaction receipt from state")). 2041 Once() 2042 }, 2043 }, 2044 } 2045 2046 for _, testCase := range testCases { 2047 t.Run(testCase.Name, func(t *testing.T) { 2048 tc := testCase 2049 tc.SetupMocks(m, tc) 2050 2051 result, err := c.TransactionInBlock(context.Background(), tc.Hash, tc.Index) 2052 2053 if result != nil || testCase.ExpectedResult != nil { 2054 assert.Equal(t, testCase.ExpectedResult.Hash(), result.Hash()) 2055 } 2056 2057 if err != nil || testCase.ExpectedError != nil { 2058 if expectedErr, ok := testCase.ExpectedError.(*types.RPCError); ok { 2059 rpcErr := err.(rpc.Error) 2060 assert.Equal(t, expectedErr.ErrorCode(), rpcErr.ErrorCode()) 2061 assert.Equal(t, expectedErr.Error(), rpcErr.Error()) 2062 } else { 2063 assert.Equal(t, testCase.ExpectedError, err) 2064 } 2065 } 2066 }) 2067 } 2068 } 2069 2070 func TestGetTransactionByBlockNumberAndIndex(t *testing.T) { 2071 s, m, _ := newSequencerMockedServer(t) 2072 defer s.Stop() 2073 2074 type testCase struct { 2075 Name string 2076 BlockNumber string 2077 Index uint 2078 2079 ExpectedResult *ethTypes.Transaction 2080 ExpectedError types.Error 2081 SetupMocks func(m *mocksWrapper, tc testCase) 2082 } 2083 2084 testCases := []testCase{ 2085 { 2086 Name: "Get Tx Successfully", 2087 BlockNumber: "0x1", 2088 Index: uint(0), 2089 ExpectedResult: ethTypes.NewTransaction(1, common.HexToAddress("0x111"), big.NewInt(2), 3, big.NewInt(4), []byte{5, 6, 7, 8}), 2090 ExpectedError: nil, 2091 SetupMocks: func(m *mocksWrapper, tc testCase) { 2092 tx := tc.ExpectedResult 2093 blockNumber, _ := encoding.DecodeUint64orHex(&tc.BlockNumber) 2094 m.DbTx. 2095 On("Commit", context.Background()). 2096 Return(nil). 2097 Once() 2098 2099 m.State. 2100 On("BeginStateTransaction", context.Background()). 2101 Return(m.DbTx, nil). 2102 Once() 2103 2104 m.State. 2105 On("GetTransactionByL2BlockNumberAndIndex", context.Background(), blockNumber, uint64(tc.Index), m.DbTx). 2106 Return(tx, nil). 2107 Once() 2108 2109 receipt := ethTypes.NewReceipt([]byte{}, false, 0) 2110 receipt.BlockHash = common.Hash{} 2111 receipt.BlockNumber = big.NewInt(1) 2112 receipt.TransactionIndex = tc.Index 2113 m.State. 2114 On("GetTransactionReceipt", context.Background(), tx.Hash(), m.DbTx). 2115 Return(receipt, nil). 2116 Once() 2117 }, 2118 }, 2119 { 2120 Name: "failed to identify block number", 2121 BlockNumber: latest, 2122 Index: uint(0), 2123 ExpectedResult: nil, 2124 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get the last block number from state"), 2125 SetupMocks: func(m *mocksWrapper, tc testCase) { 2126 m.DbTx. 2127 On("Rollback", context.Background()). 2128 Return(nil). 2129 Once() 2130 2131 m.State. 2132 On("BeginStateTransaction", context.Background()). 2133 Return(m.DbTx, nil). 2134 Once() 2135 2136 m.State. 2137 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 2138 Return(uint64(0), errors.New("failed to get last block number")). 2139 Once() 2140 }, 2141 }, 2142 { 2143 Name: "Tx not found", 2144 BlockNumber: "0x1", 2145 Index: uint(0), 2146 ExpectedResult: nil, 2147 ExpectedError: nil, 2148 SetupMocks: func(m *mocksWrapper, tc testCase) { 2149 blockNumber, _ := encoding.DecodeUint64orHex(&tc.BlockNumber) 2150 m.DbTx. 2151 On("Commit", context.Background()). 2152 Return(nil). 2153 Once() 2154 2155 m.State. 2156 On("BeginStateTransaction", context.Background()). 2157 Return(m.DbTx, nil). 2158 Once() 2159 2160 m.State. 2161 On("GetTransactionByL2BlockNumberAndIndex", context.Background(), blockNumber, uint64(tc.Index), m.DbTx). 2162 Return(nil, state.ErrNotFound). 2163 Once() 2164 }, 2165 }, 2166 { 2167 Name: "Get Tx fail to get tx from state", 2168 BlockNumber: "0x1", 2169 Index: uint(0), 2170 ExpectedResult: nil, 2171 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get transaction"), 2172 SetupMocks: func(m *mocksWrapper, tc testCase) { 2173 blockNumber, _ := encoding.DecodeUint64orHex(&tc.BlockNumber) 2174 m.DbTx. 2175 On("Rollback", context.Background()). 2176 Return(nil). 2177 Once() 2178 2179 m.State. 2180 On("BeginStateTransaction", context.Background()). 2181 Return(m.DbTx, nil). 2182 Once() 2183 2184 m.State. 2185 On("GetTransactionByL2BlockNumberAndIndex", context.Background(), blockNumber, uint64(tc.Index), m.DbTx). 2186 Return(nil, errors.New("failed to get transaction by block and index from state")). 2187 Once() 2188 }, 2189 }, 2190 { 2191 Name: "Tx found but receipt not found", 2192 BlockNumber: "0x1", 2193 Index: uint(0), 2194 ExpectedResult: nil, 2195 ExpectedError: nil, 2196 SetupMocks: func(m *mocksWrapper, tc testCase) { 2197 tx := ethTypes.NewTransaction(0, common.Address{}, big.NewInt(0), 0, big.NewInt(0), []byte{}) 2198 2199 blockNumber, _ := encoding.DecodeUint64orHex(&tc.BlockNumber) 2200 m.DbTx. 2201 On("Commit", context.Background()). 2202 Return(nil). 2203 Once() 2204 2205 m.State. 2206 On("BeginStateTransaction", context.Background()). 2207 Return(m.DbTx, nil). 2208 Once() 2209 2210 m.State. 2211 On("GetTransactionByL2BlockNumberAndIndex", context.Background(), blockNumber, uint64(tc.Index), m.DbTx). 2212 Return(tx, nil). 2213 Once() 2214 2215 m.State. 2216 On("GetTransactionReceipt", context.Background(), tx.Hash(), m.DbTx). 2217 Return(nil, state.ErrNotFound). 2218 Once() 2219 }, 2220 }, 2221 { 2222 Name: "Get Tx fail to get tx receipt from state", 2223 BlockNumber: "0x1", 2224 Index: uint(0), 2225 ExpectedResult: nil, 2226 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get transaction receipt"), 2227 SetupMocks: func(m *mocksWrapper, tc testCase) { 2228 tx := ethTypes.NewTransaction(0, common.Address{}, big.NewInt(0), 0, big.NewInt(0), []byte{}) 2229 2230 blockNumber, _ := encoding.DecodeUint64orHex(&tc.BlockNumber) 2231 m.DbTx. 2232 On("Rollback", context.Background()). 2233 Return(nil). 2234 Once() 2235 2236 m.State. 2237 On("BeginStateTransaction", context.Background()). 2238 Return(m.DbTx, nil). 2239 Once() 2240 2241 m.State. 2242 On("GetTransactionByL2BlockNumberAndIndex", context.Background(), blockNumber, uint64(tc.Index), m.DbTx). 2243 Return(tx, nil). 2244 Once() 2245 2246 m.State. 2247 On("GetTransactionReceipt", context.Background(), tx.Hash(), m.DbTx). 2248 Return(nil, errors.New("failed to get transaction receipt from state")). 2249 Once() 2250 }, 2251 }, 2252 } 2253 2254 for _, testCase := range testCases { 2255 t.Run(testCase.Name, func(t *testing.T) { 2256 tc := testCase 2257 tc.SetupMocks(m, tc) 2258 2259 res, err := s.JSONRPCCall("eth_getTransactionByBlockNumberAndIndex", tc.BlockNumber, tc.Index) 2260 require.NoError(t, err) 2261 assert.Equal(t, float64(1), res.ID) 2262 assert.Equal(t, "2.0", res.JSONRPC) 2263 2264 if res.Result != nil { 2265 var result interface{} 2266 err = json.Unmarshal(res.Result, &result) 2267 require.NoError(t, err) 2268 2269 if result != nil || testCase.ExpectedResult != nil { 2270 var tx ethTypes.Transaction 2271 err = json.Unmarshal(res.Result, &tx) 2272 require.NoError(t, err) 2273 assert.Equal(t, testCase.ExpectedResult.Hash(), tx.Hash()) 2274 } 2275 } 2276 2277 if res.Error != nil || testCase.ExpectedError != nil { 2278 assert.Equal(t, testCase.ExpectedError.ErrorCode(), res.Error.Code) 2279 assert.Equal(t, testCase.ExpectedError.Error(), res.Error.Message) 2280 } 2281 }) 2282 } 2283 } 2284 2285 func TestGetTransactionByHash(t *testing.T) { 2286 s, m, c := newSequencerMockedServer(t) 2287 defer s.Stop() 2288 2289 type testCase struct { 2290 Name string 2291 Hash common.Hash 2292 ExpectedPending bool 2293 ExpectedResult *ethTypes.Transaction 2294 ExpectedError interface{} 2295 SetupMocks func(m *mocksWrapper, tc testCase) 2296 } 2297 2298 testCases := []testCase{ 2299 { 2300 Name: "Get TX Successfully from state", 2301 Hash: common.HexToHash("0x123"), 2302 ExpectedPending: false, 2303 ExpectedResult: ethTypes.NewTransaction(1, common.Address{}, big.NewInt(1), 1, big.NewInt(1), []byte{}), 2304 ExpectedError: nil, 2305 SetupMocks: func(m *mocksWrapper, tc testCase) { 2306 m.DbTx. 2307 On("Commit", context.Background()). 2308 Return(nil). 2309 Once() 2310 2311 m.State. 2312 On("BeginStateTransaction", context.Background()). 2313 Return(m.DbTx, nil). 2314 Once() 2315 2316 m.State. 2317 On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx). 2318 Return(tc.ExpectedResult, nil). 2319 Once() 2320 2321 receipt := ethTypes.NewReceipt([]byte{}, false, 0) 2322 receipt.BlockHash = common.Hash{} 2323 receipt.BlockNumber = big.NewInt(1) 2324 2325 m.State. 2326 On("GetTransactionReceipt", context.Background(), tc.Hash, m.DbTx). 2327 Return(receipt, nil). 2328 Once() 2329 }, 2330 }, 2331 { 2332 Name: "Get TX Successfully from pool", 2333 Hash: common.HexToHash("0x123"), 2334 ExpectedPending: true, 2335 ExpectedResult: ethTypes.NewTransaction(1, common.Address{}, big.NewInt(1), 1, big.NewInt(1), []byte{}), 2336 ExpectedError: nil, 2337 SetupMocks: func(m *mocksWrapper, tc testCase) { 2338 m.DbTx. 2339 On("Commit", context.Background()). 2340 Return(nil). 2341 Once() 2342 2343 m.State. 2344 On("BeginStateTransaction", context.Background()). 2345 Return(m.DbTx, nil). 2346 Once() 2347 2348 m.State. 2349 On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx). 2350 Return(nil, state.ErrNotFound). 2351 Once() 2352 2353 m.Pool. 2354 On("GetTxByHash", context.Background(), tc.Hash). 2355 Return(&pool.Transaction{Transaction: *tc.ExpectedResult}, nil). 2356 Once() 2357 }, 2358 }, 2359 { 2360 Name: "TX Not Found", 2361 Hash: common.HexToHash("0x123"), 2362 ExpectedPending: false, 2363 ExpectedResult: nil, 2364 ExpectedError: ethereum.NotFound, 2365 SetupMocks: func(m *mocksWrapper, tc testCase) { 2366 m.DbTx. 2367 On("Commit", context.Background()). 2368 Return(nil). 2369 Once() 2370 2371 m.State. 2372 On("BeginStateTransaction", context.Background()). 2373 Return(m.DbTx, nil). 2374 Once() 2375 2376 m.State. 2377 On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx). 2378 Return(nil, state.ErrNotFound). 2379 Once() 2380 2381 m.Pool. 2382 On("GetTxByHash", context.Background(), tc.Hash). 2383 Return(nil, pool.ErrNotFound). 2384 Once() 2385 }, 2386 }, 2387 { 2388 Name: "TX failed to load from the state", 2389 Hash: common.HexToHash("0x123"), 2390 ExpectedPending: false, 2391 ExpectedResult: nil, 2392 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to load transaction by hash from state"), 2393 SetupMocks: func(m *mocksWrapper, tc testCase) { 2394 m.DbTx. 2395 On("Rollback", context.Background()). 2396 Return(nil). 2397 Once() 2398 2399 m.State. 2400 On("BeginStateTransaction", context.Background()). 2401 Return(m.DbTx, nil). 2402 Once() 2403 2404 m.State. 2405 On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx). 2406 Return(nil, errors.New("failed to load transaction by hash from state")). 2407 Once() 2408 }, 2409 }, 2410 { 2411 Name: "TX failed to load from the pool", 2412 Hash: common.HexToHash("0x123"), 2413 ExpectedPending: false, 2414 ExpectedResult: nil, 2415 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to load transaction by hash from pool"), 2416 SetupMocks: func(m *mocksWrapper, tc testCase) { 2417 m.DbTx. 2418 On("Rollback", context.Background()). 2419 Return(nil). 2420 Once() 2421 2422 m.State. 2423 On("BeginStateTransaction", context.Background()). 2424 Return(m.DbTx, nil). 2425 Once() 2426 2427 m.State. 2428 On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx). 2429 Return(nil, state.ErrNotFound). 2430 Once() 2431 2432 m.Pool. 2433 On("GetTxByHash", context.Background(), tc.Hash). 2434 Return(nil, errors.New("failed to load transaction by hash from pool")). 2435 Once() 2436 }, 2437 }, 2438 { 2439 Name: "TX receipt Not Found", 2440 Hash: common.HexToHash("0x123"), 2441 ExpectedPending: false, 2442 ExpectedResult: nil, 2443 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "transaction receipt not found"), 2444 SetupMocks: func(m *mocksWrapper, tc testCase) { 2445 tx := ðTypes.Transaction{} 2446 m.DbTx. 2447 On("Rollback", context.Background()). 2448 Return(nil). 2449 Once() 2450 2451 m.State. 2452 On("BeginStateTransaction", context.Background()). 2453 Return(m.DbTx, nil). 2454 Once() 2455 2456 m.State. 2457 On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx). 2458 Return(tx, nil). 2459 Once() 2460 2461 m.State. 2462 On("GetTransactionReceipt", context.Background(), tc.Hash, m.DbTx). 2463 Return(nil, state.ErrNotFound). 2464 Once() 2465 }, 2466 }, 2467 { 2468 Name: "TX receipt failed to load", 2469 Hash: common.HexToHash("0x123"), 2470 ExpectedPending: false, 2471 ExpectedResult: nil, 2472 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to load transaction receipt from state"), 2473 SetupMocks: func(m *mocksWrapper, tc testCase) { 2474 tx := ðTypes.Transaction{} 2475 m.DbTx. 2476 On("Rollback", context.Background()). 2477 Return(nil). 2478 Once() 2479 2480 m.State. 2481 On("BeginStateTransaction", context.Background()). 2482 Return(m.DbTx, nil). 2483 Once() 2484 2485 m.State. 2486 On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx). 2487 Return(tx, nil). 2488 Once() 2489 2490 m.State. 2491 On("GetTransactionReceipt", context.Background(), tc.Hash, m.DbTx). 2492 Return(nil, errors.New("failed to load transaction receipt from state")). 2493 Once() 2494 }, 2495 }, 2496 } 2497 2498 for _, testCase := range testCases { 2499 t.Run(testCase.Name, func(t *testing.T) { 2500 tc := testCase 2501 tc.SetupMocks(m, tc) 2502 2503 result, pending, err := c.TransactionByHash(context.Background(), testCase.Hash) 2504 assert.Equal(t, testCase.ExpectedPending, pending) 2505 2506 if result != nil || testCase.ExpectedResult != nil { 2507 assert.Equal(t, testCase.ExpectedResult.Hash(), result.Hash()) 2508 } 2509 2510 if err != nil || testCase.ExpectedError != nil { 2511 if expectedErr, ok := testCase.ExpectedError.(*types.RPCError); ok { 2512 rpcErr := err.(rpc.Error) 2513 assert.Equal(t, expectedErr.ErrorCode(), rpcErr.ErrorCode()) 2514 assert.Equal(t, expectedErr.Error(), rpcErr.Error()) 2515 } else { 2516 assert.Equal(t, testCase.ExpectedError, err) 2517 } 2518 } 2519 }) 2520 } 2521 } 2522 2523 func TestGetBlockTransactionCountByHash(t *testing.T) { 2524 s, m, c := newSequencerMockedServer(t) 2525 defer s.Stop() 2526 2527 type testCase struct { 2528 Name string 2529 BlockHash common.Hash 2530 ExpectedResult uint 2531 ExpectedError interface{} 2532 SetupMocks func(m *mocksWrapper, tc testCase) 2533 } 2534 2535 testCases := []testCase{ 2536 { 2537 Name: "Count txs successfully", 2538 BlockHash: blockHash, 2539 ExpectedResult: uint(10), 2540 ExpectedError: nil, 2541 SetupMocks: func(m *mocksWrapper, tc testCase) { 2542 m.DbTx. 2543 On("Commit", context.Background()). 2544 Return(nil). 2545 Once() 2546 2547 m.State. 2548 On("BeginStateTransaction", context.Background()). 2549 Return(m.DbTx, nil). 2550 Once() 2551 2552 m.State. 2553 On("GetL2BlockTransactionCountByHash", context.Background(), tc.BlockHash, m.DbTx). 2554 Return(uint64(10), nil). 2555 Once() 2556 }, 2557 }, 2558 { 2559 Name: "Failed to count txs by hash", 2560 BlockHash: blockHash, 2561 ExpectedResult: 0, 2562 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to count transactions"), 2563 SetupMocks: func(m *mocksWrapper, tc testCase) { 2564 m.DbTx. 2565 On("Rollback", context.Background()). 2566 Return(nil). 2567 Once() 2568 2569 m.State. 2570 On("BeginStateTransaction", context.Background()). 2571 Return(m.DbTx, nil). 2572 Once() 2573 2574 m.State. 2575 On("GetL2BlockTransactionCountByHash", context.Background(), tc.BlockHash, m.DbTx). 2576 Return(uint64(0), errors.New("failed to count txs")). 2577 Once() 2578 }, 2579 }, 2580 } 2581 2582 for _, testCase := range testCases { 2583 t.Run(testCase.Name, func(t *testing.T) { 2584 tc := testCase 2585 tc.SetupMocks(m, tc) 2586 result, err := c.TransactionCount(context.Background(), tc.BlockHash) 2587 2588 assert.Equal(t, testCase.ExpectedResult, result) 2589 2590 if err != nil || testCase.ExpectedError != nil { 2591 if expectedErr, ok := testCase.ExpectedError.(*types.RPCError); ok { 2592 rpcErr := err.(rpc.Error) 2593 assert.Equal(t, expectedErr.ErrorCode(), rpcErr.ErrorCode()) 2594 assert.Equal(t, expectedErr.Error(), rpcErr.Error()) 2595 } else { 2596 assert.Equal(t, testCase.ExpectedError, err) 2597 } 2598 } 2599 }) 2600 } 2601 } 2602 2603 func TestGetBlockTransactionCountByNumber(t *testing.T) { 2604 s, m, _ := newSequencerMockedServer(t) 2605 defer s.Stop() 2606 2607 type testCase struct { 2608 Name string 2609 BlockNumber string 2610 ExpectedResult uint 2611 ExpectedError types.Error 2612 SetupMocks func(m *mocksWrapper, tc testCase) 2613 } 2614 2615 testCases := []testCase{ 2616 { 2617 Name: "Count txs successfully for latest block", 2618 BlockNumber: latest, 2619 ExpectedResult: uint(10), 2620 ExpectedError: nil, 2621 SetupMocks: func(m *mocksWrapper, tc testCase) { 2622 blockNumber := uint64(10) 2623 m.DbTx. 2624 On("Commit", context.Background()). 2625 Return(nil). 2626 Once() 2627 2628 m.State. 2629 On("BeginStateTransaction", context.Background()). 2630 Return(m.DbTx, nil). 2631 Once() 2632 2633 m.State. 2634 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 2635 Return(blockNumber, nil). 2636 Once() 2637 2638 m.State. 2639 On("GetL2BlockTransactionCountByNumber", context.Background(), blockNumber, m.DbTx). 2640 Return(uint64(10), nil). 2641 Once() 2642 }, 2643 }, 2644 { 2645 Name: "Count txs successfully for pending block", 2646 BlockNumber: "pending", 2647 ExpectedResult: uint(10), 2648 ExpectedError: nil, 2649 SetupMocks: func(m *mocksWrapper, tc testCase) { 2650 m.DbTx. 2651 On("Commit", context.Background()). 2652 Return(nil). 2653 Once() 2654 2655 m.State. 2656 On("BeginStateTransaction", context.Background()). 2657 Return(m.DbTx, nil). 2658 Once() 2659 2660 m.Pool. 2661 On("CountPendingTransactions", context.Background()). 2662 Return(uint64(10), nil). 2663 Once() 2664 }, 2665 }, 2666 { 2667 Name: "failed to get last block number", 2668 BlockNumber: latest, 2669 ExpectedResult: 0, 2670 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get the last block number from state"), 2671 SetupMocks: func(m *mocksWrapper, tc testCase) { 2672 m.DbTx. 2673 On("Rollback", context.Background()). 2674 Return(nil). 2675 Once() 2676 2677 m.State. 2678 On("BeginStateTransaction", context.Background()). 2679 Return(m.DbTx, nil). 2680 Once() 2681 2682 m.State. 2683 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 2684 Return(uint64(0), errors.New("failed to get last block number")). 2685 Once() 2686 }, 2687 }, 2688 { 2689 Name: "failed to count tx", 2690 BlockNumber: latest, 2691 ExpectedResult: 0, 2692 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to count transactions"), 2693 SetupMocks: func(m *mocksWrapper, tc testCase) { 2694 blockNumber := uint64(10) 2695 m.DbTx. 2696 On("Rollback", context.Background()). 2697 Return(nil). 2698 Once() 2699 2700 m.State. 2701 On("BeginStateTransaction", context.Background()). 2702 Return(m.DbTx, nil). 2703 Once() 2704 2705 m.State. 2706 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 2707 Return(blockNumber, nil). 2708 Once() 2709 2710 m.State. 2711 On("GetL2BlockTransactionCountByNumber", context.Background(), blockNumber, m.DbTx). 2712 Return(uint64(0), errors.New("failed to count")). 2713 Once() 2714 }, 2715 }, 2716 { 2717 Name: "failed to count pending tx", 2718 BlockNumber: "pending", 2719 ExpectedResult: 0, 2720 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to count pending transactions"), 2721 SetupMocks: func(m *mocksWrapper, tc testCase) { 2722 m.DbTx. 2723 On("Rollback", context.Background()). 2724 Return(nil). 2725 Once() 2726 2727 m.State. 2728 On("BeginStateTransaction", context.Background()). 2729 Return(m.DbTx, nil). 2730 Once() 2731 2732 m.Pool. 2733 On("CountPendingTransactions", context.Background()). 2734 Return(uint64(0), errors.New("failed to count")). 2735 Once() 2736 }, 2737 }, 2738 } 2739 2740 for _, testCase := range testCases { 2741 t.Run(testCase.Name, func(t *testing.T) { 2742 tc := testCase 2743 tc.SetupMocks(m, tc) 2744 res, err := s.JSONRPCCall("eth_getBlockTransactionCountByNumber", tc.BlockNumber) 2745 2746 require.NoError(t, err) 2747 assert.Equal(t, float64(1), res.ID) 2748 assert.Equal(t, "2.0", res.JSONRPC) 2749 2750 if res.Result != nil { 2751 var result types.ArgUint64 2752 err = json.Unmarshal(res.Result, &result) 2753 require.NoError(t, err) 2754 assert.Equal(t, testCase.ExpectedResult, uint(result)) 2755 } 2756 2757 if res.Error != nil || testCase.ExpectedError != nil { 2758 assert.Equal(t, testCase.ExpectedError.ErrorCode(), res.Error.Code) 2759 assert.Equal(t, testCase.ExpectedError.Error(), res.Error.Message) 2760 } 2761 }) 2762 } 2763 } 2764 2765 func TestGetTransactionCount(t *testing.T) { 2766 s, m, _ := newSequencerMockedServer(t) 2767 defer s.Stop() 2768 2769 type testCase struct { 2770 Name string 2771 Params []interface{} 2772 ExpectedResult uint 2773 ExpectedError types.Error 2774 SetupMocks func(m *mocksWrapper, tc testCase) 2775 } 2776 2777 testCases := []testCase{ 2778 { 2779 Name: "Count txs successfully", 2780 Params: []interface{}{addressArg.String()}, 2781 ExpectedResult: uint(10), 2782 ExpectedError: nil, 2783 SetupMocks: func(m *mocksWrapper, tc testCase) { 2784 m.DbTx. 2785 On("Commit", context.Background()). 2786 Return(nil). 2787 Once() 2788 2789 m.State. 2790 On("BeginStateTransaction", context.Background()). 2791 Return(m.DbTx, nil). 2792 Once() 2793 2794 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumTen, Root: blockRoot}) 2795 m.State.On("GetLastL2Block", context.Background(), m.DbTx).Return(block, nil).Once() 2796 2797 m.State. 2798 On("GetNonce", context.Background(), addressArg, blockRoot). 2799 Return(uint64(10), nil). 2800 Once() 2801 }, 2802 }, 2803 { 2804 Name: "Count txs successfully by block hash with EIP-1898", 2805 Params: []interface{}{ 2806 addressArg.String(), 2807 map[string]interface{}{types.BlockHashKey: blockHash.String()}, 2808 }, 2809 ExpectedResult: uint(10), 2810 ExpectedError: nil, 2811 SetupMocks: func(m *mocksWrapper, tc testCase) { 2812 m.DbTx. 2813 On("Commit", context.Background()). 2814 Return(nil). 2815 Once() 2816 2817 m.State. 2818 On("BeginStateTransaction", context.Background()). 2819 Return(m.DbTx, nil). 2820 Once() 2821 2822 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumTen, Root: blockRoot}) 2823 m.State. 2824 On("GetL2BlockByHash", context.Background(), blockHash, m.DbTx). 2825 Return(block, nil). 2826 Once() 2827 2828 m.State. 2829 On("GetNonce", context.Background(), addressArg, blockRoot). 2830 Return(uint64(10), nil). 2831 Once() 2832 }, 2833 }, 2834 { 2835 Name: "Count txs nonce not found", 2836 Params: []interface{}{ 2837 addressArg.String(), 2838 latest, 2839 }, 2840 ExpectedResult: 0, 2841 ExpectedError: nil, 2842 SetupMocks: func(m *mocksWrapper, tc testCase) { 2843 m.DbTx. 2844 On("Commit", context.Background()). 2845 Return(nil). 2846 Once() 2847 2848 m.State. 2849 On("BeginStateTransaction", context.Background()). 2850 Return(m.DbTx, nil). 2851 Once() 2852 2853 m.State. 2854 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 2855 Return(blockNumTen.Uint64(), nil). 2856 Once() 2857 2858 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumTen, Root: blockRoot}) 2859 m.State.On("GetL2BlockByNumber", context.Background(), blockNumTenUint64, m.DbTx).Return(block, nil).Once() 2860 2861 m.State. 2862 On("GetNonce", context.Background(), addressArg, blockRoot). 2863 Return(uint64(0), state.ErrNotFound). 2864 Once() 2865 }, 2866 }, 2867 { 2868 Name: "failed to get last block number", 2869 Params: []interface{}{ 2870 addressArg.String(), 2871 latest, 2872 }, 2873 ExpectedResult: 0, 2874 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get the last block number from state"), 2875 SetupMocks: func(m *mocksWrapper, tc testCase) { 2876 m.DbTx. 2877 On("Rollback", context.Background()). 2878 Return(nil). 2879 Once() 2880 2881 m.State. 2882 On("BeginStateTransaction", context.Background()). 2883 Return(m.DbTx, nil). 2884 Once() 2885 2886 m.State. 2887 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 2888 Return(uint64(0), errors.New("failed to get last block number")). 2889 Once() 2890 }, 2891 }, 2892 { 2893 Name: "failed to get nonce", 2894 Params: []interface{}{ 2895 addressArg.String(), 2896 latest, 2897 }, 2898 ExpectedResult: 0, 2899 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to count transactions"), 2900 SetupMocks: func(m *mocksWrapper, tc testCase) { 2901 m.DbTx. 2902 On("Rollback", context.Background()). 2903 Return(nil). 2904 Once() 2905 2906 m.State. 2907 On("BeginStateTransaction", context.Background()). 2908 Return(m.DbTx, nil). 2909 Once() 2910 2911 m.State. 2912 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 2913 Return(blockNumTen.Uint64(), nil). 2914 Once() 2915 2916 block := ethTypes.NewBlockWithHeader(ðTypes.Header{Number: blockNumTen, Root: blockRoot}) 2917 m.State.On("GetL2BlockByNumber", context.Background(), blockNumTenUint64, m.DbTx).Return(block, nil).Once() 2918 2919 m.State. 2920 On("GetNonce", context.Background(), addressArg, blockRoot). 2921 Return(uint64(0), errors.New("failed to get nonce")). 2922 Once() 2923 }, 2924 }, 2925 } 2926 2927 for _, testCase := range testCases { 2928 t.Run(testCase.Name, func(t *testing.T) { 2929 tc := testCase 2930 tc.SetupMocks(m, tc) 2931 res, err := s.JSONRPCCall("eth_getTransactionCount", tc.Params...) 2932 2933 require.NoError(t, err) 2934 assert.Equal(t, float64(1), res.ID) 2935 assert.Equal(t, "2.0", res.JSONRPC) 2936 2937 if res.Result != nil { 2938 var result types.ArgUint64 2939 err = json.Unmarshal(res.Result, &result) 2940 require.NoError(t, err) 2941 assert.Equal(t, testCase.ExpectedResult, uint(result)) 2942 } 2943 2944 if res.Error != nil || testCase.ExpectedError != nil { 2945 assert.Equal(t, testCase.ExpectedError.ErrorCode(), res.Error.Code) 2946 assert.Equal(t, testCase.ExpectedError.Error(), res.Error.Message) 2947 } 2948 }) 2949 } 2950 } 2951 2952 func TestGetTransactionReceipt(t *testing.T) { 2953 s, m, c := newSequencerMockedServer(t) 2954 defer s.Stop() 2955 2956 type testCase struct { 2957 Name string 2958 Hash common.Hash 2959 ExpectedResult *ethTypes.Receipt 2960 ExpectedError interface{} 2961 SetupMocks func(m *mocksWrapper, tc testCase) 2962 } 2963 2964 testCases := []testCase{ 2965 { 2966 Name: "Get TX receipt Successfully", 2967 Hash: common.HexToHash("0x123"), 2968 ExpectedResult: ethTypes.NewReceipt([]byte{}, false, 0), 2969 ExpectedError: nil, 2970 SetupMocks: func(m *mocksWrapper, tc testCase) { 2971 m.DbTx. 2972 On("Commit", context.Background()). 2973 Return(nil). 2974 Once() 2975 2976 m.State. 2977 On("BeginStateTransaction", context.Background()). 2978 Return(m.DbTx, nil). 2979 Once() 2980 2981 tx := ethTypes.NewTransaction(1, common.Address{}, big.NewInt(1), 1, big.NewInt(1), []byte{}) 2982 privateKey, err := crypto.HexToECDSA(strings.TrimPrefix("0x28b2b0318721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e", "0x")) 2983 require.NoError(t, err) 2984 auth, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(1)) 2985 require.NoError(t, err) 2986 2987 signedTx, err := auth.Signer(auth.From, tx) 2988 require.NoError(t, err) 2989 2990 m.State. 2991 On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx). 2992 Return(signedTx, nil). 2993 Once() 2994 2995 m.State. 2996 On("GetTransactionReceipt", context.Background(), tc.Hash, m.DbTx). 2997 Return(tc.ExpectedResult, nil). 2998 Once() 2999 }, 3000 }, 3001 { 3002 Name: "Get TX receipt but tx not found", 3003 Hash: common.HexToHash("0x123"), 3004 ExpectedResult: nil, 3005 ExpectedError: ethereum.NotFound, 3006 SetupMocks: func(m *mocksWrapper, tc testCase) { 3007 m.DbTx. 3008 On("Commit", context.Background()). 3009 Return(nil). 3010 Once() 3011 3012 m.State. 3013 On("BeginStateTransaction", context.Background()). 3014 Return(m.DbTx, nil). 3015 Once() 3016 3017 m.State. 3018 On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx). 3019 Return(nil, state.ErrNotFound). 3020 Once() 3021 }, 3022 }, 3023 { 3024 Name: "Get TX receipt but failed to get tx", 3025 Hash: common.HexToHash("0x123"), 3026 ExpectedResult: nil, 3027 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get tx from state"), 3028 SetupMocks: func(m *mocksWrapper, tc testCase) { 3029 m.DbTx. 3030 On("Rollback", context.Background()). 3031 Return(nil). 3032 Once() 3033 3034 m.State. 3035 On("BeginStateTransaction", context.Background()). 3036 Return(m.DbTx, nil). 3037 Once() 3038 3039 m.State. 3040 On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx). 3041 Return(nil, errors.New("failed to get tx")). 3042 Once() 3043 }, 3044 }, 3045 { 3046 Name: "TX receipt Not Found", 3047 Hash: common.HexToHash("0x123"), 3048 ExpectedResult: nil, 3049 ExpectedError: ethereum.NotFound, 3050 SetupMocks: func(m *mocksWrapper, tc testCase) { 3051 m.DbTx. 3052 On("Commit", context.Background()). 3053 Return(nil). 3054 Once() 3055 3056 m.State. 3057 On("BeginStateTransaction", context.Background()). 3058 Return(m.DbTx, nil). 3059 Once() 3060 3061 tx := ethTypes.NewTransaction(1, common.Address{}, big.NewInt(1), 1, big.NewInt(1), []byte{}) 3062 privateKey, err := crypto.HexToECDSA(strings.TrimPrefix("0x28b2b0318721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e", "0x")) 3063 require.NoError(t, err) 3064 auth, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(1)) 3065 require.NoError(t, err) 3066 3067 signedTx, err := auth.Signer(auth.From, tx) 3068 require.NoError(t, err) 3069 3070 m.State. 3071 On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx). 3072 Return(signedTx, nil). 3073 Once() 3074 3075 m.State. 3076 On("GetTransactionReceipt", context.Background(), tc.Hash, m.DbTx). 3077 Return(nil, state.ErrNotFound). 3078 Once() 3079 }, 3080 }, 3081 { 3082 Name: "TX receipt failed to load", 3083 Hash: common.HexToHash("0x123"), 3084 ExpectedResult: nil, 3085 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to get tx receipt from state"), 3086 SetupMocks: func(m *mocksWrapper, tc testCase) { 3087 m.DbTx. 3088 On("Rollback", context.Background()). 3089 Return(nil). 3090 Once() 3091 3092 m.State. 3093 On("BeginStateTransaction", context.Background()). 3094 Return(m.DbTx, nil). 3095 Once() 3096 3097 tx := ethTypes.NewTransaction(1, common.Address{}, big.NewInt(1), 1, big.NewInt(1), []byte{}) 3098 privateKey, err := crypto.HexToECDSA(strings.TrimPrefix("0x28b2b0318721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e", "0x")) 3099 require.NoError(t, err) 3100 auth, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(1)) 3101 require.NoError(t, err) 3102 3103 signedTx, err := auth.Signer(auth.From, tx) 3104 require.NoError(t, err) 3105 3106 m.State. 3107 On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx). 3108 Return(signedTx, nil). 3109 Once() 3110 3111 m.State. 3112 On("GetTransactionReceipt", context.Background(), tc.Hash, m.DbTx). 3113 Return(nil, errors.New("failed to get tx receipt from state")). 3114 Once() 3115 }, 3116 }, 3117 { 3118 Name: "Get TX but failed to build response Successfully", 3119 Hash: common.HexToHash("0x123"), 3120 ExpectedResult: nil, 3121 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to build the receipt response"), 3122 SetupMocks: func(m *mocksWrapper, tc testCase) { 3123 m.DbTx. 3124 On("Rollback", context.Background()). 3125 Return(nil). 3126 Once() 3127 3128 m.State. 3129 On("BeginStateTransaction", context.Background()). 3130 Return(m.DbTx, nil). 3131 Once() 3132 3133 tx := ethTypes.NewTransaction(1, common.Address{}, big.NewInt(1), 1, big.NewInt(1), []byte{}) 3134 3135 m.State. 3136 On("GetTransactionByHash", context.Background(), tc.Hash, m.DbTx). 3137 Return(tx, nil). 3138 Once() 3139 3140 m.State. 3141 On("GetTransactionReceipt", context.Background(), tc.Hash, m.DbTx). 3142 Return(ethTypes.NewReceipt([]byte{}, false, 0), nil). 3143 Once() 3144 }, 3145 }, 3146 } 3147 3148 for _, testCase := range testCases { 3149 t.Run(testCase.Name, func(t *testing.T) { 3150 tc := testCase 3151 tc.SetupMocks(m, tc) 3152 3153 result, err := c.TransactionReceipt(context.Background(), testCase.Hash) 3154 3155 if result != nil || testCase.ExpectedResult != nil { 3156 assert.Equal(t, testCase.ExpectedResult.TxHash, result.TxHash) 3157 } 3158 3159 if err != nil || testCase.ExpectedError != nil { 3160 if expectedErr, ok := testCase.ExpectedError.(*types.RPCError); ok { 3161 rpcErr := err.(rpc.Error) 3162 assert.Equal(t, expectedErr.ErrorCode(), rpcErr.ErrorCode()) 3163 assert.Equal(t, expectedErr.Error(), rpcErr.Error()) 3164 } else { 3165 assert.Equal(t, testCase.ExpectedError, err) 3166 } 3167 } 3168 }) 3169 } 3170 } 3171 3172 func TestSendRawTransactionViaGeth(t *testing.T) { 3173 s, m, c := newSequencerMockedServer(t) 3174 defer s.Stop() 3175 3176 type testCase struct { 3177 Name string 3178 Tx *ethTypes.Transaction 3179 ExpectedError interface{} 3180 SetupMocks func(t *testing.T, m *mocksWrapper, tc testCase) 3181 } 3182 3183 testCases := []testCase{ 3184 { 3185 Name: "Send TX successfully", 3186 Tx: ethTypes.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), uint64(1), big.NewInt(1), []byte{}), 3187 ExpectedError: nil, 3188 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 3189 txMatchByHash := mock.MatchedBy(func(tx ethTypes.Transaction) bool { 3190 h1 := tx.Hash().Hex() 3191 h2 := tc.Tx.Hash().Hex() 3192 return h1 == h2 3193 }) 3194 3195 m.Pool. 3196 On("AddTx", context.Background(), txMatchByHash, ""). 3197 Return(nil). 3198 Once() 3199 }, 3200 }, 3201 { 3202 Name: "Send TX failed to add to the pool", 3203 Tx: ethTypes.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), uint64(1), big.NewInt(1), []byte{}), 3204 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to add TX to the pool"), 3205 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 3206 txMatchByHash := mock.MatchedBy(func(tx ethTypes.Transaction) bool { 3207 h1 := tx.Hash().Hex() 3208 h2 := tc.Tx.Hash().Hex() 3209 return h1 == h2 3210 }) 3211 3212 m.Pool. 3213 On("AddTx", context.Background(), txMatchByHash, ""). 3214 Return(errors.New("failed to add TX to the pool")). 3215 Once() 3216 }, 3217 }, 3218 } 3219 3220 for _, testCase := range testCases { 3221 t.Run(testCase.Name, func(t *testing.T) { 3222 tc := testCase 3223 tc.SetupMocks(t, m, tc) 3224 3225 err := c.SendTransaction(context.Background(), tc.Tx) 3226 3227 if err != nil || testCase.ExpectedError != nil { 3228 if expectedErr, ok := testCase.ExpectedError.(*types.RPCError); ok { 3229 rpcErr := err.(rpc.Error) 3230 assert.Equal(t, expectedErr.ErrorCode(), rpcErr.ErrorCode()) 3231 assert.Equal(t, expectedErr.Error(), rpcErr.Error()) 3232 } else { 3233 assert.Equal(t, testCase.ExpectedError, err) 3234 } 3235 } 3236 }) 3237 } 3238 } 3239 3240 func TestSendRawTransactionJSONRPCCall(t *testing.T) { 3241 s, m, _ := newSequencerMockedServer(t) 3242 defer s.Stop() 3243 3244 type testCase struct { 3245 Name string 3246 Input string 3247 ExpectedResult *common.Hash 3248 ExpectedError types.Error 3249 Prepare func(t *testing.T, tc *testCase) 3250 SetupMocks func(t *testing.T, m *mocksWrapper, tc testCase) 3251 } 3252 3253 testCases := []testCase{ 3254 { 3255 Name: "Send TX successfully", 3256 Prepare: func(t *testing.T, tc *testCase) { 3257 tx := ethTypes.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), uint64(1), big.NewInt(1), []byte{}) 3258 3259 txBinary, err := tx.MarshalBinary() 3260 require.NoError(t, err) 3261 3262 rawTx := hex.EncodeToHex(txBinary) 3263 require.NoError(t, err) 3264 3265 tc.Input = rawTx 3266 tc.ExpectedResult = state.HashPtr(tx.Hash()) 3267 tc.ExpectedError = nil 3268 }, 3269 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 3270 m.Pool. 3271 On("AddTx", context.Background(), mock.IsType(ethTypes.Transaction{}), ""). 3272 Return(nil). 3273 Once() 3274 }, 3275 }, 3276 { 3277 Name: "Send TX failed to add to the pool", 3278 Prepare: func(t *testing.T, tc *testCase) { 3279 tx := ethTypes.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), uint64(1), big.NewInt(1), []byte{}) 3280 3281 txBinary, err := tx.MarshalBinary() 3282 require.NoError(t, err) 3283 3284 rawTx := hex.EncodeToHex(txBinary) 3285 require.NoError(t, err) 3286 3287 tc.Input = rawTx 3288 tc.ExpectedResult = nil 3289 tc.ExpectedError = types.NewRPCError(types.DefaultErrorCode, "failed to add TX to the pool") 3290 }, 3291 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 3292 m.Pool. 3293 On("AddTx", context.Background(), mock.IsType(ethTypes.Transaction{}), ""). 3294 Return(errors.New("failed to add TX to the pool")). 3295 Once() 3296 }, 3297 }, 3298 { 3299 Name: "Send invalid tx input", 3300 Prepare: func(t *testing.T, tc *testCase) { 3301 tc.Input = "0x1234" 3302 tc.ExpectedResult = nil 3303 tc.ExpectedError = types.NewRPCError(types.InvalidParamsErrorCode, "invalid tx input") 3304 }, 3305 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) {}, 3306 }, 3307 } 3308 3309 for _, testCase := range testCases { 3310 t.Run(testCase.Name, func(t *testing.T) { 3311 tc := testCase 3312 tc.Prepare(t, &tc) 3313 tc.SetupMocks(t, m, tc) 3314 3315 res, err := s.JSONRPCCall("eth_sendRawTransaction", tc.Input) 3316 require.NoError(t, err) 3317 3318 assert.Equal(t, float64(1), res.ID) 3319 assert.Equal(t, "2.0", res.JSONRPC) 3320 3321 if res.Result != nil || tc.ExpectedResult != nil { 3322 var result common.Hash 3323 err = json.Unmarshal(res.Result, &result) 3324 require.NoError(t, err) 3325 assert.Equal(t, *tc.ExpectedResult, result) 3326 } 3327 if res.Error != nil || tc.ExpectedError != nil { 3328 assert.Equal(t, tc.ExpectedError.ErrorCode(), res.Error.Code) 3329 assert.Equal(t, tc.ExpectedError.Error(), res.Error.Message) 3330 } 3331 }) 3332 } 3333 } 3334 3335 func TestSendRawTransactionViaGethForNonSequencerNode(t *testing.T) { 3336 sequencerServer, sequencerMocks, _ := newSequencerMockedServer(t) 3337 defer sequencerServer.Stop() 3338 nonSequencerServer, _, nonSequencerClient := newNonSequencerMockedServer(t, sequencerServer.ServerURL) 3339 defer nonSequencerServer.Stop() 3340 3341 type testCase struct { 3342 Name string 3343 Tx *ethTypes.Transaction 3344 ExpectedError interface{} 3345 SetupMocks func(t *testing.T, m *mocksWrapper, tc testCase) 3346 } 3347 3348 testCases := []testCase{ 3349 { 3350 Name: "Send TX successfully", 3351 Tx: ethTypes.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), uint64(1), big.NewInt(1), []byte{}), 3352 ExpectedError: nil, 3353 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 3354 txMatchByHash := mock.MatchedBy(func(tx ethTypes.Transaction) bool { 3355 h1 := tx.Hash().Hex() 3356 h2 := tc.Tx.Hash().Hex() 3357 return h1 == h2 3358 }) 3359 3360 m.Pool. 3361 On("AddTx", context.Background(), txMatchByHash, ""). 3362 Return(nil). 3363 Once() 3364 }, 3365 }, 3366 { 3367 Name: "Send TX failed to add to the pool", 3368 Tx: ethTypes.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), uint64(1), big.NewInt(1), []byte{}), 3369 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to add TX to the pool"), 3370 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 3371 txMatchByHash := mock.MatchedBy(func(tx ethTypes.Transaction) bool { 3372 h1 := tx.Hash().Hex() 3373 h2 := tc.Tx.Hash().Hex() 3374 return h1 == h2 3375 }) 3376 3377 m.Pool. 3378 On("AddTx", context.Background(), txMatchByHash, ""). 3379 Return(errors.New("failed to add TX to the pool")). 3380 Once() 3381 }, 3382 }, 3383 } 3384 3385 for _, testCase := range testCases { 3386 t.Run(testCase.Name, func(t *testing.T) { 3387 tc := testCase 3388 tc.SetupMocks(t, sequencerMocks, tc) 3389 3390 err := nonSequencerClient.SendTransaction(context.Background(), tc.Tx) 3391 3392 if err != nil || testCase.ExpectedError != nil { 3393 if expectedErr, ok := testCase.ExpectedError.(*types.RPCError); ok { 3394 rpcErr := err.(rpc.Error) 3395 assert.Equal(t, expectedErr.ErrorCode(), rpcErr.ErrorCode()) 3396 assert.Equal(t, expectedErr.Error(), rpcErr.Error()) 3397 } else { 3398 assert.Equal(t, testCase.ExpectedError, err) 3399 } 3400 } 3401 }) 3402 } 3403 } 3404 3405 func TestSendRawTransactionViaGethForNonSequencerNodeFailsToRelayTxToSequencerNode(t *testing.T) { 3406 nonSequencerServer, _, nonSequencerClient := newNonSequencerMockedServer(t, "http://wrong.url") 3407 defer nonSequencerServer.Stop() 3408 3409 type testCase struct { 3410 Name string 3411 Tx *ethTypes.Transaction 3412 ExpectedError interface{} 3413 } 3414 3415 testCases := []testCase{ 3416 { 3417 Name: "Send TX failed to relay tx to the sequencer node", 3418 Tx: ethTypes.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), uint64(1), big.NewInt(1), []byte{}), 3419 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to relay tx to the sequencer node"), 3420 }, 3421 } 3422 3423 for _, testCase := range testCases { 3424 t.Run(testCase.Name, func(t *testing.T) { 3425 tc := testCase 3426 3427 err := nonSequencerClient.SendTransaction(context.Background(), tc.Tx) 3428 3429 if err != nil || testCase.ExpectedError != nil { 3430 if expectedErr, ok := testCase.ExpectedError.(*types.RPCError); ok { 3431 rpcErr := err.(rpc.Error) 3432 assert.Equal(t, expectedErr.ErrorCode(), rpcErr.ErrorCode()) 3433 assert.Equal(t, expectedErr.Error(), rpcErr.Error()) 3434 } else { 3435 assert.Equal(t, testCase.ExpectedError, err) 3436 } 3437 } 3438 }) 3439 } 3440 } 3441 3442 func TestProtocolVersion(t *testing.T) { 3443 s, _, _ := newSequencerMockedServer(t) 3444 defer s.Stop() 3445 3446 res, err := s.JSONRPCCall("eth_protocolVersion") 3447 require.NoError(t, err) 3448 3449 assert.Equal(t, float64(1), res.ID) 3450 assert.Equal(t, "2.0", res.JSONRPC) 3451 assert.Nil(t, res.Error) 3452 3453 var result string 3454 err = json.Unmarshal(res.Result, &result) 3455 require.NoError(t, err) 3456 3457 assert.Equal(t, "0x0", result) 3458 } 3459 3460 func TestNewFilter(t *testing.T) { 3461 s, m, _ := newSequencerMockedServer(t) 3462 defer s.Stop() 3463 3464 type testCase struct { 3465 Name string 3466 Request types.LogFilterRequest 3467 ExpectedResult string 3468 ExpectedError types.Error 3469 SetupMocks func(m *mocksWrapper, tc testCase) 3470 } 3471 3472 hash := common.HexToHash("0x42") 3473 blockNumber := "8" 3474 testCases := []testCase{ 3475 { 3476 Name: "New filter created successfully", 3477 Request: types.LogFilterRequest{ 3478 ToBlock: &blockNumber, 3479 }, 3480 ExpectedResult: "1", 3481 ExpectedError: nil, 3482 SetupMocks: func(m *mocksWrapper, tc testCase) { 3483 m.Storage. 3484 On("NewLogFilter", mock.IsType(&websocket.Conn{}), mock.IsType(LogFilter{})). 3485 Return("1", nil). 3486 Once() 3487 }, 3488 }, 3489 { 3490 Name: "failed to create new filter", 3491 Request: types.LogFilterRequest{ 3492 BlockHash: &hash, 3493 }, 3494 ExpectedResult: "", 3495 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to create new log filter"), 3496 SetupMocks: func(m *mocksWrapper, tc testCase) { 3497 m.Storage. 3498 On("NewLogFilter", mock.IsType(&websocket.Conn{}), mock.IsType(LogFilter{})). 3499 Return("", errors.New("failed to add new filter")). 3500 Once() 3501 }, 3502 }, 3503 { 3504 Name: "failed to create new filter because BlockHash and ToBlock are present", 3505 Request: types.LogFilterRequest{ 3506 BlockHash: &hash, 3507 ToBlock: &blockNumber, 3508 }, 3509 ExpectedResult: "", 3510 ExpectedError: types.NewRPCError(types.InvalidParamsErrorCode, "invalid argument 0: cannot specify both BlockHash and FromBlock/ToBlock, choose one or the other"), 3511 SetupMocks: func(m *mocksWrapper, tc testCase) { 3512 m.Storage. 3513 On("NewLogFilter", mock.IsType(&websocket.Conn{}), mock.IsType(LogFilter{})). 3514 Once(). 3515 Return("", ErrFilterInvalidPayload). 3516 Once() 3517 }, 3518 }, 3519 } 3520 3521 for _, testCase := range testCases { 3522 t.Run(testCase.Name, func(t *testing.T) { 3523 tc := testCase 3524 tc.SetupMocks(m, tc) 3525 3526 res, err := s.JSONRPCCall("eth_newFilter", tc.Request) 3527 require.NoError(t, err) 3528 3529 assert.Equal(t, float64(1), res.ID) 3530 assert.Equal(t, "2.0", res.JSONRPC) 3531 3532 if res.Result != nil { 3533 var result string 3534 err = json.Unmarshal(res.Result, &result) 3535 require.NoError(t, err) 3536 assert.Equal(t, tc.ExpectedResult, result) 3537 } 3538 3539 if res.Error != nil || tc.ExpectedError != nil { 3540 assert.Equal(t, tc.ExpectedError.ErrorCode(), res.Error.Code) 3541 assert.Equal(t, tc.ExpectedError.Error(), res.Error.Message) 3542 } 3543 }) 3544 } 3545 } 3546 3547 func TestNewBlockFilter(t *testing.T) { 3548 s, m, _ := newSequencerMockedServer(t) 3549 defer s.Stop() 3550 3551 type testCase struct { 3552 Name string 3553 ExpectedResult string 3554 ExpectedError types.Error 3555 SetupMocks func(m *mocksWrapper, tc testCase) 3556 } 3557 3558 testCases := []testCase{ 3559 { 3560 Name: "New block filter created successfully", 3561 ExpectedResult: "1", 3562 ExpectedError: nil, 3563 SetupMocks: func(m *mocksWrapper, tc testCase) { 3564 m.Storage. 3565 On("NewBlockFilter", mock.IsType(&websocket.Conn{})). 3566 Return("1", nil). 3567 Once() 3568 }, 3569 }, 3570 { 3571 Name: "failed to create new block filter", 3572 ExpectedResult: "", 3573 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to create new block filter"), 3574 SetupMocks: func(m *mocksWrapper, tc testCase) { 3575 m.Storage. 3576 On("NewBlockFilter", mock.IsType(&websocket.Conn{})). 3577 Return("", errors.New("failed to add new block filter")). 3578 Once() 3579 }, 3580 }, 3581 } 3582 3583 for _, testCase := range testCases { 3584 t.Run(testCase.Name, func(t *testing.T) { 3585 tc := testCase 3586 tc.SetupMocks(m, tc) 3587 3588 res, err := s.JSONRPCCall("eth_newBlockFilter") 3589 require.NoError(t, err) 3590 3591 assert.Equal(t, float64(1), res.ID) 3592 assert.Equal(t, "2.0", res.JSONRPC) 3593 3594 if res.Result != nil { 3595 var result string 3596 err = json.Unmarshal(res.Result, &result) 3597 require.NoError(t, err) 3598 assert.Equal(t, tc.ExpectedResult, result) 3599 } 3600 3601 if res.Error != nil || tc.ExpectedError != nil { 3602 assert.Equal(t, tc.ExpectedError.ErrorCode(), res.Error.Code) 3603 assert.Equal(t, tc.ExpectedError.Error(), res.Error.Message) 3604 } 3605 }) 3606 } 3607 } 3608 3609 func TestNewPendingTransactionFilter(t *testing.T) { 3610 s, m, _ := newSequencerMockedServer(t) 3611 defer s.Stop() 3612 3613 type testCase struct { 3614 Name string 3615 ExpectedResult string 3616 ExpectedError types.Error 3617 SetupMocks func(m *mocksWrapper, tc testCase) 3618 } 3619 3620 testCases := []testCase{ 3621 // { 3622 // Name: "New pending transaction filter created successfully", 3623 // ExpectedResult: "1", 3624 // ExpectedError: nil, 3625 // SetupMocks: func(m *mocks, tc testCase) { 3626 // m.Storage. 3627 // On("NewPendingTransactionFilter", mock.IsType(&websocket.Conn{})). 3628 // Return("1", nil). 3629 // Once() 3630 // }, 3631 // }, 3632 // { 3633 // Name: "failed to create new pending transaction filter", 3634 // ExpectedResult: "", 3635 // ExpectedError: types.NewRPCError(types.DefaultErrorCode, "failed to create new pending transaction filter"), 3636 // SetupMocks: func(m *mocks, tc testCase) { 3637 // m.Storage. 3638 // On("NewPendingTransactionFilter", mock.IsType(&websocket.Conn{})). 3639 // Return("", errors.New("failed to add new pending transaction filter")). 3640 // Once() 3641 // }, 3642 // }, 3643 { 3644 Name: "can't create pending tx filter", 3645 ExpectedResult: "", 3646 ExpectedError: types.NewRPCError(types.DefaultErrorCode, "not supported yet"), 3647 SetupMocks: func(m *mocksWrapper, tc testCase) {}, 3648 }, 3649 } 3650 3651 for _, testCase := range testCases { 3652 t.Run(testCase.Name, func(t *testing.T) { 3653 tc := testCase 3654 tc.SetupMocks(m, tc) 3655 3656 res, err := s.JSONRPCCall("eth_newPendingTransactionFilter") 3657 require.NoError(t, err) 3658 3659 assert.Equal(t, float64(1), res.ID) 3660 assert.Equal(t, "2.0", res.JSONRPC) 3661 3662 if res.Result != nil { 3663 var result string 3664 err = json.Unmarshal(res.Result, &result) 3665 require.NoError(t, err) 3666 assert.Equal(t, tc.ExpectedResult, result) 3667 } 3668 3669 if res.Error != nil || tc.ExpectedError != nil { 3670 assert.Equal(t, tc.ExpectedError.ErrorCode(), res.Error.Code) 3671 assert.Equal(t, tc.ExpectedError.Error(), res.Error.Message) 3672 } 3673 }) 3674 } 3675 } 3676 3677 func TestUninstallFilter(t *testing.T) { 3678 s, m, _ := newSequencerMockedServer(t) 3679 defer s.Stop() 3680 3681 type testCase struct { 3682 Name string 3683 FilterID string 3684 ExpectedResult bool 3685 ExpectedError types.Error 3686 SetupMocks func(m *mocksWrapper, tc testCase) 3687 } 3688 3689 testCases := []testCase{ 3690 { 3691 Name: "Uninstalls filter successfully", 3692 FilterID: "1", 3693 ExpectedResult: true, 3694 ExpectedError: nil, 3695 SetupMocks: func(m *mocksWrapper, tc testCase) { 3696 m.Storage. 3697 On("UninstallFilter", tc.FilterID). 3698 Return(nil). 3699 Once() 3700 }, 3701 }, 3702 { 3703 Name: "filter already uninstalled", 3704 FilterID: "1", 3705 ExpectedResult: false, 3706 ExpectedError: nil, 3707 SetupMocks: func(m *mocksWrapper, tc testCase) { 3708 m.Storage. 3709 On("UninstallFilter", tc.FilterID). 3710 Return(ErrNotFound). 3711 Once() 3712 }, 3713 }, 3714 } 3715 3716 for _, testCase := range testCases { 3717 t.Run(testCase.Name, func(t *testing.T) { 3718 tc := testCase 3719 tc.SetupMocks(m, tc) 3720 3721 res, err := s.JSONRPCCall("eth_uninstallFilter", tc.FilterID) 3722 require.NoError(t, err) 3723 3724 assert.Equal(t, float64(1), res.ID) 3725 assert.Equal(t, "2.0", res.JSONRPC) 3726 3727 if res.Result != nil { 3728 var result bool 3729 err = json.Unmarshal(res.Result, &result) 3730 require.NoError(t, err) 3731 assert.Equal(t, tc.ExpectedResult, result) 3732 } 3733 3734 if res.Error != nil || tc.ExpectedError != nil { 3735 assert.Equal(t, tc.ExpectedError.ErrorCode(), res.Error.Code) 3736 assert.Equal(t, tc.ExpectedError.Error(), res.Error.Message) 3737 } 3738 }) 3739 } 3740 } 3741 3742 func TestGetLogs(t *testing.T) { 3743 s, m, c := newSequencerMockedServer(t) 3744 defer s.Stop() 3745 3746 type testCase struct { 3747 Name string 3748 Filter ethereum.FilterQuery 3749 ExpectedResult []ethTypes.Log 3750 ExpectedError interface{} 3751 Prepare func(t *testing.T, tc *testCase) 3752 SetupMocks func(m *mocksWrapper, tc testCase) 3753 } 3754 3755 testCases := []testCase{ 3756 { 3757 Name: "Get logs successfully", 3758 Prepare: func(t *testing.T, tc *testCase) { 3759 tc.Filter = ethereum.FilterQuery{ 3760 FromBlock: big.NewInt(1), ToBlock: big.NewInt(2), 3761 Addresses: []common.Address{common.HexToAddress("0x111")}, 3762 Topics: [][]common.Hash{{common.HexToHash("0x222")}}, 3763 } 3764 tc.ExpectedResult = []ethTypes.Log{{ 3765 Address: common.Address{}, Topics: []common.Hash{}, Data: []byte{}, 3766 BlockNumber: uint64(1), TxHash: common.Hash{}, TxIndex: uint(1), 3767 BlockHash: common.Hash{}, Index: uint(1), Removed: false, 3768 }} 3769 tc.ExpectedError = nil 3770 }, 3771 SetupMocks: func(m *mocksWrapper, tc testCase) { 3772 var since *time.Time 3773 logs := make([]*ethTypes.Log, 0, len(tc.ExpectedResult)) 3774 for _, log := range tc.ExpectedResult { 3775 l := log 3776 logs = append(logs, &l) 3777 } 3778 3779 m.DbTx. 3780 On("Commit", context.Background()). 3781 Return(nil). 3782 Once() 3783 3784 m.State. 3785 On("BeginStateTransaction", context.Background()). 3786 Return(m.DbTx, nil). 3787 Once() 3788 3789 m.State. 3790 On("GetLogs", context.Background(), tc.Filter.FromBlock.Uint64(), tc.Filter.ToBlock.Uint64(), tc.Filter.Addresses, tc.Filter.Topics, tc.Filter.BlockHash, since, m.DbTx). 3791 Return(logs, nil). 3792 Once() 3793 }, 3794 }, 3795 { 3796 Name: "Get logs fails to get logs from state", 3797 Prepare: func(t *testing.T, tc *testCase) { 3798 tc.Filter = ethereum.FilterQuery{ 3799 FromBlock: big.NewInt(1), ToBlock: big.NewInt(2), 3800 Addresses: []common.Address{common.HexToAddress("0x111")}, 3801 Topics: [][]common.Hash{{common.HexToHash("0x222")}}, 3802 } 3803 tc.ExpectedResult = nil 3804 tc.ExpectedError = types.NewRPCError(types.DefaultErrorCode, "failed to get logs from state") 3805 }, 3806 SetupMocks: func(m *mocksWrapper, tc testCase) { 3807 var since *time.Time 3808 m.DbTx. 3809 On("Rollback", context.Background()). 3810 Return(nil). 3811 Once() 3812 3813 m.State. 3814 On("BeginStateTransaction", context.Background()). 3815 Return(m.DbTx, nil). 3816 Once() 3817 3818 m.State. 3819 On("GetLogs", context.Background(), tc.Filter.FromBlock.Uint64(), tc.Filter.ToBlock.Uint64(), tc.Filter.Addresses, tc.Filter.Topics, tc.Filter.BlockHash, since, m.DbTx). 3820 Return(nil, errors.New("failed to get logs from state")). 3821 Once() 3822 }, 3823 }, 3824 { 3825 Name: "Get logs fails to identify from block", 3826 Prepare: func(t *testing.T, tc *testCase) { 3827 tc.Filter = ethereum.FilterQuery{ 3828 FromBlock: big.NewInt(-1), ToBlock: big.NewInt(2), 3829 Addresses: []common.Address{common.HexToAddress("0x111")}, 3830 Topics: [][]common.Hash{{common.HexToHash("0x222")}}, 3831 } 3832 tc.ExpectedResult = nil 3833 tc.ExpectedError = types.NewRPCError(types.DefaultErrorCode, "failed to get the last block number from state") 3834 }, 3835 SetupMocks: func(m *mocksWrapper, tc testCase) { 3836 m.DbTx. 3837 On("Rollback", context.Background()). 3838 Return(nil). 3839 Once() 3840 3841 m.State. 3842 On("BeginStateTransaction", context.Background()). 3843 Return(m.DbTx, nil). 3844 Once() 3845 3846 m.State. 3847 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 3848 Return(uint64(0), errors.New("failed to get last block number from state")). 3849 Once() 3850 }, 3851 }, 3852 { 3853 Name: "Get logs fails to identify to block", 3854 Prepare: func(t *testing.T, tc *testCase) { 3855 tc.Filter = ethereum.FilterQuery{ 3856 FromBlock: big.NewInt(1), ToBlock: big.NewInt(-1), 3857 Addresses: []common.Address{common.HexToAddress("0x111")}, 3858 Topics: [][]common.Hash{{common.HexToHash("0x222")}}, 3859 } 3860 tc.ExpectedResult = nil 3861 tc.ExpectedError = types.NewRPCError(types.DefaultErrorCode, "failed to get the last block number from state") 3862 }, 3863 SetupMocks: func(m *mocksWrapper, tc testCase) { 3864 m.DbTx. 3865 On("Rollback", context.Background()). 3866 Return(nil). 3867 Once() 3868 3869 m.State. 3870 On("BeginStateTransaction", context.Background()). 3871 Return(m.DbTx, nil). 3872 Once() 3873 3874 m.State. 3875 On("GetLastL2BlockNumber", context.Background(), m.DbTx). 3876 Return(uint64(0), errors.New("failed to get last block number from state")). 3877 Once() 3878 }, 3879 }, 3880 } 3881 3882 for _, testCase := range testCases { 3883 t.Run(testCase.Name, func(t *testing.T) { 3884 tc := testCase 3885 tc.Prepare(t, &tc) 3886 tc.SetupMocks(m, tc) 3887 3888 result, err := c.FilterLogs(context.Background(), tc.Filter) 3889 3890 if result != nil || tc.ExpectedResult != nil { 3891 assert.ElementsMatch(t, tc.ExpectedResult, result) 3892 } 3893 3894 if err != nil || tc.ExpectedError != nil { 3895 if expectedErr, ok := tc.ExpectedError.(*types.RPCError); ok { 3896 rpcErr := err.(rpc.Error) 3897 assert.Equal(t, expectedErr.ErrorCode(), rpcErr.ErrorCode()) 3898 assert.Equal(t, expectedErr.Error(), rpcErr.Error()) 3899 } else { 3900 assert.Equal(t, tc.ExpectedError, err) 3901 } 3902 } 3903 }) 3904 } 3905 } 3906 3907 func TestGetFilterLogs(t *testing.T) { 3908 s, m, _ := newSequencerMockedServer(t) 3909 defer s.Stop() 3910 3911 type testCase struct { 3912 Name string 3913 FilterID string 3914 ExpectedResult []ethTypes.Log 3915 ExpectedError types.Error 3916 Prepare func(t *testing.T, tc *testCase) 3917 SetupMocks func(t *testing.T, m *mocksWrapper, tc testCase) 3918 } 3919 3920 testCases := []testCase{ 3921 { 3922 Name: "Get filter logs successfully", 3923 Prepare: func(t *testing.T, tc *testCase) { 3924 tc.FilterID = "1" 3925 tc.ExpectedResult = []ethTypes.Log{{ 3926 Address: common.Address{}, Topics: []common.Hash{}, Data: []byte{}, 3927 BlockNumber: uint64(1), TxHash: common.Hash{}, TxIndex: uint(1), 3928 BlockHash: common.Hash{}, Index: uint(1), Removed: false, 3929 }} 3930 tc.ExpectedError = nil 3931 }, 3932 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 3933 var since *time.Time 3934 logs := make([]*ethTypes.Log, 0, len(tc.ExpectedResult)) 3935 for _, log := range tc.ExpectedResult { 3936 l := log 3937 logs = append(logs, &l) 3938 } 3939 3940 bn1 := types.BlockNumber(1) 3941 bn2 := types.BlockNumber(2) 3942 logFilter := LogFilter{ 3943 FromBlock: &bn1, 3944 ToBlock: &bn2, 3945 Addresses: []common.Address{common.HexToAddress("0x111")}, 3946 Topics: [][]common.Hash{{common.HexToHash("0x222")}}, 3947 } 3948 3949 filter := &Filter{ 3950 ID: tc.FilterID, 3951 Type: FilterTypeLog, 3952 LastPoll: time.Now(), 3953 Parameters: logFilter, 3954 } 3955 3956 m.DbTx. 3957 On("Commit", context.Background()). 3958 Return(nil). 3959 Once() 3960 3961 m.State. 3962 On("BeginStateTransaction", context.Background()). 3963 Return(m.DbTx, nil). 3964 Once() 3965 3966 m.Storage. 3967 On("GetFilter", tc.FilterID). 3968 Return(filter, nil). 3969 Once() 3970 3971 m.State. 3972 On("GetLogs", context.Background(), uint64(*logFilter.FromBlock), uint64(*logFilter.ToBlock), logFilter.Addresses, logFilter.Topics, logFilter.BlockHash, since, m.DbTx). 3973 Return(logs, nil). 3974 Once() 3975 }, 3976 }, 3977 { 3978 Name: "Get filter logs filter not found", 3979 Prepare: func(t *testing.T, tc *testCase) { 3980 tc.FilterID = "1" 3981 tc.ExpectedResult = nil 3982 tc.ExpectedError = nil 3983 }, 3984 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 3985 m.Storage. 3986 On("GetFilter", tc.FilterID). 3987 Return(nil, ErrNotFound). 3988 Once() 3989 }, 3990 }, 3991 { 3992 Name: "Get filter logs failed to get filter", 3993 Prepare: func(t *testing.T, tc *testCase) { 3994 tc.FilterID = "1" 3995 tc.ExpectedResult = nil 3996 tc.ExpectedError = types.NewRPCError(types.DefaultErrorCode, "failed to get filter from storage") 3997 }, 3998 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 3999 m.Storage. 4000 On("GetFilter", tc.FilterID). 4001 Return(nil, errors.New("failed to get filter")). 4002 Once() 4003 }, 4004 }, 4005 { 4006 Name: "Get filter logs is a valid filter but its not a log filter", 4007 Prepare: func(t *testing.T, tc *testCase) { 4008 tc.FilterID = "1" 4009 tc.ExpectedResult = nil 4010 tc.ExpectedError = nil 4011 }, 4012 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 4013 filter := &Filter{ 4014 ID: tc.FilterID, 4015 Type: FilterTypeBlock, 4016 LastPoll: time.Now(), 4017 Parameters: "", 4018 } 4019 4020 m.Storage. 4021 On("GetFilter", tc.FilterID). 4022 Return(filter, nil). 4023 Once() 4024 }, 4025 }, 4026 } 4027 4028 for _, testCase := range testCases { 4029 t.Run(testCase.Name, func(t *testing.T) { 4030 tc := testCase 4031 tc.Prepare(t, &tc) 4032 tc.SetupMocks(t, m, tc) 4033 4034 res, err := s.JSONRPCCall("eth_getFilterLogs", tc.FilterID) 4035 require.NoError(t, err) 4036 assert.Equal(t, float64(1), res.ID) 4037 assert.Equal(t, "2.0", res.JSONRPC) 4038 4039 if res.Result != nil { 4040 var result interface{} 4041 err = json.Unmarshal(res.Result, &result) 4042 require.NoError(t, err) 4043 4044 if result != nil || tc.ExpectedResult != nil { 4045 var logs []ethTypes.Log 4046 err = json.Unmarshal(res.Result, &logs) 4047 require.NoError(t, err) 4048 assert.ElementsMatch(t, tc.ExpectedResult, logs) 4049 } 4050 } 4051 4052 if res.Error != nil || tc.ExpectedError != nil { 4053 assert.Equal(t, tc.ExpectedError.ErrorCode(), res.Error.Code) 4054 assert.Equal(t, tc.ExpectedError.Error(), res.Error.Message) 4055 } 4056 }) 4057 } 4058 } 4059 4060 func TestGetFilterChanges(t *testing.T) { 4061 s, m, _ := newSequencerMockedServer(t) 4062 defer s.Stop() 4063 4064 type testCase struct { 4065 Name string 4066 FilterID string 4067 ExpectedResults []interface{} 4068 ExpectedErrors []types.Error 4069 Prepare func(t *testing.T, tc *testCase) 4070 SetupMocks func(t *testing.T, m *mocksWrapper, tc testCase) 4071 } 4072 4073 var nilTx pgx.Tx 4074 testCases := []testCase{ 4075 { 4076 Name: "Get block filter changes multiple times successfully", 4077 Prepare: func(t *testing.T, tc *testCase) { 4078 tc.FilterID = "2" 4079 // first call 4080 tc.ExpectedResults = append(tc.ExpectedResults, []common.Hash{ 4081 common.HexToHash("0x111"), 4082 }) 4083 tc.ExpectedErrors = append(tc.ExpectedErrors, nil) 4084 4085 // second call 4086 tc.ExpectedResults = append(tc.ExpectedResults, []common.Hash{ 4087 common.HexToHash("0x222"), 4088 common.HexToHash("0x333"), 4089 }) 4090 tc.ExpectedErrors = append(tc.ExpectedErrors, nil) 4091 4092 // third call 4093 tc.ExpectedResults = append(tc.ExpectedResults, []common.Hash{}) 4094 tc.ExpectedErrors = append(tc.ExpectedErrors, nil) 4095 }, 4096 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 4097 filter := &Filter{ 4098 ID: tc.FilterID, 4099 Type: FilterTypeBlock, 4100 LastPoll: time.Now(), 4101 Parameters: "{}", 4102 } 4103 4104 m.Storage. 4105 On("GetFilter", tc.FilterID). 4106 Return(filter, nil). 4107 Once() 4108 4109 m.State. 4110 On("GetL2BlockHashesSince", context.Background(), filter.LastPoll, mock.IsType(nilTx)). 4111 Return(tc.ExpectedResults[0].([]common.Hash), nil). 4112 Once() 4113 4114 m.Storage. 4115 On("UpdateFilterLastPoll", tc.FilterID). 4116 Run(func(args mock.Arguments) { 4117 filter.LastPoll = time.Now() 4118 4119 m.Storage. 4120 On("GetFilter", tc.FilterID). 4121 Return(filter, nil). 4122 Once() 4123 4124 m.State. 4125 On("GetL2BlockHashesSince", context.Background(), filter.LastPoll, mock.IsType(nilTx)). 4126 Return(tc.ExpectedResults[1].([]common.Hash), nil). 4127 Once() 4128 4129 m.Storage. 4130 On("UpdateFilterLastPoll", tc.FilterID). 4131 Run(func(args mock.Arguments) { 4132 filter.LastPoll = time.Now() 4133 4134 m.Storage. 4135 On("GetFilter", tc.FilterID). 4136 Return(filter, nil). 4137 Once() 4138 4139 m.State. 4140 On("GetL2BlockHashesSince", context.Background(), filter.LastPoll, mock.IsType(nilTx)). 4141 Return(tc.ExpectedResults[2].([]common.Hash), nil). 4142 Once() 4143 4144 m.Storage. 4145 On("UpdateFilterLastPoll", tc.FilterID). 4146 Return(nil). 4147 Once() 4148 }). 4149 Return(nil). 4150 Once() 4151 }). 4152 Return(nil). 4153 Once() 4154 }, 4155 }, 4156 { 4157 Name: "Get pending transactions filter changes multiple times successfully", 4158 Prepare: func(t *testing.T, tc *testCase) { 4159 tc.FilterID = "3" 4160 // first call 4161 tc.ExpectedResults = append(tc.ExpectedResults, []common.Hash{ 4162 common.HexToHash("0x444"), 4163 }) 4164 tc.ExpectedErrors = append(tc.ExpectedErrors, nil) 4165 4166 // second call 4167 tc.ExpectedResults = append(tc.ExpectedResults, []common.Hash{ 4168 common.HexToHash("0x555"), 4169 common.HexToHash("0x666"), 4170 }) 4171 tc.ExpectedErrors = append(tc.ExpectedErrors, nil) 4172 4173 // third call 4174 tc.ExpectedResults = append(tc.ExpectedResults, []common.Hash{}) 4175 tc.ExpectedErrors = append(tc.ExpectedErrors, nil) 4176 }, 4177 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 4178 filter := &Filter{ 4179 ID: tc.FilterID, 4180 Type: FilterTypePendingTx, 4181 LastPoll: time.Now(), 4182 Parameters: "{}", 4183 } 4184 4185 m.Storage. 4186 On("GetFilter", tc.FilterID). 4187 Return(filter, nil). 4188 Once() 4189 4190 m.Pool. 4191 On("GetPendingTxHashesSince", context.Background(), filter.LastPoll). 4192 Return(tc.ExpectedResults[0].([]common.Hash), nil). 4193 Once() 4194 4195 m.Storage. 4196 On("UpdateFilterLastPoll", tc.FilterID). 4197 Run(func(args mock.Arguments) { 4198 filter.LastPoll = time.Now() 4199 4200 m.Storage. 4201 On("GetFilter", tc.FilterID). 4202 Return(filter, nil). 4203 Once() 4204 4205 m.Pool. 4206 On("GetPendingTxHashesSince", context.Background(), filter.LastPoll). 4207 Return(tc.ExpectedResults[1].([]common.Hash), nil). 4208 Once() 4209 4210 m.Storage. 4211 On("UpdateFilterLastPoll", tc.FilterID). 4212 Run(func(args mock.Arguments) { 4213 filter.LastPoll = time.Now() 4214 4215 m.Storage. 4216 On("GetFilter", tc.FilterID). 4217 Return(filter, nil). 4218 Once() 4219 4220 m.Pool. 4221 On("GetPendingTxHashesSince", context.Background(), filter.LastPoll). 4222 Return(tc.ExpectedResults[2].([]common.Hash), nil). 4223 Once() 4224 4225 m.Storage. 4226 On("UpdateFilterLastPoll", tc.FilterID). 4227 Return(nil). 4228 Once() 4229 }). 4230 Return(nil). 4231 Once() 4232 }). 4233 Return(nil). 4234 Once() 4235 }, 4236 }, 4237 { 4238 Name: "Get log filter changes multiple times successfully", 4239 Prepare: func(t *testing.T, tc *testCase) { 4240 tc.FilterID = "1" 4241 // first call 4242 tc.ExpectedResults = append(tc.ExpectedResults, []ethTypes.Log{{ 4243 Address: common.Address{}, Topics: []common.Hash{}, Data: []byte{}, 4244 BlockNumber: uint64(1), TxHash: common.Hash{}, TxIndex: uint(1), 4245 BlockHash: common.Hash{}, Index: uint(1), Removed: false, 4246 }}) 4247 tc.ExpectedErrors = append(tc.ExpectedErrors, nil) 4248 4249 // second call 4250 tc.ExpectedResults = append(tc.ExpectedResults, []ethTypes.Log{{ 4251 Address: common.Address{}, Topics: []common.Hash{}, Data: []byte{}, 4252 BlockNumber: uint64(1), TxHash: common.Hash{}, TxIndex: uint(1), 4253 BlockHash: common.Hash{}, Index: uint(1), Removed: false, 4254 }, { 4255 Address: common.Address{}, Topics: []common.Hash{}, Data: []byte{}, 4256 BlockNumber: uint64(1), TxHash: common.Hash{}, TxIndex: uint(1), 4257 BlockHash: common.Hash{}, Index: uint(1), Removed: false, 4258 }}) 4259 tc.ExpectedErrors = append(tc.ExpectedErrors, nil) 4260 4261 // third call 4262 tc.ExpectedResults = append(tc.ExpectedResults, nil) 4263 tc.ExpectedErrors = append(tc.ExpectedErrors, nil) 4264 }, 4265 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 4266 bn1 := types.BlockNumber(1) 4267 bn2 := types.BlockNumber(2) 4268 logFilter := LogFilter{ 4269 FromBlock: &bn1, ToBlock: &bn2, 4270 Addresses: []common.Address{common.HexToAddress("0x111")}, 4271 Topics: [][]common.Hash{{common.HexToHash("0x222")}}, 4272 } 4273 4274 filter := &Filter{ 4275 ID: tc.FilterID, 4276 Type: FilterTypeLog, 4277 LastPoll: time.Now(), 4278 Parameters: logFilter, 4279 } 4280 4281 m.Storage. 4282 On("GetFilter", tc.FilterID). 4283 Return(filter, nil). 4284 Once() 4285 4286 expectedLogs := tc.ExpectedResults[0].([]ethTypes.Log) 4287 logs := make([]*ethTypes.Log, 0, len(expectedLogs)) 4288 for _, log := range expectedLogs { 4289 l := log 4290 logs = append(logs, &l) 4291 } 4292 4293 m.State. 4294 On("GetLogs", context.Background(), uint64(*logFilter.FromBlock), uint64(*logFilter.ToBlock), logFilter.Addresses, logFilter.Topics, logFilter.BlockHash, &filter.LastPoll, mock.IsType(nilTx)). 4295 Return(logs, nil). 4296 Once() 4297 4298 m.Storage. 4299 On("UpdateFilterLastPoll", tc.FilterID). 4300 Run(func(args mock.Arguments) { 4301 filter.LastPoll = time.Now() 4302 4303 m.Storage. 4304 On("GetFilter", tc.FilterID). 4305 Return(filter, nil). 4306 Once() 4307 4308 expectedLogs = tc.ExpectedResults[1].([]ethTypes.Log) 4309 logs = make([]*ethTypes.Log, 0, len(expectedLogs)) 4310 for _, log := range expectedLogs { 4311 l := log 4312 logs = append(logs, &l) 4313 } 4314 4315 m.State. 4316 On("GetLogs", context.Background(), uint64(*logFilter.FromBlock), uint64(*logFilter.ToBlock), logFilter.Addresses, logFilter.Topics, logFilter.BlockHash, &filter.LastPoll, mock.IsType(nilTx)). 4317 Return(logs, nil). 4318 Once() 4319 4320 m.Storage. 4321 On("UpdateFilterLastPoll", tc.FilterID). 4322 Run(func(args mock.Arguments) { 4323 filter.LastPoll = time.Now() 4324 4325 m.Storage. 4326 On("GetFilter", tc.FilterID). 4327 Return(filter, nil). 4328 Once() 4329 4330 m.State. 4331 On("GetLogs", context.Background(), uint64(*logFilter.FromBlock), uint64(*logFilter.ToBlock), logFilter.Addresses, logFilter.Topics, logFilter.BlockHash, &filter.LastPoll, mock.IsType(nilTx)). 4332 Return([]*ethTypes.Log{}, nil). 4333 Once() 4334 4335 m.Storage. 4336 On("UpdateFilterLastPoll", tc.FilterID). 4337 Return(nil). 4338 Once() 4339 }). 4340 Return(nil). 4341 Once() 4342 }). 4343 Return(nil). 4344 Once() 4345 }, 4346 }, 4347 { 4348 Name: "Get filter changes when filter is not found", 4349 Prepare: func(t *testing.T, tc *testCase) { 4350 tc.FilterID = "1" 4351 // first call 4352 tc.ExpectedResults = append(tc.ExpectedResults, nil) 4353 tc.ExpectedErrors = append(tc.ExpectedErrors, types.NewRPCError(types.DefaultErrorCode, "filter not found")) 4354 }, 4355 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 4356 m.Storage. 4357 On("GetFilter", tc.FilterID). 4358 Return(nil, ErrNotFound). 4359 Once() 4360 }, 4361 }, 4362 { 4363 Name: "Get filter changes fails to get filter", 4364 Prepare: func(t *testing.T, tc *testCase) { 4365 tc.FilterID = "1" 4366 // first call 4367 tc.ExpectedResults = append(tc.ExpectedResults, nil) 4368 tc.ExpectedErrors = append(tc.ExpectedErrors, types.NewRPCError(types.DefaultErrorCode, "failed to get filter from storage")) 4369 }, 4370 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 4371 m.Storage. 4372 On("GetFilter", tc.FilterID). 4373 Return(nil, errors.New("failed to get filter")). 4374 Once() 4375 }, 4376 }, 4377 { 4378 Name: "Get block filter changes fails to get block hashes", 4379 Prepare: func(t *testing.T, tc *testCase) { 4380 tc.FilterID = "2" 4381 tc.ExpectedResults = append(tc.ExpectedResults, nil) 4382 tc.ExpectedErrors = append(tc.ExpectedErrors, types.NewRPCError(types.DefaultErrorCode, "failed to get block hashes")) 4383 }, 4384 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 4385 filter := &Filter{ 4386 ID: tc.FilterID, 4387 Type: FilterTypeBlock, 4388 LastPoll: time.Now(), 4389 Parameters: LogFilter{}, 4390 } 4391 4392 m.Storage. 4393 On("GetFilter", tc.FilterID). 4394 Return(filter, nil). 4395 Once() 4396 4397 m.State. 4398 On("GetL2BlockHashesSince", context.Background(), filter.LastPoll, mock.IsType(nilTx)). 4399 Return([]common.Hash{}, errors.New("failed to get hashes")). 4400 Once() 4401 }, 4402 }, 4403 { 4404 Name: "Get block filter changes fails to update the last time it was requested", 4405 Prepare: func(t *testing.T, tc *testCase) { 4406 tc.FilterID = "2" 4407 tc.ExpectedResults = append(tc.ExpectedResults, nil) 4408 tc.ExpectedErrors = append(tc.ExpectedErrors, types.NewRPCError(types.DefaultErrorCode, "failed to update last time the filter changes were requested")) 4409 }, 4410 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 4411 filter := &Filter{ 4412 ID: tc.FilterID, 4413 Type: FilterTypeBlock, 4414 LastPoll: time.Now(), 4415 Parameters: LogFilter{}, 4416 } 4417 4418 m.Storage. 4419 On("GetFilter", tc.FilterID). 4420 Return(filter, nil). 4421 Once() 4422 4423 m.State. 4424 On("GetL2BlockHashesSince", context.Background(), filter.LastPoll, mock.IsType(nilTx)). 4425 Return([]common.Hash{}, nil). 4426 Once() 4427 4428 m.Storage. 4429 On("UpdateFilterLastPoll", tc.FilterID). 4430 Return(errors.New("failed to update filter last poll")). 4431 Once() 4432 }, 4433 }, 4434 { 4435 Name: "Get pending transactions filter fails to get the hashes", 4436 Prepare: func(t *testing.T, tc *testCase) { 4437 tc.FilterID = "3" 4438 tc.ExpectedResults = append(tc.ExpectedResults, nil) 4439 tc.ExpectedErrors = append(tc.ExpectedErrors, types.NewRPCError(types.DefaultErrorCode, "failed to get pending transaction hashes")) 4440 }, 4441 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 4442 filter := &Filter{ 4443 ID: tc.FilterID, 4444 Type: FilterTypePendingTx, 4445 LastPoll: time.Now(), 4446 Parameters: LogFilter{}, 4447 } 4448 4449 m.Storage. 4450 On("GetFilter", tc.FilterID). 4451 Return(filter, nil). 4452 Once() 4453 4454 m.Pool. 4455 On("GetPendingTxHashesSince", context.Background(), filter.LastPoll). 4456 Return([]common.Hash{}, errors.New("failed to get pending tx hashes")). 4457 Once() 4458 }, 4459 }, 4460 { 4461 Name: "Get pending transactions fails to update the last time it was requested", 4462 Prepare: func(t *testing.T, tc *testCase) { 4463 tc.FilterID = "3" 4464 tc.ExpectedResults = append(tc.ExpectedResults, nil) 4465 tc.ExpectedErrors = append(tc.ExpectedErrors, types.NewRPCError(types.DefaultErrorCode, "failed to update last time the filter changes were requested")) 4466 }, 4467 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 4468 filter := &Filter{ 4469 ID: tc.FilterID, 4470 Type: FilterTypePendingTx, 4471 LastPoll: time.Now(), 4472 Parameters: LogFilter{}, 4473 } 4474 4475 m.Storage. 4476 On("GetFilter", tc.FilterID). 4477 Return(filter, nil). 4478 Once() 4479 4480 m.Pool. 4481 On("GetPendingTxHashesSince", context.Background(), filter.LastPoll). 4482 Return([]common.Hash{}, nil). 4483 Once() 4484 4485 m.Storage. 4486 On("UpdateFilterLastPoll", tc.FilterID). 4487 Return(errors.New("failed to update filter last poll")). 4488 Once() 4489 }, 4490 }, 4491 { 4492 Name: "Get log filter changes fails to get logs", 4493 Prepare: func(t *testing.T, tc *testCase) { 4494 tc.FilterID = "1" 4495 tc.ExpectedResults = append(tc.ExpectedResults, nil) 4496 tc.ExpectedErrors = append(tc.ExpectedErrors, types.NewRPCError(types.DefaultErrorCode, "failed to get logs from state")) 4497 }, 4498 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 4499 bn1 := types.BlockNumber(1) 4500 bn2 := types.BlockNumber(2) 4501 logFilter := LogFilter{ 4502 4503 FromBlock: &bn1, ToBlock: &bn2, 4504 Addresses: []common.Address{common.HexToAddress("0x111")}, 4505 Topics: [][]common.Hash{{common.HexToHash("0x222")}}, 4506 } 4507 4508 filter := &Filter{ 4509 ID: tc.FilterID, 4510 Type: FilterTypeLog, 4511 LastPoll: time.Now(), 4512 Parameters: logFilter, 4513 } 4514 4515 m.Storage. 4516 On("GetFilter", tc.FilterID). 4517 Return(filter, nil). 4518 Once() 4519 4520 m.State. 4521 On("GetLogs", context.Background(), uint64(*logFilter.FromBlock), uint64(*logFilter.ToBlock), logFilter.Addresses, logFilter.Topics, logFilter.BlockHash, &filter.LastPoll, mock.IsType(nilTx)). 4522 Return(nil, errors.New("failed to get logs")). 4523 Once() 4524 }, 4525 }, 4526 { 4527 Name: "Get log filter changes fails to update the last time it was requested", 4528 Prepare: func(t *testing.T, tc *testCase) { 4529 tc.FilterID = "1" 4530 tc.ExpectedResults = append(tc.ExpectedResults, nil) 4531 tc.ExpectedErrors = append(tc.ExpectedErrors, types.NewRPCError(types.DefaultErrorCode, "failed to update last time the filter changes were requested")) 4532 }, 4533 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 4534 bn1 := types.BlockNumber(1) 4535 bn2 := types.BlockNumber(2) 4536 logFilter := LogFilter{ 4537 FromBlock: &bn1, ToBlock: &bn2, 4538 Addresses: []common.Address{common.HexToAddress("0x111")}, 4539 Topics: [][]common.Hash{{common.HexToHash("0x222")}}, 4540 } 4541 4542 filter := &Filter{ 4543 ID: tc.FilterID, 4544 Type: FilterTypeLog, 4545 LastPoll: time.Now(), 4546 Parameters: logFilter, 4547 } 4548 4549 m.Storage. 4550 On("GetFilter", tc.FilterID). 4551 Return(filter, nil). 4552 Once() 4553 4554 m.State. 4555 On("GetLogs", context.Background(), uint64(*logFilter.FromBlock), uint64(*logFilter.ToBlock), logFilter.Addresses, logFilter.Topics, logFilter.BlockHash, &filter.LastPoll, mock.IsType(nilTx)). 4556 Return([]*ethTypes.Log{}, nil). 4557 Once() 4558 4559 m.Storage. 4560 On("UpdateFilterLastPoll", tc.FilterID). 4561 Return(errors.New("failed to update filter last poll")). 4562 Once() 4563 }, 4564 }, 4565 { 4566 Name: "Get filter changes for a unknown log type", 4567 Prepare: func(t *testing.T, tc *testCase) { 4568 tc.FilterID = "4" 4569 tc.ExpectedResults = append(tc.ExpectedResults, nil) 4570 tc.ExpectedErrors = append(tc.ExpectedErrors, nil) 4571 }, 4572 SetupMocks: func(t *testing.T, m *mocksWrapper, tc testCase) { 4573 filter := &Filter{ 4574 Type: "unknown type", 4575 } 4576 4577 m.Storage. 4578 On("GetFilter", tc.FilterID). 4579 Return(filter, nil). 4580 Once() 4581 }, 4582 }, 4583 } 4584 4585 for _, testCase := range testCases { 4586 t.Run(testCase.Name, func(t *testing.T) { 4587 tc := testCase 4588 tc.Prepare(t, &tc) 4589 tc.SetupMocks(t, m, tc) 4590 4591 timesToCall := len(tc.ExpectedResults) 4592 4593 for i := 0; i < timesToCall; i++ { 4594 res, err := s.JSONRPCCall("eth_getFilterChanges", tc.FilterID) 4595 require.NoError(t, err) 4596 assert.Equal(t, float64(1), res.ID) 4597 assert.Equal(t, "2.0", res.JSONRPC) 4598 4599 if res.Result != nil { 4600 var result interface{} 4601 err = json.Unmarshal(res.Result, &result) 4602 require.NoError(t, err) 4603 4604 if result != nil || tc.ExpectedResults[i] != nil { 4605 if logs, ok := tc.ExpectedResults[i].([]ethTypes.Log); ok { 4606 err = json.Unmarshal(res.Result, &logs) 4607 require.NoError(t, err) 4608 assert.ElementsMatch(t, tc.ExpectedResults[i], logs) 4609 } 4610 if hashes, ok := tc.ExpectedResults[i].([]common.Hash); ok { 4611 err = json.Unmarshal(res.Result, &hashes) 4612 require.NoError(t, err) 4613 assert.ElementsMatch(t, tc.ExpectedResults[i], hashes) 4614 } 4615 } 4616 } 4617 4618 if res.Error != nil || tc.ExpectedErrors[i] != nil { 4619 assert.Equal(t, tc.ExpectedErrors[i].ErrorCode(), res.Error.Code) 4620 assert.Equal(t, tc.ExpectedErrors[i].Error(), res.Error.Message) 4621 } 4622 } 4623 }) 4624 } 4625 }