From 2d98c3bd0db3528de1d8a0f3f73a143324eb7482 Mon Sep 17 00:00:00 2001 From: Alex Sharov <AskAlexSharov@gmail.com> Date: Wed, 29 Sep 2021 13:51:51 +0700 Subject: [PATCH] Remote RPC: add blocksLRU (#2744) --- cmd/rpcdaemon/commands/call_traces_test.go | 6 +-- .../commands/corner_cases_support_test.go | 2 +- cmd/rpcdaemon/commands/daemon.go | 5 +- cmd/rpcdaemon/commands/debug_api.go | 10 ++-- cmd/rpcdaemon/commands/debug_api_test.go | 4 +- cmd/rpcdaemon/commands/erigon_issuance.go | 3 +- cmd/rpcdaemon/commands/erigon_receipts.go | 8 +-- cmd/rpcdaemon/commands/eth_api.go | 52 +++++++++++++++++-- cmd/rpcdaemon/commands/eth_api_test.go | 22 ++++---- cmd/rpcdaemon/commands/eth_block.go | 7 ++- cmd/rpcdaemon/commands/eth_call_test.go | 4 +- cmd/rpcdaemon/commands/eth_ming_test.go | 2 +- cmd/rpcdaemon/commands/eth_receipts.go | 10 ++-- cmd/rpcdaemon/commands/eth_system.go | 26 ++++------ cmd/rpcdaemon/commands/eth_txs.go | 15 ++---- cmd/rpcdaemon/commands/eth_uncles.go | 6 +-- .../commands/send_transaction_test.go | 2 +- cmd/rpcdaemon/commands/trace_adhoc.go | 4 +- cmd/rpcdaemon/commands/trace_adhoc_test.go | 8 +-- cmd/rpcdaemon/commands/trace_filtering.go | 13 ++--- cmd/rpcdaemon/commands/tracing.go | 2 +- cmd/rpcdaemon/commands/txpool_api_test.go | 2 +- 22 files changed, 122 insertions(+), 91 deletions(-) diff --git a/cmd/rpcdaemon/commands/call_traces_test.go b/cmd/rpcdaemon/commands/call_traces_test.go index 736c13535e..728a6215a6 100644 --- a/cmd/rpcdaemon/commands/call_traces_test.go +++ b/cmd/rpcdaemon/commands/call_traces_test.go @@ -45,7 +45,7 @@ func TestCallTraceOneByOne(t *testing.T) { if err != nil { t.Fatalf("generate chain: %v", err) } - api := NewTraceAPI(NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig)), m.DB, &cli.Flags{}) + api := NewTraceAPI(NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig), false), m.DB, &cli.Flags{}) // Insert blocks 1 by 1, to tirgget possible "off by one" errors for i := 0; i < chain.Length; i++ { if err = m.InsertChain(chain.Slice(i, i+1)); err != nil { @@ -90,7 +90,7 @@ func TestCallTraceUnwind(t *testing.T) { if err != nil { t.Fatalf("generate chainB: %v", err) } - api := NewTraceAPI(NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig)), m.DB, &cli.Flags{}) + api := NewTraceAPI(NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig), false), m.DB, &cli.Flags{}) if err = m.InsertChain(chainA); err != nil { t.Fatalf("inserting chainA: %v", err) } @@ -150,7 +150,7 @@ func TestFilterNoAddresses(t *testing.T) { if err != nil { t.Fatalf("generate chain: %v", err) } - api := NewTraceAPI(NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig)), m.DB, &cli.Flags{}) + api := NewTraceAPI(NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig), false), m.DB, &cli.Flags{}) // Insert blocks 1 by 1, to tirgget possible "off by one" errors for i := 0; i < chain.Length; i++ { if err = m.InsertChain(chain.Slice(i, i+1)); err != nil { diff --git a/cmd/rpcdaemon/commands/corner_cases_support_test.go b/cmd/rpcdaemon/commands/corner_cases_support_test.go index 858723e6d2..e4dd2c95f2 100644 --- a/cmd/rpcdaemon/commands/corner_cases_support_test.go +++ b/cmd/rpcdaemon/commands/corner_cases_support_test.go @@ -18,7 +18,7 @@ func TestNotFoundMustReturnNil(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) defer db.Close() stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache), db, nil, nil, nil, 5000000) + api := NewEthAPI(NewBaseApi(nil, stateCache, false), db, nil, nil, nil, 5000000) ctx := context.Background() a, err := api.GetTransactionByBlockNumberAndIndex(ctx, 10_000, 1) diff --git a/cmd/rpcdaemon/commands/daemon.go b/cmd/rpcdaemon/commands/daemon.go index 6c84e68e6e..bb55ce7c78 100644 --- a/cmd/rpcdaemon/commands/daemon.go +++ b/cmd/rpcdaemon/commands/daemon.go @@ -14,11 +14,12 @@ import ( // APIList describes the list of available RPC apis func APIList(ctx context.Context, db kv.RoDB, - eth services.ApiBackend, txPool txpool.TxpoolClient, mining txpool.MiningClient, filters *filters.Filters, stateCache kvcache.Cache, + eth services.ApiBackend, txPool txpool.TxpoolClient, mining txpool.MiningClient, filters *filters.Filters, + stateCache kvcache.Cache, cfg cli.Flags, customAPIList []rpc.API) []rpc.API { var defaultAPIList []rpc.API - base := NewBaseApi(filters, stateCache) + base := NewBaseApi(filters, stateCache, cfg.SingleNodeMode) ethImpl := NewEthAPI(base, db, eth, txPool, mining, cfg.Gascap) erigonImpl := NewErigonAPI(base, db) txpoolImpl := NewTxPoolAPI(base, db, txPool) diff --git a/cmd/rpcdaemon/commands/debug_api.go b/cmd/rpcdaemon/commands/debug_api.go index 3bcbedbf77..c161779e32 100644 --- a/cmd/rpcdaemon/commands/debug_api.go +++ b/cmd/rpcdaemon/commands/debug_api.go @@ -62,7 +62,7 @@ func (api *PrivateDebugAPIImpl) StorageRangeAt(ctx context.Context, blockHash co return StorageRangeResult{}, err } - block, _, err := rawdb.ReadBlockByHashWithSenders(tx, blockHash) + block, err := api.blockByHashWithSenders(tx, blockHash) if err != nil { return StorageRangeResult{}, err } @@ -106,7 +106,7 @@ func (api *PrivateDebugAPIImpl) AccountRange(ctx context.Context, blockNrOrHash } } else if hash, ok := blockNrOrHash.Hash(); ok { - block, err1 := rawdb.ReadBlockByHash(tx, hash) + block, err1 := api.blockByHashWithSenders(tx, hash) if err1 != nil { return state.IteratorDump{}, err1 } @@ -185,7 +185,7 @@ func (api *PrivateDebugAPIImpl) GetModifiedAccountsByHash(ctx context.Context, s } defer tx.Rollback() - startBlock, err := rawdb.ReadBlockByHash(tx, startHash) + startBlock, err := api.blockByHashWithSenders(tx, startHash) if err != nil { return nil, err } @@ -196,7 +196,7 @@ func (api *PrivateDebugAPIImpl) GetModifiedAccountsByHash(ctx context.Context, s endNum := startNum + 1 // allows for single parameter calls if endHash != nil { - endBlock, err := rawdb.ReadBlockByHash(tx, *endHash) + endBlock, err := api.blockByHashWithSenders(tx, *endHash) if err != nil { return nil, err } @@ -225,7 +225,7 @@ func (api *PrivateDebugAPIImpl) AccountAt(ctx context.Context, blockHash common. return nil, err } - block, _, err := rawdb.ReadBlockByHashWithSenders(tx, blockHash) + block, err := api.blockByHashWithSenders(tx, blockHash) if err != nil { return nil, err } diff --git a/cmd/rpcdaemon/commands/debug_api_test.go b/cmd/rpcdaemon/commands/debug_api_test.go index a8c31922ad..a0eff1db45 100644 --- a/cmd/rpcdaemon/commands/debug_api_test.go +++ b/cmd/rpcdaemon/commands/debug_api_test.go @@ -39,7 +39,7 @@ var debugTraceTransactionNoRefundTests = []struct { func TestTraceTransaction(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewPrivateDebugAPI(NewBaseApi(nil, stateCache), db, 0) + api := NewPrivateDebugAPI(NewBaseApi(nil, stateCache, false), db, 0) for _, tt := range debugTraceTransactionTests { var buf bytes.Buffer stream := jsoniter.NewStream(jsoniter.ConfigDefault, &buf, 4096) @@ -69,7 +69,7 @@ func TestTraceTransaction(t *testing.T) { func TestTraceTransactionNoRefund(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewPrivateDebugAPI(NewBaseApi(nil, stateCache), db, 0) + api := NewPrivateDebugAPI(NewBaseApi(nil, stateCache, false), db, 0) for _, tt := range debugTraceTransactionNoRefundTests { var buf bytes.Buffer stream := jsoniter.NewStream(jsoniter.ConfigDefault, &buf, 4096) diff --git a/cmd/rpcdaemon/commands/erigon_issuance.go b/cmd/rpcdaemon/commands/erigon_issuance.go index b45d60cbc4..82b5a09e93 100644 --- a/cmd/rpcdaemon/commands/erigon_issuance.go +++ b/cmd/rpcdaemon/commands/erigon_issuance.go @@ -6,7 +6,6 @@ import ( "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/consensus/ethash" - "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/rpc" ) @@ -74,7 +73,7 @@ func (api *ErigonImpl) getBlockByRPCNumber(tx kv.Tx, blockNr rpc.BlockNumber) (* if err != nil { return nil, err } - return rawdb.ReadBlockByNumber(tx, blockNum) + return api.blockByNumberWithSenders(tx, blockNum) } // Issuance structure to return information about issuance diff --git a/cmd/rpcdaemon/commands/erigon_receipts.go b/cmd/rpcdaemon/commands/erigon_receipts.go index 0e792b3060..b014b1e30e 100644 --- a/cmd/rpcdaemon/commands/erigon_receipts.go +++ b/cmd/rpcdaemon/commands/erigon_receipts.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" ) @@ -22,11 +21,14 @@ func (api *ErigonImpl) GetLogsByHash(ctx context.Context, hash common.Hash) ([][ return nil, err } - block, senders, err := rawdb.ReadBlockByHashWithSenders(tx, hash) + block, err := api.blockByHashWithSenders(tx, hash) if err != nil { return nil, err } - receipts, err := getReceipts(ctx, tx, chainConfig, block, senders) + if block == nil { + return nil, nil + } + receipts, err := getReceipts(ctx, tx, chainConfig, block, block.Body().SendersFromTxs()) if err != nil { return nil, fmt.Errorf("getReceipts error: %v", err) } diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go index 9e1797a7b3..5eb8bb2b32 100644 --- a/cmd/rpcdaemon/commands/eth_api.go +++ b/cmd/rpcdaemon/commands/eth_api.go @@ -6,6 +6,7 @@ import ( "math/big" "sync" + lru "github.com/hashicorp/golang-lru" "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/kvcache" @@ -98,15 +99,20 @@ type EthAPI interface { } type BaseAPI struct { - stateCache kvcache.Cache + stateCache kvcache.Cache // thread-safe + blocksLRU *lru.Cache // thread-safe filters *filters.Filters _chainConfig *params.ChainConfig _genesis *types.Block _genesisLock sync.RWMutex } -func NewBaseApi(f *filters.Filters, stateCache kvcache.Cache) *BaseAPI { - return &BaseAPI{filters: f, stateCache: stateCache} +func NewBaseApi(f *filters.Filters, stateCache kvcache.Cache, singleNodeMode bool) *BaseAPI { + var blocksLRU *lru.Cache + if !singleNodeMode { + blocksLRU, _ = lru.New(256) + } + return &BaseAPI{filters: f, stateCache: stateCache, blocksLRU: blocksLRU} } func (api *BaseAPI) chainConfig(tx kv.Tx) (*params.ChainConfig, error) { @@ -120,6 +126,42 @@ func (api *BaseAPI) genesis(tx kv.Tx) (*types.Block, error) { return genesis, err } +func (api *BaseAPI) blockByNumberWithSenders(tx kv.Tx, number uint64) (*types.Block, error) { + hash, hashErr := rawdb.ReadCanonicalHash(tx, number) + if hashErr != nil { + return nil, hashErr + } + return api.blockWithSenders(tx, hash, number) +} +func (api *BaseAPI) blockByHashWithSenders(tx kv.Tx, hash common.Hash) (*types.Block, error) { + if api.blocksLRU != nil { + if it, ok := api.blocksLRU.Get(hash); ok && it != nil { + return it.(*types.Block), nil + } + } + number := rawdb.ReadHeaderNumber(tx, hash) + if number == nil { + return nil, nil + } + return api.blockWithSenders(tx, hash, *number) +} +func (api *BaseAPI) blockWithSenders(tx kv.Tx, hash common.Hash, number uint64) (*types.Block, error) { + if api.blocksLRU != nil { + if it, ok := api.blocksLRU.Get(hash); ok && it != nil { + return it.(*types.Block), nil + } + } + block, _, err := rawdb.ReadBlockWithSenders(tx, hash, number) + if err != nil { + return nil, err + } + + if api.blocksLRU != nil { + api.blocksLRU.Add(hash, block) + } + return block, nil +} + func (api *BaseAPI) chainConfigWithGenesis(tx kv.Tx) (*params.ChainConfig, *types.Block, error) { api._genesisLock.RLock() cc, genesisBlock := api._chainConfig, api._genesis @@ -149,7 +191,7 @@ func (api *BaseAPI) pendingBlock() *types.Block { return api.filters.LastPendingBlock() } -func (api *BaseAPI) getBlockByNumber(number rpc.BlockNumber, tx kv.Tx) (*types.Block, error) { +func (api *BaseAPI) blockByRPCNumber(number rpc.BlockNumber, tx kv.Tx) (*types.Block, error) { if number == rpc.PendingBlockNumber { return api.pendingBlock(), nil } @@ -159,7 +201,7 @@ func (api *BaseAPI) getBlockByNumber(number rpc.BlockNumber, tx kv.Tx) (*types.B return nil, err } - block, _, err := rawdb.ReadBlockByNumberWithSenders(tx, n) + block, err := api.blockByNumberWithSenders(tx, n) return block, err } diff --git a/cmd/rpcdaemon/commands/eth_api_test.go b/cmd/rpcdaemon/commands/eth_api_test.go index 90bda38f11..7b31dc7f8a 100644 --- a/cmd/rpcdaemon/commands/eth_api_test.go +++ b/cmd/rpcdaemon/commands/eth_api_test.go @@ -18,7 +18,7 @@ import ( func TestGetTransactionReceipt(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache), db, nil, nil, nil, 5000000) + api := NewEthAPI(NewBaseApi(nil, stateCache, false), db, nil, nil, nil, 5000000) // Call GetTransactionReceipt for transaction which is not in the database if _, err := api.GetTransactionReceipt(context.Background(), common.Hash{}); err != nil { t.Errorf("calling GetTransactionReceipt with empty hash: %v", err) @@ -28,7 +28,7 @@ func TestGetTransactionReceipt(t *testing.T) { func TestGetTransactionReceiptUnprotected(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache), db, nil, nil, nil, 5000000) + api := NewEthAPI(NewBaseApi(nil, stateCache, false), db, nil, nil, nil, 5000000) // Call GetTransactionReceipt for un-protected transaction if _, err := api.GetTransactionReceipt(context.Background(), common.HexToHash("0x3f3cb8a0e13ed2481f97f53f7095b9cbc78b6ffb779f2d3e565146371a8830ea")); err != nil { t.Errorf("calling GetTransactionReceipt for unprotected tx: %v", err) @@ -41,7 +41,7 @@ func TestGetStorageAt_ByBlockNumber_WithRequireCanonicalDefault(t *testing.T) { assert := assert.New(t) db := rpcdaemontest.CreateTestKV(t) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache), db, nil, nil, nil, 5000000) + api := NewEthAPI(NewBaseApi(nil, stateCache, false), db, nil, nil, nil, 5000000) addr := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") result, err := api.GetStorageAt(context.Background(), addr, "0x0", rpc.BlockNumberOrHashWithNumber(0)) @@ -57,7 +57,7 @@ func TestGetStorageAt_ByBlockHash_WithRequireCanonicalDefault(t *testing.T) { m, _, _ := rpcdaemontest.CreateTestSentry(t) db := m.DB stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache), db, nil, nil, nil, 5000000) + api := NewEthAPI(NewBaseApi(nil, stateCache, false), db, nil, nil, nil, 5000000) addr := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") result, err := api.GetStorageAt(context.Background(), addr, "0x0", rpc.BlockNumberOrHashWithHash(m.Genesis.Hash(), false)) @@ -73,7 +73,7 @@ func TestGetStorageAt_ByBlockHash_WithRequireCanonicalTrue(t *testing.T) { m, _, _ := rpcdaemontest.CreateTestSentry(t) db := m.DB stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache), db, nil, nil, nil, 5000000) + api := NewEthAPI(NewBaseApi(nil, stateCache, false), db, nil, nil, nil, 5000000) addr := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") result, err := api.GetStorageAt(context.Background(), addr, "0x0", rpc.BlockNumberOrHashWithHash(m.Genesis.Hash(), true)) @@ -88,7 +88,7 @@ func TestGetStorageAt_ByBlockHash_WithRequireCanonicalDefault_BlockNotFoundError m, _, _ := rpcdaemontest.CreateTestSentry(t) db := m.DB stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache), db, nil, nil, nil, 5000000) + api := NewEthAPI(NewBaseApi(nil, stateCache, false), db, nil, nil, nil, 5000000) addr := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") offChain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(i int, block *core.BlockGen) { @@ -111,7 +111,7 @@ func TestGetStorageAt_ByBlockHash_WithRequireCanonicalTrue_BlockNotFoundError(t m, _, _ := rpcdaemontest.CreateTestSentry(t) db := m.DB stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache), db, nil, nil, nil, 5000000) + api := NewEthAPI(NewBaseApi(nil, stateCache, false), db, nil, nil, nil, 5000000) addr := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") offChain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(i int, block *core.BlockGen) { @@ -135,7 +135,7 @@ func TestGetStorageAt_ByBlockHash_WithRequireCanonicalDefault_NonCanonicalBlock( m, _, orphanedChain := rpcdaemontest.CreateTestSentry(t) db := m.DB stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache), db, nil, nil, nil, 5000000) + api := NewEthAPI(NewBaseApi(nil, stateCache, false), db, nil, nil, nil, 5000000) addr := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") orphanedBlock := orphanedChain[0].Blocks[0] @@ -152,7 +152,7 @@ func TestGetStorageAt_ByBlockHash_WithRequireCanonicalTrue_NonCanonicalBlock(t * m, _, orphanedChain := rpcdaemontest.CreateTestSentry(t) db := m.DB stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache), db, nil, nil, nil, 5000000) + api := NewEthAPI(NewBaseApi(nil, stateCache, false), db, nil, nil, nil, 5000000) addr := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") orphanedBlock := orphanedChain[0].Blocks[0] @@ -170,7 +170,7 @@ func TestCall_ByBlockHash_WithRequireCanonicalDefault_NonCanonicalBlock(t *testi m, _, orphanedChain := rpcdaemontest.CreateTestSentry(t) db := m.DB stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache), db, nil, nil, nil, 5000000) + api := NewEthAPI(NewBaseApi(nil, stateCache, false), db, nil, nil, nil, 5000000) from := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") to := common.HexToAddress("0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e") @@ -195,7 +195,7 @@ func TestCall_ByBlockHash_WithRequireCanonicalTrue_NonCanonicalBlock(t *testing. m, _, orphanedChain := rpcdaemontest.CreateTestSentry(t) db := m.DB stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache), db, nil, nil, nil, 5000000) + api := NewEthAPI(NewBaseApi(nil, stateCache, false), db, nil, nil, nil, 5000000) from := common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") to := common.HexToAddress("0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e") diff --git a/cmd/rpcdaemon/commands/eth_block.go b/cmd/rpcdaemon/commands/eth_block.go index 6817b31c56..ba875f2423 100644 --- a/cmd/rpcdaemon/commands/eth_block.go +++ b/cmd/rpcdaemon/commands/eth_block.go @@ -173,7 +173,7 @@ func (api *APIImpl) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber return nil, err } defer tx.Rollback() - b, err := api.getBlockByNumber(number, tx) + b, err := api.blockByRPCNumber(number, tx) if err != nil { return nil, err } @@ -181,7 +181,6 @@ func (api *APIImpl) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber return nil, nil } additionalFields := make(map[string]interface{}) - td, err := rawdb.ReadTd(tx, b.Hash(), b.NumberU64()) if err != nil { return nil, err @@ -219,7 +218,7 @@ func (api *APIImpl) GetBlockByHash(ctx context.Context, numberOrHash rpc.BlockNu additionalFields := make(map[string]interface{}) - block, _, err := rawdb.ReadBlockByHashWithSenders(tx, hash) + block, err := api.blockByHashWithSenders(tx, hash) if err != nil { return nil, err } @@ -252,7 +251,7 @@ func (api *APIImpl) GetBlockTransactionCountByNumber(ctx context.Context, blockN } defer tx.Rollback() if blockNr == rpc.PendingBlockNumber { - b, err := api.getBlockByNumber(blockNr, tx) + b, err := api.blockByRPCNumber(blockNr, tx) if err != nil { return nil, err } diff --git a/cmd/rpcdaemon/commands/eth_call_test.go b/cmd/rpcdaemon/commands/eth_call_test.go index 653a767550..aee770f868 100644 --- a/cmd/rpcdaemon/commands/eth_call_test.go +++ b/cmd/rpcdaemon/commands/eth_call_test.go @@ -15,7 +15,7 @@ import ( func TestEstimateGas(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache), db, nil, nil, nil, 5000000) + api := NewEthAPI(NewBaseApi(nil, stateCache, false), db, nil, nil, nil, 5000000) var from = common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") var to = common.HexToAddress("0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e") if _, err := api.EstimateGas(context.Background(), ethapi.CallArgs{ @@ -29,7 +29,7 @@ func TestEstimateGas(t *testing.T) { func TestEthCallNonCanonical(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache), db, nil, nil, nil, 5000000) + api := NewEthAPI(NewBaseApi(nil, stateCache, false), db, nil, nil, nil, 5000000) var from = common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") var to = common.HexToAddress("0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e") if _, err := api.Call(context.Background(), ethapi.CallArgs{ diff --git a/cmd/rpcdaemon/commands/eth_ming_test.go b/cmd/rpcdaemon/commands/eth_ming_test.go index b1bad5b716..35e734ed28 100644 --- a/cmd/rpcdaemon/commands/eth_ming_test.go +++ b/cmd/rpcdaemon/commands/eth_ming_test.go @@ -20,7 +20,7 @@ func TestPendingBlock(t *testing.T) { mining := txpool.NewMiningClient(conn) ff := filters.New(ctx, nil, nil, mining) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(ff, stateCache), nil, nil, nil, mining, 5000000) + api := NewEthAPI(NewBaseApi(ff, stateCache, false), nil, nil, nil, mining, 5000000) expect := uint64(12345) b, err := rlp.EncodeToBytes(types.NewBlockWithHeader(&types.Header{Number: big.NewInt(int64(expect))})) require.NoError(t, err) diff --git a/cmd/rpcdaemon/commands/eth_receipts.go b/cmd/rpcdaemon/commands/eth_receipts.go index e18e039d32..1f0e281d79 100644 --- a/cmd/rpcdaemon/commands/eth_receipts.go +++ b/cmd/rpcdaemon/commands/eth_receipts.go @@ -167,7 +167,7 @@ func (api *APIImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria) ([ } if len(blockLogs) > 0 { - b, err := rawdb.ReadBlockByNumber(tx, blockNToMatch) + b, err := api.blockByNumberWithSenders(tx, blockNToMatch) if err != nil { return nil, err } @@ -241,7 +241,7 @@ func (api *APIImpl) GetTransactionReceipt(ctx context.Context, hash common.Hash) } // Extract transactions from block - block, senders, bErr := rawdb.ReadBlockByNumberWithSenders(tx, *blockNumber) + block, bErr := api.blockByNumberWithSenders(tx, *blockNumber) if bErr != nil { return nil, bErr } @@ -260,7 +260,7 @@ func (api *APIImpl) GetTransactionReceipt(ctx context.Context, hash common.Hash) if err != nil { return nil, err } - receipts, err := getReceipts(ctx, tx, cc, block, senders) + receipts, err := getReceipts(ctx, tx, cc, block, block.Body().SendersFromTxs()) if err != nil { return nil, fmt.Errorf("getReceipts error: %v", err) } @@ -282,7 +282,7 @@ func (api *APIImpl) GetBlockReceipts(ctx context.Context, number rpc.BlockNumber if err != nil { return nil, err } - block, senders, err := rawdb.ReadBlockByNumberWithSenders(tx, blockNum) + block, err := api.blockByNumberWithSenders(tx, blockNum) if err != nil { return nil, err } @@ -293,7 +293,7 @@ func (api *APIImpl) GetBlockReceipts(ctx context.Context, number rpc.BlockNumber if err != nil { return nil, err } - receipts, err := getReceipts(ctx, tx, chainConfig, block, senders) + receipts, err := getReceipts(ctx, tx, chainConfig, block, block.Body().SendersFromTxs()) if err != nil { return nil, fmt.Errorf("getReceipts error: %v", err) } diff --git a/cmd/rpcdaemon/commands/eth_system.go b/cmd/rpcdaemon/commands/eth_system.go index b56e3098fe..9cff08d163 100644 --- a/cmd/rpcdaemon/commands/eth_system.go +++ b/cmd/rpcdaemon/commands/eth_system.go @@ -113,7 +113,7 @@ func (api *APIImpl) GasPrice(ctx context.Context) (*hexutil.Big, error) { if err != nil { return nil, err } - oracle := gasprice.NewOracle(&GasPriceOracleBackend{tx: tx, cc: cc}, ethconfig.Defaults.GPO) + oracle := gasprice.NewOracle(NewGasPriceOracleBackend(tx, cc, api.BaseAPI), ethconfig.Defaults.GPO) tipcap, err := oracle.SuggestTipCap(ctx) if err != nil { return nil, err @@ -135,7 +135,7 @@ func (api *APIImpl) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, err if err != nil { return nil, err } - oracle := gasprice.NewOracle(&GasPriceOracleBackend{tx: tx, cc: cc}, ethconfig.Defaults.GPO) + oracle := gasprice.NewOracle(NewGasPriceOracleBackend(tx, cc, api.BaseAPI), ethconfig.Defaults.GPO) tipcap, err := oracle.SuggestTipCap(ctx) if err != nil { return nil, err @@ -160,7 +160,7 @@ func (api *APIImpl) FeeHistory(ctx context.Context, blockCount rpc.DecimalOrHex, if err != nil { return nil, err } - oracle := gasprice.NewOracle(&GasPriceOracleBackend{tx: tx, cc: cc}, ethconfig.Defaults.GPO) + oracle := gasprice.NewOracle(NewGasPriceOracleBackend(tx, cc, api.BaseAPI), ethconfig.Defaults.GPO) oldest, reward, baseFee, gasUsed, err := oracle.FeeHistory(ctx, int(blockCount), lastBlock, rewardPercentiles) if err != nil { @@ -189,8 +189,13 @@ func (api *APIImpl) FeeHistory(ctx context.Context, blockCount rpc.DecimalOrHex, } type GasPriceOracleBackend struct { - tx kv.Tx - cc *params.ChainConfig + tx kv.Tx + cc *params.ChainConfig + baseApi *BaseAPI +} + +func NewGasPriceOracleBackend(tx kv.Tx, cc *params.ChainConfig, baseApi *BaseAPI) *GasPriceOracleBackend { + return &GasPriceOracleBackend{tx: tx, cc: cc, baseApi: baseApi} } func (b *GasPriceOracleBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { @@ -206,16 +211,7 @@ func (b *GasPriceOracleBackend) HeaderByNumber(ctx context.Context, number rpc.B return header, nil } func (b *GasPriceOracleBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) { - blockNum, err := getBlockNumber(number, b.tx) - if err != nil { - return nil, err - } - - block, _, err := rawdb.ReadBlockByNumberWithSenders(b.tx, blockNum) - if err != nil { - return nil, err - } - return block, nil + return b.baseApi.blockByRPCNumber(number, b.tx) } func (b *GasPriceOracleBackend) ChainConfig() *params.ChainConfig { return b.cc diff --git a/cmd/rpcdaemon/commands/eth_txs.go b/cmd/rpcdaemon/commands/eth_txs.go index 3d1899dfde..7f32150aac 100644 --- a/cmd/rpcdaemon/commands/eth_txs.go +++ b/cmd/rpcdaemon/commands/eth_txs.go @@ -38,7 +38,7 @@ func (api *APIImpl) GetTransactionByHash(ctx context.Context, hash common.Hash) return nil, err } if chainConfig.IsLondon(blockNumber) && blockHash != (common.Hash{}) { - block, err := rawdb.ReadBlockByHash(tx, blockHash) + block, err := api.blockByHashWithSenders(tx, blockHash) if err != nil { return nil, err } @@ -108,7 +108,7 @@ func (api *APIImpl) GetTransactionByBlockHashAndIndex(ctx context.Context, block defer tx.Rollback() // https://infura.io/docs/ethereum/json-rpc/eth-getTransactionByBlockHashAndIndex - block, _, err := rawdb.ReadBlockByHashWithSenders(tx, blockHash) + block, err := api.blockByHashWithSenders(tx, blockHash) if err != nil { return nil, err } @@ -133,7 +133,7 @@ func (api *APIImpl) GetRawTransactionByBlockHashAndIndex(ctx context.Context, bl defer tx.Rollback() // https://infura.io/docs/ethereum/json-rpc/eth-getRawTransactionByBlockHashAndIndex - block, err := rawdb.ReadBlockByHash(tx, blockHash) + block, err := api.blockByHashWithSenders(tx, blockHash) if err != nil { return nil, err } @@ -158,7 +158,7 @@ func (api *APIImpl) GetTransactionByBlockNumberAndIndex(ctx context.Context, blo return nil, err } - block, err := rawdb.ReadBlockByNumber(tx, blockNum) + block, err := api.blockByNumberWithSenders(tx, blockNum) if err != nil { return nil, err } @@ -183,12 +183,7 @@ func (api *APIImpl) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, defer tx.Rollback() // https://infura.io/docs/ethereum/json-rpc/eth-getRawTransactionByBlockNumberAndIndex - blockNum, err := getBlockNumber(blockNr, tx) - if err != nil { - return nil, err - } - - block, err := rawdb.ReadBlockByNumber(tx, blockNum) + block, err := api.blockByRPCNumber(blockNr, tx) if err != nil { return nil, err } diff --git a/cmd/rpcdaemon/commands/eth_uncles.go b/cmd/rpcdaemon/commands/eth_uncles.go index 4e8207e3e2..c0dcfeebae 100644 --- a/cmd/rpcdaemon/commands/eth_uncles.go +++ b/cmd/rpcdaemon/commands/eth_uncles.go @@ -24,7 +24,7 @@ func (api *APIImpl) GetUncleByBlockNumberAndIndex(ctx context.Context, number rp if err != nil { return nil, err } - block, err := rawdb.ReadBlockByNumber(tx, blockNum) + block, err := api.blockByNumberWithSenders(tx, blockNum) if err != nil { return nil, err } @@ -56,7 +56,7 @@ func (api *APIImpl) GetUncleByBlockHashAndIndex(ctx context.Context, hash common } defer tx.Rollback() - block, err := rawdb.ReadBlockByHash(tx, hash) + block, err := api.blockByHashWithSenders(tx, hash) if err != nil { return nil, err } @@ -96,7 +96,7 @@ func (api *APIImpl) GetUncleCountByBlockNumber(ctx context.Context, number rpc.B return &n, err } - block, err := rawdb.ReadBlockByNumber(tx, blockNum) + block, err := api.blockByNumberWithSenders(tx, blockNum) if err != nil { return nil, err } diff --git a/cmd/rpcdaemon/commands/send_transaction_test.go b/cmd/rpcdaemon/commands/send_transaction_test.go index 9634ca113f..2338f40cf0 100644 --- a/cmd/rpcdaemon/commands/send_transaction_test.go +++ b/cmd/rpcdaemon/commands/send_transaction_test.go @@ -71,7 +71,7 @@ func TestSendRawTransaction(t *testing.T) { txPool := txpool.NewTxpoolClient(conn) ff := filters.New(ctx, nil, txPool, txpool.NewMiningClient(conn)) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := commands.NewEthAPI(commands.NewBaseApi(ff, stateCache), m.DB, nil, txPool, nil, 5000000) + api := commands.NewEthAPI(commands.NewBaseApi(ff, stateCache, false), m.DB, nil, txPool, nil, 5000000) buf := bytes.NewBuffer(nil) err = txn.MarshalBinary(buf) diff --git a/cmd/rpcdaemon/commands/trace_adhoc.go b/cmd/rpcdaemon/commands/trace_adhoc.go index 691dd69f69..2efe0f821c 100644 --- a/cmd/rpcdaemon/commands/trace_adhoc.go +++ b/cmd/rpcdaemon/commands/trace_adhoc.go @@ -707,7 +707,7 @@ func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash common.Ha } // Extract transactions from block - block, _, bErr := rawdb.ReadBlockByNumberWithSenders(tx, *blockNumber) + block, bErr := api.blockByNumberWithSenders(tx, *blockNumber) if bErr != nil { return nil, bErr } @@ -791,7 +791,7 @@ func (api *TraceAPIImpl) ReplayBlockTransactions(ctx context.Context, blockNrOrH parentNr -= 1 } // Extract transactions from block - block, _, bErr := rawdb.ReadBlockByNumberWithSenders(tx, blockNumber) + block, bErr := api.blockByNumberWithSenders(tx, blockNumber) if bErr != nil { return nil, bErr } diff --git a/cmd/rpcdaemon/commands/trace_adhoc_test.go b/cmd/rpcdaemon/commands/trace_adhoc_test.go index acc05a706e..050c5b4e70 100644 --- a/cmd/rpcdaemon/commands/trace_adhoc_test.go +++ b/cmd/rpcdaemon/commands/trace_adhoc_test.go @@ -19,7 +19,7 @@ import ( func TestEmptyQuery(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewTraceAPI(NewBaseApi(nil, stateCache), db, &cli.Flags{}) + api := NewTraceAPI(NewBaseApi(nil, stateCache, false), db, &cli.Flags{}) // Call GetTransactionReceipt for transaction which is not in the database var latest = rpc.LatestBlockNumber results, err := api.CallMany(context.Background(), json.RawMessage("[]"), &rpc.BlockNumberOrHash{BlockNumber: &latest}) @@ -36,7 +36,7 @@ func TestEmptyQuery(t *testing.T) { func TestCoinbaseBalance(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewTraceAPI(NewBaseApi(nil, stateCache), db, &cli.Flags{}) + api := NewTraceAPI(NewBaseApi(nil, stateCache, false), db, &cli.Flags{}) // Call GetTransactionReceipt for transaction which is not in the database var latest = rpc.LatestBlockNumber results, err := api.CallMany(context.Background(), json.RawMessage(` @@ -63,7 +63,7 @@ func TestCoinbaseBalance(t *testing.T) { func TestReplayTransaction(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewTraceAPI(NewBaseApi(nil, stateCache), db, &cli.Flags{}) + api := NewTraceAPI(NewBaseApi(nil, stateCache, false), db, &cli.Flags{}) var txnHash common.Hash if err := db.View(context.Background(), func(tx kv.Tx) error { b, err := rawdb.ReadBlockByNumber(tx, 6) @@ -91,7 +91,7 @@ func TestReplayTransaction(t *testing.T) { func TestReplayBlockTransactions(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewTraceAPI(NewBaseApi(nil, stateCache), db, &cli.Flags{}) + api := NewTraceAPI(NewBaseApi(nil, stateCache, false), db, &cli.Flags{}) // Call GetTransactionReceipt for transaction which is not in the database n := rpc.BlockNumber(6) diff --git a/cmd/rpcdaemon/commands/trace_filtering.go b/cmd/rpcdaemon/commands/trace_filtering.go index d09b54727a..ed7388f3c5 100644 --- a/cmd/rpcdaemon/commands/trace_filtering.go +++ b/cmd/rpcdaemon/commands/trace_filtering.go @@ -37,7 +37,7 @@ func (api *TraceAPIImpl) Transaction(ctx context.Context, txHash common.Hash) (P } // Extract transactions from block - block, _, bErr := rawdb.ReadBlockByNumberWithSenders(tx, *blockNumber) + block, bErr := api.blockByNumberWithSenders(tx, *blockNumber) if bErr != nil { return nil, bErr } @@ -121,17 +121,14 @@ func (api *TraceAPIImpl) Block(ctx context.Context, blockNr rpc.BlockNumber) (Pa bn := hexutil.Uint64(blockNum) // Extract transactions from block - hash, hashErr := rawdb.ReadCanonicalHash(tx, blockNum) - if hashErr != nil { - return nil, hashErr - } - block, _, bErr := rawdb.ReadBlockWithSenders(tx, hash, uint64(bn)) + block, bErr := api.blockByNumberWithSenders(tx, blockNum) if bErr != nil { return nil, bErr } if block == nil { - return nil, fmt.Errorf("could not find block %x %d", hash, uint64(bn)) + return nil, fmt.Errorf("could not find block %d", uint64(bn)) } + hash := block.Hash() parentNr := bn if parentNr > 0 { @@ -292,7 +289,7 @@ func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest, str return hashErr } - block, _, bErr := rawdb.ReadBlockWithSenders(dbtx, hash, b) + block, bErr := api.blockWithSenders(dbtx, hash, b) if bErr != nil { stream.WriteNil() return bErr diff --git a/cmd/rpcdaemon/commands/tracing.go b/cmd/rpcdaemon/commands/tracing.go index 9b1f4ac1cd..fe082919d7 100644 --- a/cmd/rpcdaemon/commands/tracing.go +++ b/cmd/rpcdaemon/commands/tracing.go @@ -44,7 +44,7 @@ func (api *PrivateDebugAPIImpl) TraceTransaction(ctx context.Context, hash commo return err } - block, _, err := rawdb.ReadBlockByHashWithSenders(tx, blockHash) + block, err := api.blockByHashWithSenders(tx, blockHash) if err != nil { return err } diff --git a/cmd/rpcdaemon/commands/txpool_api_test.go b/cmd/rpcdaemon/commands/txpool_api_test.go index 6ef762550a..b51abb704a 100644 --- a/cmd/rpcdaemon/commands/txpool_api_test.go +++ b/cmd/rpcdaemon/commands/txpool_api_test.go @@ -63,7 +63,7 @@ func TestTxPoolContent(t *testing.T) { ctx, conn := rpcdaemontest.CreateTestGrpcConn(t, m) txPool := txpool.NewTxpoolClient(conn) ff := filters.New(ctx, nil, txPool, txpool.NewMiningClient(conn)) - api := NewTxPoolAPI(NewBaseApi(ff, kvcache.New(kvcache.DefaultCoherentConfig)), m.DB, txPool) + api := NewTxPoolAPI(NewBaseApi(ff, kvcache.New(kvcache.DefaultCoherentConfig), false), m.DB, txPool) expectValue := uint64(1234) txn, err := types.SignTx(types.NewTransaction(0, common.Address{1}, uint256.NewInt(expectValue), params.TxGas, u256.Num1, nil), *types.LatestSignerForChainID(m.ChainConfig.ChainID), m.Key) -- GitLab