github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/jsonrpc/endpoints_eth.go (about) 1 package jsonrpc 2 3 import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "math/big" 9 "net/http" 10 "strings" 11 12 "github.com/0xPolygon/supernets2-node/hex" 13 "github.com/0xPolygon/supernets2-node/jsonrpc/client" 14 "github.com/0xPolygon/supernets2-node/jsonrpc/types" 15 "github.com/0xPolygon/supernets2-node/log" 16 "github.com/0xPolygon/supernets2-node/pool" 17 "github.com/0xPolygon/supernets2-node/state" 18 "github.com/0xPolygon/supernets2-node/state/runtime" 19 "github.com/ethereum/go-ethereum/common" 20 ethTypes "github.com/ethereum/go-ethereum/core/types" 21 "github.com/gorilla/websocket" 22 "github.com/jackc/pgx/v4" 23 ) 24 25 const ( 26 // DefaultSenderAddress is the address that jRPC will use 27 // to communicate with the state for eth_EstimateGas and eth_Call when 28 // the From field is not specified because it is optional 29 DefaultSenderAddress = "0x1111111111111111111111111111111111111111" 30 ) 31 32 // EthEndpoints contains implementations for the "eth" RPC endpoints 33 type EthEndpoints struct { 34 cfg Config 35 chainID uint64 36 pool types.PoolInterface 37 state types.StateInterface 38 storage storageInterface 39 txMan DBTxManager 40 } 41 42 // NewEthEndpoints creates an new instance of Eth 43 func NewEthEndpoints(cfg Config, chainID uint64, p types.PoolInterface, s types.StateInterface, storage storageInterface) *EthEndpoints { 44 e := &EthEndpoints{cfg: cfg, chainID: chainID, pool: p, state: s, storage: storage} 45 s.RegisterNewL2BlockEventHandler(e.onNewL2Block) 46 47 return e 48 } 49 50 // BlockNumber returns current block number 51 func (e *EthEndpoints) BlockNumber() (interface{}, types.Error) { 52 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 53 lastBlockNumber, err := e.state.GetLastL2BlockNumber(ctx, dbTx) 54 if err != nil { 55 return "0x0", types.NewRPCError(types.DefaultErrorCode, "failed to get the last block number from state") 56 } 57 58 return hex.EncodeUint64(lastBlockNumber), nil 59 }) 60 } 61 62 // Call executes a new message call immediately and returns the value of 63 // executed contract and potential error. 64 // Note, this function doesn't make any changes in the state/blockchain and is 65 // useful to execute view/pure methods and retrieve values. 66 func (e *EthEndpoints) Call(arg *types.TxArgs, blockArg *types.BlockNumberOrHash) (interface{}, types.Error) { 67 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 68 if arg == nil { 69 return RPCErrorResponse(types.InvalidParamsErrorCode, "missing value for required argument 0", nil) 70 } else if blockArg == nil { 71 return RPCErrorResponse(types.InvalidParamsErrorCode, "missing value for required argument 1", nil) 72 } 73 block, respErr := e.getBlockByArg(ctx, blockArg, dbTx) 74 if respErr != nil { 75 return nil, respErr 76 } 77 var blockToProcess *uint64 78 if blockArg != nil { 79 blockNumArg := blockArg.Number() 80 if blockNumArg != nil && (*blockArg.Number() == types.LatestBlockNumber || *blockArg.Number() == types.PendingBlockNumber) { 81 blockToProcess = nil 82 } else { 83 n := block.NumberU64() 84 blockToProcess = &n 85 } 86 } 87 88 // If the caller didn't supply the gas limit in the message, then we set it to maximum possible => block gas limit 89 if arg.Gas == nil || uint64(*arg.Gas) <= 0 { 90 header, err := e.state.GetL2BlockHeaderByNumber(ctx, block.NumberU64(), dbTx) 91 if err != nil { 92 return RPCErrorResponse(types.DefaultErrorCode, "failed to get block header", err) 93 } 94 95 gas := types.ArgUint64(header.GasLimit) 96 arg.Gas = &gas 97 } 98 99 defaultSenderAddress := common.HexToAddress(DefaultSenderAddress) 100 sender, tx, err := arg.ToTransaction(ctx, e.state, e.cfg.MaxCumulativeGasUsed, block.Root(), defaultSenderAddress, dbTx) 101 if err != nil { 102 return RPCErrorResponse(types.DefaultErrorCode, "failed to convert arguments into an unsigned transaction", err) 103 } 104 105 result, err := e.state.ProcessUnsignedTransaction(ctx, tx, sender, blockToProcess, true, dbTx) 106 if err != nil { 107 return RPCErrorResponse(types.DefaultErrorCode, "failed to execute the unsigned transaction", err) 108 } 109 110 if result.Reverted() { 111 data := make([]byte, len(result.ReturnValue)) 112 copy(data, result.ReturnValue) 113 return nil, types.NewRPCErrorWithData(types.RevertedErrorCode, result.Err.Error(), &data) 114 } else if result.Failed() { 115 return nil, types.NewRPCErrorWithData(types.DefaultErrorCode, result.Err.Error(), nil) 116 } 117 118 return types.ArgBytesPtr(result.ReturnValue), nil 119 }) 120 } 121 122 // ChainId returns the chain id of the client 123 func (e *EthEndpoints) ChainId() (interface{}, types.Error) { //nolint:revive 124 return hex.EncodeUint64(e.chainID), nil 125 } 126 127 // EstimateGas generates and returns an estimate of how much gas is necessary to 128 // allow the transaction to complete. 129 // The transaction will not be added to the blockchain. 130 // Note that the estimate may be significantly more than the amount of gas actually 131 // used by the transaction, for a variety of reasons including EVM mechanics and 132 // node performance. 133 func (e *EthEndpoints) EstimateGas(arg *types.TxArgs, blockArg *types.BlockNumberOrHash) (interface{}, types.Error) { 134 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 135 if arg == nil { 136 return RPCErrorResponse(types.InvalidParamsErrorCode, "missing value for required argument 0", nil) 137 } 138 139 block, respErr := e.getBlockByArg(ctx, blockArg, dbTx) 140 if respErr != nil { 141 return nil, respErr 142 } 143 144 var blockToProcess *uint64 145 if blockArg != nil { 146 blockNumArg := blockArg.Number() 147 if blockNumArg != nil && (*blockArg.Number() == types.LatestBlockNumber || *blockArg.Number() == types.PendingBlockNumber) { 148 blockToProcess = nil 149 } else { 150 n := block.NumberU64() 151 blockToProcess = &n 152 } 153 } 154 155 defaultSenderAddress := common.HexToAddress(DefaultSenderAddress) 156 sender, tx, err := arg.ToTransaction(ctx, e.state, e.cfg.MaxCumulativeGasUsed, block.Root(), defaultSenderAddress, dbTx) 157 if err != nil { 158 return RPCErrorResponse(types.DefaultErrorCode, "failed to convert arguments into an unsigned transaction", err) 159 } 160 161 gasEstimation, returnValue, err := e.state.EstimateGas(tx, sender, blockToProcess, dbTx) 162 if errors.Is(err, runtime.ErrExecutionReverted) { 163 data := make([]byte, len(returnValue)) 164 copy(data, returnValue) 165 return nil, types.NewRPCErrorWithData(types.RevertedErrorCode, err.Error(), &data) 166 } else if err != nil { 167 return nil, types.NewRPCErrorWithData(types.DefaultErrorCode, err.Error(), nil) 168 } 169 if err != nil { 170 return RPCErrorResponse(types.DefaultErrorCode, err.Error(), nil) 171 } 172 return hex.EncodeUint64(gasEstimation), nil 173 }) 174 } 175 176 // GasPrice returns the average gas price based on the last x blocks 177 func (e *EthEndpoints) GasPrice() (interface{}, types.Error) { 178 ctx := context.Background() 179 if e.cfg.SequencerNodeURI != "" { 180 return e.getPriceFromSequencerNode() 181 } 182 gasPrice, err := e.pool.GetGasPrice(ctx) 183 if err != nil { 184 return "0x0", nil 185 } 186 return hex.EncodeUint64(gasPrice), nil 187 } 188 189 func (e *EthEndpoints) getPriceFromSequencerNode() (interface{}, types.Error) { 190 res, err := client.JSONRPCCall(e.cfg.SequencerNodeURI, "eth_gasPrice") 191 if err != nil { 192 return RPCErrorResponse(types.DefaultErrorCode, "failed to get gas price from sequencer node", err) 193 } 194 195 if res.Error != nil { 196 return RPCErrorResponse(res.Error.Code, res.Error.Message, nil) 197 } 198 199 var gasPrice types.ArgUint64 200 err = json.Unmarshal(res.Result, &gasPrice) 201 if err != nil { 202 return RPCErrorResponse(types.DefaultErrorCode, "failed to read gas price from sequencer node", err) 203 } 204 return gasPrice, nil 205 } 206 207 // GetBalance returns the account's balance at the referenced block 208 func (e *EthEndpoints) GetBalance(address types.ArgAddress, blockArg *types.BlockNumberOrHash) (interface{}, types.Error) { 209 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 210 block, rpcErr := e.getBlockByArg(ctx, blockArg, dbTx) 211 if rpcErr != nil { 212 return nil, rpcErr 213 } 214 215 balance, err := e.state.GetBalance(ctx, address.Address(), block.Root()) 216 if errors.Is(err, state.ErrNotFound) { 217 return hex.EncodeUint64(0), nil 218 } else if err != nil { 219 return RPCErrorResponse(types.DefaultErrorCode, "failed to get balance from state", err) 220 } 221 222 return hex.EncodeBig(balance), nil 223 }) 224 } 225 226 func (e *EthEndpoints) getBlockByArg(ctx context.Context, blockArg *types.BlockNumberOrHash, dbTx pgx.Tx) (*ethTypes.Block, types.Error) { 227 // If no block argument is provided, return the latest block 228 if blockArg == nil { 229 block, err := e.state.GetLastL2Block(ctx, dbTx) 230 if err != nil { 231 return nil, types.NewRPCError(types.DefaultErrorCode, "failed to get the last block number from state") 232 } 233 return block, nil 234 } 235 236 // If we have a block hash, try to get the block by hash 237 if blockArg.IsHash() { 238 block, err := e.state.GetL2BlockByHash(ctx, blockArg.Hash().Hash(), dbTx) 239 if errors.Is(err, state.ErrNotFound) { 240 return nil, types.NewRPCError(types.DefaultErrorCode, "header for hash not found") 241 } else if err != nil { 242 return nil, types.NewRPCError(types.DefaultErrorCode, fmt.Sprintf("failed to get block by hash %v", blockArg.Hash().Hash())) 243 } 244 return block, nil 245 } 246 247 // Otherwise, try to get the block by number 248 blockNum, rpcErr := blockArg.Number().GetNumericBlockNumber(ctx, e.state, dbTx) 249 if rpcErr != nil { 250 return nil, rpcErr 251 } 252 block, err := e.state.GetL2BlockByNumber(context.Background(), blockNum, dbTx) 253 if errors.Is(err, state.ErrNotFound) || block == nil { 254 return nil, types.NewRPCError(types.DefaultErrorCode, "header not found") 255 } else if err != nil { 256 return nil, types.NewRPCError(types.DefaultErrorCode, fmt.Sprintf("failed to get block by number %v", blockNum)) 257 } 258 259 return block, nil 260 } 261 262 // GetBlockByHash returns information about a block by hash 263 func (e *EthEndpoints) GetBlockByHash(hash types.ArgHash, fullTx bool) (interface{}, types.Error) { 264 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 265 block, err := e.state.GetL2BlockByHash(ctx, hash.Hash(), dbTx) 266 if errors.Is(err, state.ErrNotFound) { 267 return nil, nil 268 } else if err != nil { 269 return RPCErrorResponse(types.DefaultErrorCode, "failed to get block by hash from state", err) 270 } 271 272 rpcBlock := types.NewBlock(block, fullTx) 273 274 return rpcBlock, nil 275 }) 276 } 277 278 // GetBlockByNumber returns information about a block by block number 279 func (e *EthEndpoints) GetBlockByNumber(number types.BlockNumber, fullTx bool) (interface{}, types.Error) { 280 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 281 if number == types.PendingBlockNumber { 282 lastBlock, err := e.state.GetLastL2Block(ctx, dbTx) 283 if err != nil { 284 return RPCErrorResponse(types.DefaultErrorCode, "couldn't load last block from state to compute the pending block", err) 285 } 286 header := ethTypes.CopyHeader(lastBlock.Header()) 287 header.ParentHash = lastBlock.Hash() 288 header.Number = big.NewInt(0).SetUint64(lastBlock.Number().Uint64() + 1) 289 header.TxHash = ethTypes.EmptyRootHash 290 header.UncleHash = ethTypes.EmptyUncleHash 291 block := ethTypes.NewBlockWithHeader(header) 292 rpcBlock := types.NewBlock(block, fullTx) 293 294 return rpcBlock, nil 295 } 296 var err error 297 blockNumber, rpcErr := number.GetNumericBlockNumber(ctx, e.state, dbTx) 298 if rpcErr != nil { 299 return nil, rpcErr 300 } 301 302 block, err := e.state.GetL2BlockByNumber(ctx, blockNumber, dbTx) 303 if errors.Is(err, state.ErrNotFound) { 304 return nil, nil 305 } else if err != nil { 306 return RPCErrorResponse(types.DefaultErrorCode, fmt.Sprintf("couldn't load block from state by number %v", blockNumber), err) 307 } 308 309 rpcBlock := types.NewBlock(block, fullTx) 310 311 return rpcBlock, nil 312 }) 313 } 314 315 // GetCode returns account code at given block number 316 func (e *EthEndpoints) GetCode(address types.ArgAddress, blockArg *types.BlockNumberOrHash) (interface{}, types.Error) { 317 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 318 var err error 319 block, rpcErr := e.getBlockByArg(ctx, blockArg, dbTx) 320 if rpcErr != nil { 321 return nil, rpcErr 322 } 323 324 code, err := e.state.GetCode(ctx, address.Address(), block.Root()) 325 if errors.Is(err, state.ErrNotFound) { 326 return "0x", nil 327 } else if err != nil { 328 return RPCErrorResponse(types.DefaultErrorCode, "failed to get code", err) 329 } 330 331 return types.ArgBytes(code), nil 332 }) 333 } 334 335 // GetCompilers eth_getCompilers 336 func (e *EthEndpoints) GetCompilers() (interface{}, types.Error) { 337 return []interface{}{}, nil 338 } 339 340 // GetFilterChanges polling method for a filter, which returns 341 // an array of logs which occurred since last poll. 342 func (e *EthEndpoints) GetFilterChanges(filterID string) (interface{}, types.Error) { 343 filter, err := e.storage.GetFilter(filterID) 344 if errors.Is(err, ErrNotFound) { 345 return RPCErrorResponse(types.DefaultErrorCode, "filter not found", err) 346 } else if err != nil { 347 return RPCErrorResponse(types.DefaultErrorCode, "failed to get filter from storage", err) 348 } 349 350 switch filter.Type { 351 case FilterTypeBlock: 352 { 353 res, err := e.state.GetL2BlockHashesSince(context.Background(), filter.LastPoll, nil) 354 if err != nil { 355 return RPCErrorResponse(types.DefaultErrorCode, "failed to get block hashes", err) 356 } 357 rpcErr := e.updateFilterLastPoll(filter.ID) 358 if rpcErr != nil { 359 return nil, rpcErr 360 } 361 if len(res) == 0 { 362 return nil, nil 363 } 364 return res, nil 365 } 366 case FilterTypePendingTx: 367 { 368 res, err := e.pool.GetPendingTxHashesSince(context.Background(), filter.LastPoll) 369 if err != nil { 370 return RPCErrorResponse(types.DefaultErrorCode, "failed to get pending transaction hashes", err) 371 } 372 rpcErr := e.updateFilterLastPoll(filter.ID) 373 if rpcErr != nil { 374 return nil, rpcErr 375 } 376 if len(res) == 0 { 377 return nil, nil 378 } 379 return res, nil 380 } 381 case FilterTypeLog: 382 { 383 filterParameters := filter.Parameters.(LogFilter) 384 filterParameters.Since = &filter.LastPoll 385 386 resInterface, err := e.internalGetLogs(context.Background(), nil, filterParameters) 387 if err != nil { 388 return nil, err 389 } 390 rpcErr := e.updateFilterLastPoll(filter.ID) 391 if rpcErr != nil { 392 return nil, rpcErr 393 } 394 res := resInterface.([]types.Log) 395 if len(res) == 0 { 396 return nil, nil 397 } 398 return res, nil 399 } 400 default: 401 return nil, nil 402 } 403 } 404 405 // GetFilterLogs returns an array of all logs matching filter 406 // with given id. 407 func (e *EthEndpoints) GetFilterLogs(filterID string) (interface{}, types.Error) { 408 filter, err := e.storage.GetFilter(filterID) 409 if errors.Is(err, ErrNotFound) { 410 return nil, nil 411 } else if err != nil { 412 return RPCErrorResponse(types.DefaultErrorCode, "failed to get filter from storage", err) 413 } 414 415 if filter.Type != FilterTypeLog { 416 return nil, nil 417 } 418 419 filterParameters := filter.Parameters.(LogFilter) 420 filterParameters.Since = nil 421 422 return e.GetLogs(filterParameters) 423 } 424 425 // GetLogs returns a list of logs accordingly to the provided filter 426 func (e *EthEndpoints) GetLogs(filter LogFilter) (interface{}, types.Error) { 427 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 428 return e.internalGetLogs(ctx, dbTx, filter) 429 }) 430 } 431 432 func (e *EthEndpoints) internalGetLogs(ctx context.Context, dbTx pgx.Tx, filter LogFilter) (interface{}, types.Error) { 433 var err error 434 var fromBlock uint64 = 0 435 if filter.FromBlock != nil { 436 var rpcErr types.Error 437 fromBlock, rpcErr = filter.FromBlock.GetNumericBlockNumber(ctx, e.state, dbTx) 438 if rpcErr != nil { 439 return nil, rpcErr 440 } 441 } 442 443 toBlock, rpcErr := filter.ToBlock.GetNumericBlockNumber(ctx, e.state, dbTx) 444 if rpcErr != nil { 445 return nil, rpcErr 446 } 447 448 logs, err := e.state.GetLogs(ctx, fromBlock, toBlock, filter.Addresses, filter.Topics, filter.BlockHash, filter.Since, dbTx) 449 if err != nil { 450 return RPCErrorResponse(types.DefaultErrorCode, "failed to get logs from state", err) 451 } 452 453 result := make([]types.Log, 0, len(logs)) 454 for _, l := range logs { 455 result = append(result, types.NewLog(*l)) 456 } 457 458 return result, nil 459 } 460 461 // GetStorageAt gets the value stored for an specific address and position 462 func (e *EthEndpoints) GetStorageAt(address types.ArgAddress, storageKeyStr string, blockArg *types.BlockNumberOrHash) (interface{}, types.Error) { 463 storageKey := types.ArgHash{} 464 err := storageKey.UnmarshalText([]byte(storageKeyStr)) 465 if err != nil { 466 return RPCErrorResponse(types.DefaultErrorCode, "unable to decode storage key: hex string invalid", nil) 467 } 468 469 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 470 block, respErr := e.getBlockByArg(ctx, blockArg, dbTx) 471 if respErr != nil { 472 return nil, respErr 473 } 474 475 value, err := e.state.GetStorageAt(ctx, address.Address(), storageKey.Hash().Big(), block.Root()) 476 if errors.Is(err, state.ErrNotFound) { 477 return types.ArgBytesPtr(common.Hash{}.Bytes()), nil 478 } else if err != nil { 479 return RPCErrorResponse(types.DefaultErrorCode, "failed to get storage value from state", err) 480 } 481 482 return types.ArgBytesPtr(common.BigToHash(value).Bytes()), nil 483 }) 484 } 485 486 // GetTransactionByBlockHashAndIndex returns information about a transaction by 487 // block hash and transaction index position. 488 func (e *EthEndpoints) GetTransactionByBlockHashAndIndex(hash types.ArgHash, index types.Index) (interface{}, types.Error) { 489 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 490 tx, err := e.state.GetTransactionByL2BlockHashAndIndex(ctx, hash.Hash(), uint64(index), dbTx) 491 if errors.Is(err, state.ErrNotFound) { 492 return nil, nil 493 } else if err != nil { 494 return RPCErrorResponse(types.DefaultErrorCode, "failed to get transaction", err) 495 } 496 497 receipt, err := e.state.GetTransactionReceipt(ctx, tx.Hash(), dbTx) 498 if errors.Is(err, state.ErrNotFound) { 499 return nil, nil 500 } else if err != nil { 501 return RPCErrorResponse(types.DefaultErrorCode, "failed to get transaction receipt", err) 502 } 503 504 txIndex := uint64(receipt.TransactionIndex) 505 return types.NewTransaction(*tx, receipt.BlockNumber, &receipt.BlockHash, &txIndex), nil 506 }) 507 } 508 509 // GetTransactionByBlockNumberAndIndex returns information about a transaction by 510 // block number and transaction index position. 511 func (e *EthEndpoints) GetTransactionByBlockNumberAndIndex(number *types.BlockNumber, index types.Index) (interface{}, types.Error) { 512 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 513 var err error 514 blockNumber, rpcErr := number.GetNumericBlockNumber(ctx, e.state, dbTx) 515 if rpcErr != nil { 516 return nil, rpcErr 517 } 518 519 tx, err := e.state.GetTransactionByL2BlockNumberAndIndex(ctx, blockNumber, uint64(index), dbTx) 520 if errors.Is(err, state.ErrNotFound) { 521 return nil, nil 522 } else if err != nil { 523 return RPCErrorResponse(types.DefaultErrorCode, "failed to get transaction", err) 524 } 525 526 receipt, err := e.state.GetTransactionReceipt(ctx, tx.Hash(), dbTx) 527 if errors.Is(err, state.ErrNotFound) { 528 return nil, nil 529 } else if err != nil { 530 return RPCErrorResponse(types.DefaultErrorCode, "failed to get transaction receipt", err) 531 } 532 533 txIndex := uint64(receipt.TransactionIndex) 534 return types.NewTransaction(*tx, receipt.BlockNumber, &receipt.BlockHash, &txIndex), nil 535 }) 536 } 537 538 // GetTransactionByHash returns a transaction by his hash 539 func (e *EthEndpoints) GetTransactionByHash(hash types.ArgHash) (interface{}, types.Error) { 540 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 541 // try to get tx from state 542 tx, err := e.state.GetTransactionByHash(ctx, hash.Hash(), dbTx) 543 if err != nil && !errors.Is(err, state.ErrNotFound) { 544 return RPCErrorResponse(types.DefaultErrorCode, "failed to load transaction by hash from state", err) 545 } 546 if tx != nil { 547 receipt, err := e.state.GetTransactionReceipt(ctx, hash.Hash(), dbTx) 548 if errors.Is(err, state.ErrNotFound) { 549 return RPCErrorResponse(types.DefaultErrorCode, "transaction receipt not found", err) 550 } else if err != nil { 551 return RPCErrorResponse(types.DefaultErrorCode, "failed to load transaction receipt from state", err) 552 } 553 554 txIndex := uint64(receipt.TransactionIndex) 555 return types.NewTransaction(*tx, receipt.BlockNumber, &receipt.BlockHash, &txIndex), nil 556 } 557 558 // if the tx does not exist in the state, look for it in the pool 559 if e.cfg.SequencerNodeURI != "" { 560 return e.getTransactionByHashFromSequencerNode(hash.Hash()) 561 } 562 poolTx, err := e.pool.GetTxByHash(ctx, hash.Hash()) 563 if errors.Is(err, pool.ErrNotFound) { 564 return nil, nil 565 } else if err != nil { 566 return RPCErrorResponse(types.DefaultErrorCode, "failed to load transaction by hash from pool", err) 567 } 568 tx = &poolTx.Transaction 569 570 return types.NewTransaction(*tx, nil, nil, nil), nil 571 }) 572 } 573 574 func (e *EthEndpoints) getTransactionByHashFromSequencerNode(hash common.Hash) (interface{}, types.Error) { 575 res, err := client.JSONRPCCall(e.cfg.SequencerNodeURI, "eth_getTransactionByHash", hash.String()) 576 if err != nil { 577 return RPCErrorResponse(types.DefaultErrorCode, "failed to get tx from sequencer node", err) 578 } 579 580 if res.Error != nil { 581 return RPCErrorResponse(res.Error.Code, res.Error.Message, nil) 582 } 583 584 var tx *types.Transaction 585 err = json.Unmarshal(res.Result, &tx) 586 if err != nil { 587 return RPCErrorResponse(types.DefaultErrorCode, "failed to read tx from sequencer node", err) 588 } 589 return tx, nil 590 } 591 592 // GetTransactionCount returns account nonce 593 func (e *EthEndpoints) GetTransactionCount(address types.ArgAddress, blockArg *types.BlockNumberOrHash) (interface{}, types.Error) { 594 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 595 var ( 596 pendingNonce uint64 597 nonce uint64 598 err error 599 ) 600 601 block, respErr := e.getBlockByArg(ctx, blockArg, dbTx) 602 if respErr != nil { 603 return nil, respErr 604 } 605 606 if blockArg != nil { 607 blockNumArg := blockArg.Number() 608 if blockNumArg != nil && *blockNumArg == types.PendingBlockNumber { 609 if e.cfg.SequencerNodeURI != "" { 610 return e.getTransactionCountFromSequencerNode(address.Address(), blockArg.Number()) 611 } 612 pendingNonce, err = e.pool.GetNonce(ctx, address.Address()) 613 if err != nil { 614 return RPCErrorResponse(types.DefaultErrorCode, "failed to count pending transactions", err) 615 } 616 } 617 } 618 619 nonce, err = e.state.GetNonce(ctx, address.Address(), block.Root()) 620 621 if errors.Is(err, state.ErrNotFound) { 622 return hex.EncodeUint64(0), nil 623 } else if err != nil { 624 return RPCErrorResponse(types.DefaultErrorCode, "failed to count transactions", err) 625 } 626 627 if pendingNonce > nonce { 628 nonce = pendingNonce 629 } 630 631 return hex.EncodeUint64(nonce), nil 632 }) 633 } 634 635 func (e *EthEndpoints) getTransactionCountFromSequencerNode(address common.Address, number *types.BlockNumber) (interface{}, types.Error) { 636 res, err := client.JSONRPCCall(e.cfg.SequencerNodeURI, "eth_getTransactionCount", address.String(), number.StringOrHex()) 637 if err != nil { 638 return RPCErrorResponse(types.DefaultErrorCode, "failed to get nonce from sequencer node", err) 639 } 640 641 if res.Error != nil { 642 return RPCErrorResponse(res.Error.Code, res.Error.Message, nil) 643 } 644 645 var nonce types.ArgUint64 646 err = json.Unmarshal(res.Result, &nonce) 647 if err != nil { 648 return RPCErrorResponse(types.DefaultErrorCode, "failed to read nonce from sequencer node", err) 649 } 650 return nonce, nil 651 } 652 653 // GetBlockTransactionCountByHash returns the number of transactions in a 654 // block from a block matching the given block hash. 655 func (e *EthEndpoints) GetBlockTransactionCountByHash(hash types.ArgHash) (interface{}, types.Error) { 656 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 657 c, err := e.state.GetL2BlockTransactionCountByHash(ctx, hash.Hash(), dbTx) 658 if err != nil { 659 return RPCErrorResponse(types.DefaultErrorCode, "failed to count transactions", err) 660 } 661 662 return types.ArgUint64(c), nil 663 }) 664 } 665 666 // GetBlockTransactionCountByNumber returns the number of transactions in a 667 // block from a block matching the given block number. 668 func (e *EthEndpoints) GetBlockTransactionCountByNumber(number *types.BlockNumber) (interface{}, types.Error) { 669 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 670 if number != nil && *number == types.PendingBlockNumber { 671 if e.cfg.SequencerNodeURI != "" { 672 return e.getBlockTransactionCountByNumberFromSequencerNode(number) 673 } 674 c, err := e.pool.CountPendingTransactions(ctx) 675 if err != nil { 676 return RPCErrorResponse(types.DefaultErrorCode, "failed to count pending transactions", err) 677 } 678 return types.ArgUint64(c), nil 679 } 680 681 var err error 682 blockNumber, rpcErr := number.GetNumericBlockNumber(ctx, e.state, dbTx) 683 if rpcErr != nil { 684 return nil, rpcErr 685 } 686 687 c, err := e.state.GetL2BlockTransactionCountByNumber(ctx, blockNumber, dbTx) 688 if err != nil { 689 return RPCErrorResponse(types.DefaultErrorCode, "failed to count transactions", err) 690 } 691 692 return types.ArgUint64(c), nil 693 }) 694 } 695 696 func (e *EthEndpoints) getBlockTransactionCountByNumberFromSequencerNode(number *types.BlockNumber) (interface{}, types.Error) { 697 res, err := client.JSONRPCCall(e.cfg.SequencerNodeURI, "eth_getBlockTransactionCountByNumber", number.StringOrHex()) 698 if err != nil { 699 return RPCErrorResponse(types.DefaultErrorCode, "failed to get tx count by block number from sequencer node", err) 700 } 701 702 if res.Error != nil { 703 return RPCErrorResponse(res.Error.Code, res.Error.Message, nil) 704 } 705 706 var count types.ArgUint64 707 err = json.Unmarshal(res.Result, &count) 708 if err != nil { 709 return RPCErrorResponse(types.DefaultErrorCode, "failed to read tx count by block number from sequencer node", err) 710 } 711 return count, nil 712 } 713 714 // GetTransactionReceipt returns a transaction receipt by his hash 715 func (e *EthEndpoints) GetTransactionReceipt(hash types.ArgHash) (interface{}, types.Error) { 716 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 717 tx, err := e.state.GetTransactionByHash(ctx, hash.Hash(), dbTx) 718 if errors.Is(err, state.ErrNotFound) { 719 return nil, nil 720 } else if err != nil { 721 return RPCErrorResponse(types.DefaultErrorCode, "failed to get tx from state", err) 722 } 723 724 r, err := e.state.GetTransactionReceipt(ctx, hash.Hash(), dbTx) 725 if errors.Is(err, state.ErrNotFound) { 726 return nil, nil 727 } else if err != nil { 728 return RPCErrorResponse(types.DefaultErrorCode, "failed to get tx receipt from state", err) 729 } 730 731 receipt, err := types.NewReceipt(*tx, r) 732 if err != nil { 733 return RPCErrorResponse(types.DefaultErrorCode, "failed to build the receipt response", err) 734 } 735 736 return receipt, nil 737 }) 738 } 739 740 // NewBlockFilter creates a filter in the node, to notify when 741 // a new block arrives. To check if the state has changed, 742 // call eth_getFilterChanges. 743 func (e *EthEndpoints) NewBlockFilter() (interface{}, types.Error) { 744 return e.newBlockFilter(nil) 745 } 746 747 // internal 748 func (e *EthEndpoints) newBlockFilter(wsConn *websocket.Conn) (interface{}, types.Error) { 749 id, err := e.storage.NewBlockFilter(wsConn) 750 if err != nil { 751 return RPCErrorResponse(types.DefaultErrorCode, "failed to create new block filter", err) 752 } 753 754 return id, nil 755 } 756 757 // NewFilter creates a filter object, based on filter options, 758 // to notify when the state changes (logs). To check if the state 759 // has changed, call eth_getFilterChanges. 760 func (e *EthEndpoints) NewFilter(filter LogFilter) (interface{}, types.Error) { 761 return e.newFilter(nil, filter) 762 } 763 764 // internal 765 func (e *EthEndpoints) newFilter(wsConn *websocket.Conn, filter LogFilter) (interface{}, types.Error) { 766 id, err := e.storage.NewLogFilter(wsConn, filter) 767 if errors.Is(err, ErrFilterInvalidPayload) { 768 return RPCErrorResponse(types.InvalidParamsErrorCode, err.Error(), nil) 769 } else if err != nil { 770 return RPCErrorResponse(types.DefaultErrorCode, "failed to create new log filter", err) 771 } 772 773 return id, nil 774 } 775 776 // NewPendingTransactionFilter creates a filter in the node, to 777 // notify when new pending transactions arrive. To check if the 778 // state has changed, call eth_getFilterChanges. 779 func (e *EthEndpoints) NewPendingTransactionFilter() (interface{}, types.Error) { 780 return e.newPendingTransactionFilter(nil) 781 } 782 783 // internal 784 func (e *EthEndpoints) newPendingTransactionFilter(wsConn *websocket.Conn) (interface{}, types.Error) { 785 return nil, types.NewRPCError(types.DefaultErrorCode, "not supported yet") 786 // id, err := e.storage.NewPendingTransactionFilter(wsConn) 787 // if err != nil { 788 // return rpcErrorResponse(types.DefaultErrorCode, "failed to create new pending transaction filter", err) 789 // } 790 791 // return id, nil 792 } 793 794 // SendRawTransaction has two different ways to handle new transactions: 795 // - for Sequencer nodes it tries to add the tx to the pool 796 // - for Non-Sequencer nodes it relays the Tx to the Sequencer node 797 func (e *EthEndpoints) SendRawTransaction(httpRequest *http.Request, input string) (interface{}, types.Error) { 798 if e.cfg.SequencerNodeURI != "" { 799 return e.relayTxToSequencerNode(input) 800 } else { 801 ip := "" 802 ips := httpRequest.Header.Get("X-Forwarded-For") 803 804 if ips != "" { 805 ip = strings.Split(ips, ",")[0] 806 } 807 808 return e.tryToAddTxToPool(input, ip) 809 } 810 } 811 812 func (e *EthEndpoints) relayTxToSequencerNode(input string) (interface{}, types.Error) { 813 res, err := client.JSONRPCCall(e.cfg.SequencerNodeURI, "eth_sendRawTransaction", input) 814 if err != nil { 815 return RPCErrorResponse(types.DefaultErrorCode, "failed to relay tx to the sequencer node", err) 816 } 817 818 if res.Error != nil { 819 return RPCErrorResponse(res.Error.Code, res.Error.Message, nil) 820 } 821 822 txHash := res.Result 823 824 return txHash, nil 825 } 826 827 func (e *EthEndpoints) tryToAddTxToPool(input, ip string) (interface{}, types.Error) { 828 tx, err := hexToTx(input) 829 if err != nil { 830 return RPCErrorResponse(types.InvalidParamsErrorCode, "invalid tx input", err) 831 } 832 833 log.Infof("adding TX to the pool: %v", tx.Hash().Hex()) 834 if err := e.pool.AddTx(context.Background(), *tx, ip); err != nil { 835 return RPCErrorResponse(types.DefaultErrorCode, err.Error(), nil) 836 } 837 log.Infof("TX added to the pool: %v", tx.Hash().Hex()) 838 839 return tx.Hash().Hex(), nil 840 } 841 842 // UninstallFilter uninstalls a filter with given id. 843 func (e *EthEndpoints) UninstallFilter(filterID string) (interface{}, types.Error) { 844 err := e.storage.UninstallFilter(filterID) 845 if errors.Is(err, ErrNotFound) { 846 return false, nil 847 } else if err != nil { 848 return RPCErrorResponse(types.DefaultErrorCode, "failed to uninstall filter", err) 849 } 850 851 return true, nil 852 } 853 854 // Syncing returns an object with data about the sync status or false. 855 // https://eth.wiki/json-rpc/API#eth_syncing 856 func (e *EthEndpoints) Syncing() (interface{}, types.Error) { 857 return e.txMan.NewDbTxScope(e.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { 858 _, err := e.state.GetLastL2BlockNumber(ctx, dbTx) 859 if err != nil { 860 return RPCErrorResponse(types.DefaultErrorCode, "failed to get last block number from state", err) 861 } 862 863 syncInfo, err := e.state.GetSyncingInfo(ctx, dbTx) 864 if err != nil { 865 return RPCErrorResponse(types.DefaultErrorCode, "failed to get syncing info from state", err) 866 } 867 868 if syncInfo.CurrentBlockNumber == syncInfo.LastBlockNumberSeen { 869 return false, nil 870 } 871 872 return struct { 873 S types.ArgUint64 `json:"startingBlock"` 874 C types.ArgUint64 `json:"currentBlock"` 875 H types.ArgUint64 `json:"highestBlock"` 876 }{ 877 S: types.ArgUint64(syncInfo.InitialSyncingBlock), 878 C: types.ArgUint64(syncInfo.CurrentBlockNumber), 879 H: types.ArgUint64(syncInfo.LastBlockNumberSeen), 880 }, nil 881 }) 882 } 883 884 // GetUncleByBlockHashAndIndex returns information about a uncle of a 885 // block by hash and uncle index position 886 func (e *EthEndpoints) GetUncleByBlockHashAndIndex(hash types.ArgHash, index types.Index) (interface{}, types.Error) { 887 return nil, nil 888 } 889 890 // GetUncleByBlockNumberAndIndex returns information about a uncle of a 891 // block by number and uncle index position 892 func (e *EthEndpoints) GetUncleByBlockNumberAndIndex(number types.BlockNumber, index types.Index) (interface{}, types.Error) { 893 return nil, nil 894 } 895 896 // GetUncleCountByBlockHash returns the number of uncles in a block 897 // matching the given block hash 898 func (e *EthEndpoints) GetUncleCountByBlockHash(hash types.ArgAddress) (interface{}, types.Error) { 899 return "0x0", nil 900 } 901 902 // GetUncleCountByBlockNumber returns the number of uncles in a block 903 // matching the given block number 904 func (e *EthEndpoints) GetUncleCountByBlockNumber(number types.BlockNumber) (interface{}, types.Error) { 905 return "0x0", nil 906 } 907 908 // ProtocolVersion returns the protocol version. 909 func (e *EthEndpoints) ProtocolVersion() (interface{}, types.Error) { 910 return "0x0", nil 911 } 912 913 func hexToTx(str string) (*ethTypes.Transaction, error) { 914 tx := new(ethTypes.Transaction) 915 916 b, err := hex.DecodeHex(str) 917 if err != nil { 918 return nil, err 919 } 920 921 if err := tx.UnmarshalBinary(b); err != nil { 922 return nil, err 923 } 924 925 return tx, nil 926 } 927 928 func (e *EthEndpoints) updateFilterLastPoll(filterID string) types.Error { 929 err := e.storage.UpdateFilterLastPoll(filterID) 930 if err != nil && !errors.Is(err, ErrNotFound) { 931 return types.NewRPCError(types.DefaultErrorCode, "failed to update last time the filter changes were requested") 932 } 933 return nil 934 } 935 936 // Subscribe Creates a new subscription over particular events. 937 // The node will return a subscription id. 938 // For each event that matches the subscription a notification with relevant 939 // data is sent together with the subscription id. 940 func (e *EthEndpoints) Subscribe(wsConn *websocket.Conn, name string, logFilter *LogFilter) (interface{}, types.Error) { 941 switch name { 942 case "newHeads": 943 return e.newBlockFilter(wsConn) 944 case "logs": 945 var lf LogFilter 946 if logFilter != nil { 947 lf = *logFilter 948 } 949 return e.newFilter(wsConn, lf) 950 case "pendingTransactions", "newPendingTransactions": 951 return e.newPendingTransactionFilter(wsConn) 952 case "syncing": 953 return nil, types.NewRPCError(types.DefaultErrorCode, "not supported yet") 954 default: 955 return nil, types.NewRPCError(types.DefaultErrorCode, "invalid filter name") 956 } 957 } 958 959 // Unsubscribe uninstalls the filter based on the provided filterID 960 func (e *EthEndpoints) Unsubscribe(wsConn *websocket.Conn, filterID string) (interface{}, types.Error) { 961 return e.UninstallFilter(filterID) 962 } 963 964 // uninstallFilterByWSConn uninstalls the filters connected to the 965 // provided web socket connection 966 func (e *EthEndpoints) uninstallFilterByWSConn(wsConn *websocket.Conn) error { 967 return e.storage.UninstallFilterByWSConn(wsConn) 968 } 969 970 // onNewL2Block is triggered when the state triggers the event for a new l2 block 971 func (e *EthEndpoints) onNewL2Block(event state.NewL2BlockEvent) { 972 blockFilters, err := e.storage.GetAllBlockFiltersWithWSConn() 973 if err != nil { 974 log.Errorf("failed to get all block filters with web sockets connections: %v", err) 975 } else { 976 for _, filter := range blockFilters { 977 b := types.NewBlock(&event.Block, false) 978 e.sendSubscriptionResponse(filter, b) 979 } 980 } 981 982 logFilters, err := e.storage.GetAllLogFiltersWithWSConn() 983 if err != nil { 984 log.Errorf("failed to get all log filters with web sockets connections: %v", err) 985 } else { 986 for _, filter := range logFilters { 987 changes, err := e.GetFilterChanges(filter.ID) 988 if err != nil { 989 log.Errorf("failed to get filters changes for filter %v with web sockets connections: %v", filter.ID, err) 990 continue 991 } 992 993 if changes != nil { 994 e.sendSubscriptionResponse(filter, changes) 995 } 996 } 997 } 998 } 999 1000 func (e *EthEndpoints) sendSubscriptionResponse(filter *Filter, data interface{}) { 1001 const errMessage = "Unable to write WS message to filter %v, %s" 1002 result, err := json.Marshal(data) 1003 if err != nil { 1004 log.Errorf(fmt.Sprintf(errMessage, filter.ID, err.Error())) 1005 } 1006 1007 res := types.SubscriptionResponse{ 1008 JSONRPC: "2.0", 1009 Method: "eth_subscription", 1010 Params: types.SubscriptionResponseParams{ 1011 Subscription: filter.ID, 1012 Result: result, 1013 }, 1014 } 1015 message, err := json.Marshal(res) 1016 if err != nil { 1017 log.Errorf(fmt.Sprintf(errMessage, filter.ID, err.Error())) 1018 } 1019 1020 err = filter.WsConn.WriteMessage(websocket.TextMessage, message) 1021 if err != nil { 1022 log.Errorf(fmt.Sprintf(errMessage, filter.ID, err.Error())) 1023 } 1024 }