Skip to content

Commit 2a244ee

Browse files
committed
utilize eth_getBlockReceipts if possible
1 parent 6c6514f commit 2a244ee

File tree

12 files changed

+309
-71
lines changed

12 files changed

+309
-71
lines changed

README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,43 @@ rpc:
136136
batchDelay: 100
137137
```
138138

139+
#### RPC Block Receipts Enabled
140+
If this is `true`, will use `eth_getBlockReceipts` instead of `eth_getLogs`. Allows getting receipt data for transactions, but is not supported by every RPC. Default is `true`, but it will try to detect if the RPC supports `eth_getBlockReceipts` automatically.
141+
142+
cmd: `--rpc-block-receipts-enabled`
143+
env: `RPC_BLOCKRECEIPTS_ENABLED`
144+
yaml:
145+
```yaml
146+
rpc:
147+
blockReceipts:
148+
enabled: true
149+
```
150+
151+
#### RPC Block Receipts Blocks Per Request
152+
How many blocks at a time to fetch block receipts for from the RPC. Default is 250.
153+
Has no effect if it's larger than RPC blocks per request.
154+
155+
cmd: `--rpc-block-receipts-blocksPerRequest`
156+
env: `RPC_BLOCKRECEIPTS_BLOCKSPERREQUEST`
157+
yaml:
158+
```yaml
159+
rpc:
160+
blockReceipts:
161+
blocksPerRequest: 100
162+
```
163+
164+
#### RPC Block Receipts Batch Delay
165+
Milliseconds to wait between batches of block receipts when fetching from the RPC. Default is 0.
166+
167+
cmd: `--rpc-block-receipts-batchDelay`
168+
env: `RPC_BLOCKRECEIPTS_BATCHDELAY`
169+
yaml:
170+
```yaml
171+
rpc:
172+
blockReceipts:
173+
batchDelay: 100
174+
```
175+
139176
#### RPC Traces Enabled
140177
Whether to enable fetching traces from the RPC. Default is `true`, but it will try to detect if the RPC supports traces automatically.
141178

cmd/root.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ func init() {
4141
rootCmd.PersistentFlags().Int("rpc-blocks-batchDelay", 0, "Milliseconds to wait between batches of blocks when fetching from the RPC")
4242
rootCmd.PersistentFlags().Int("rpc-logs-blocksPerRequest", 0, "How many blocks to fetch logs per request")
4343
rootCmd.PersistentFlags().Int("rpc-logs-batchDelay", 0, "Milliseconds to wait between batches of logs when fetching from the RPC")
44+
rootCmd.PersistentFlags().Bool("rpc-blockReceipts-enabled", true, "Whether to enable fetching block receipts from the RPC")
45+
rootCmd.PersistentFlags().Int("rpc-blockReceipts-blocksPerRequest", 0, "How many blocks to fetch receipts for per request")
46+
rootCmd.PersistentFlags().Int("rpc-blockReceipts-batchDelay", 0, "Milliseconds to wait between batches of receipts when fetching from the RPC")
4447
rootCmd.PersistentFlags().Bool("rpc-traces-enabled", true, "Whether to enable fetching traces from the RPC")
4548
rootCmd.PersistentFlags().Int("rpc-traces-blocksPerRequest", 0, "How many blocks to fetch traces per request")
4649
rootCmd.PersistentFlags().Int("rpc-traces-batchDelay", 0, "Milliseconds to wait between batches of traces when fetching from the RPC")
@@ -89,6 +92,9 @@ func init() {
8992
viper.BindPFlag("rpc.blocks.batchDelay", rootCmd.PersistentFlags().Lookup("rpc-blocks-batchDelay"))
9093
viper.BindPFlag("rpc.logs.blocksPerRequest", rootCmd.PersistentFlags().Lookup("rpc-logs-blocksPerRequest"))
9194
viper.BindPFlag("rpc.logs.batchDelay", rootCmd.PersistentFlags().Lookup("rpc-logs-batchDelay"))
95+
viper.BindPFlag("rpc.blockReceipts.enabled", rootCmd.PersistentFlags().Lookup("rpc-blockReceipts-enabled"))
96+
viper.BindPFlag("rpc.blockReceipts.blocksPerRequest", rootCmd.PersistentFlags().Lookup("rpc-blockReceipts-blocksPerRequest"))
97+
viper.BindPFlag("rpc.blockReceipts.batchDelay", rootCmd.PersistentFlags().Lookup("rpc-blockReceipts-batchDelay"))
9298
viper.BindPFlag("rpc.traces.enabled", rootCmd.PersistentFlags().Lookup("rpc-traces-enabled"))
9399
viper.BindPFlag("rpc.traces.blocksPerRequest", rootCmd.PersistentFlags().Lookup("rpc-traces-blocksPerRequest"))
94100
viper.BindPFlag("rpc.traces.batchDelay", rootCmd.PersistentFlags().Lookup("rpc-traces-batchDelay"))

configs/config.example.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ rpc:
55
logs:
66
blocksPerRequest: 400
77
batchDelay: 100
8+
blockReceipts:
9+
enabled: true
10+
blocksPerRequest: 500
11+
batchDelay: 100
812
traces:
913
enabled: true
1014
blocksPerRequest: 200
@@ -29,6 +33,11 @@ failureRecoverer:
2933
interval: 10000
3034
blocksPerRun: 100
3135

36+
reorgHandler:
37+
enabled: true
38+
interval: 1000
39+
blocksPerScan: 50
40+
3241
storage:
3342
main:
3443
clickhouse:

configs/config.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,22 +81,22 @@ type RedisConfig struct {
8181
DB int `mapstructure:"db"`
8282
}
8383

84-
type RPCBatchSizeConfig struct {
84+
type RPCBatchRequestConfig struct {
8585
BlocksPerRequest int `mapstructure:"blocksPerRequest"`
8686
BatchDelay int `mapstructure:"batchDelay"`
8787
}
8888

89-
type RPCTracesConfig struct {
90-
Enabled bool `mapstructure:"enabled"`
91-
BlocksPerRequest int `mapstructure:"blocksPerRequest"`
92-
BatchDelay int `mapstructure:"batchDelay"`
89+
type ToggleableRPCBatchRequestConfig struct {
90+
Enabled bool `mapstructure:"enabled"`
91+
RPCBatchRequestConfig
9392
}
9493

9594
type RPCConfig struct {
96-
URL string `mapstructure:"url"`
97-
Blocks RPCBatchSizeConfig `mapstructure:"blocks"`
98-
Logs RPCBatchSizeConfig `mapstructure:"logs"`
99-
Traces RPCTracesConfig `mapstructure:"traces"`
95+
URL string `mapstructure:"url"`
96+
Blocks RPCBatchRequestConfig `mapstructure:"blocks"`
97+
Logs RPCBatchRequestConfig `mapstructure:"logs"`
98+
BlockReceipts ToggleableRPCBatchRequestConfig `mapstructure:"blockReceipts"`
99+
Traces ToggleableRPCBatchRequestConfig `mapstructure:"traces"`
100100
}
101101

102102
type APIConfig struct {

internal/common/log.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,5 @@ type Log struct {
1818
}
1919

2020
type RawLogs = []map[string]interface{}
21+
type RawReceipts = []RawReceipt
22+
type RawReceipt = map[string]interface{}

internal/common/transaction.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,13 @@ type Transaction struct {
2525
R *big.Int `json:"r"`
2626
S *big.Int `json:"s"`
2727
V *big.Int `json:"v"`
28-
AccessListJson string `json:"access_list_json"`
28+
AccessListJson *string `json:"access_list_json"`
29+
ContractAddress *string `json:"contract_address"`
30+
GasUsed *uint64 `json:"gas_used"`
31+
CumulativeGasUsed *uint64 `json:"cumulative_gas_used"`
32+
EffectiveGasPrice *big.Int `json:"effective_gas_price"`
33+
BlobGasUsed *uint64 `json:"blob_gas_used"`
34+
BlobGasPrice *big.Int `json:"blob_gas_price"`
35+
LogsBloom *string `json:"logs_bloom"`
36+
Status *uint64 `json:"status"`
2937
}

internal/rpc/params.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ func GetLogsParams(blockNum *big.Int) []interface{} {
2121
func TraceBlockParams(blockNum *big.Int) []interface{} {
2222
return []interface{}{hexutil.EncodeBig(blockNum)}
2323
}
24+
25+
func GetBlockReceiptsParams(blockNum *big.Int) []interface{} {
26+
return []interface{}{hexutil.EncodeBig(blockNum)}
27+
}

internal/rpc/rpc.go

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ type GetBlocksResult struct {
2727
}
2828

2929
type BlocksPerRequestConfig struct {
30-
Blocks int
31-
Logs int
32-
Traces int
30+
Blocks int
31+
Logs int
32+
Traces int
33+
Receipts int
3334
}
3435

3536
type IRPCClient interface {
@@ -44,13 +45,14 @@ type IRPCClient interface {
4445
}
4546

4647
type Client struct {
47-
RPCClient *gethRpc.Client
48-
EthClient *ethclient.Client
49-
supportsTraceBlock bool
50-
isWebsocket bool
51-
url string
52-
chainID *big.Int
53-
blocksPerRequest BlocksPerRequestConfig
48+
RPCClient *gethRpc.Client
49+
EthClient *ethclient.Client
50+
supportsTraceBlock bool
51+
supportsBlockReceipts bool
52+
isWebsocket bool
53+
url string
54+
chainID *big.Int
55+
blocksPerRequest BlocksPerRequestConfig
5456
}
5557

5658
func Initialize() (IRPCClient, error) {
@@ -118,12 +120,29 @@ func (rpc *Client) checkSupportedMethods() error {
118120
}
119121
log.Debug().Msg("eth_getBlockByNumber method supported")
120122

121-
var getLogsResult interface{}
122-
logsErr := rpc.RPCClient.Call(&getLogsResult, "eth_getLogs", map[string]string{"fromBlock": "0x0", "toBlock": "0x0"})
123-
if logsErr != nil {
124-
return fmt.Errorf("eth_getLogs method not supported: %v", logsErr)
123+
if config.Cfg.RPC.BlockReceipts.Enabled {
124+
var getBlockReceiptsResult interface{}
125+
receiptsErr := rpc.RPCClient.Call(&getBlockReceiptsResult, "eth_getBlockReceipts", "latest")
126+
if receiptsErr != nil {
127+
log.Warn().Err(receiptsErr).Msg("eth_getBlockReceipts method not supported")
128+
return fmt.Errorf("eth_getBlockReceipts method not supported: %v", receiptsErr)
129+
} else {
130+
rpc.supportsBlockReceipts = true
131+
log.Debug().Msg("eth_getBlockReceipts method supported")
132+
}
133+
} else {
134+
rpc.supportsBlockReceipts = false
135+
log.Debug().Msg("eth_getBlockReceipts method disabled")
136+
}
137+
138+
if !rpc.supportsBlockReceipts {
139+
var getLogsResult interface{}
140+
logsErr := rpc.RPCClient.Call(&getLogsResult, "eth_getLogs", map[string]string{"fromBlock": "0x0", "toBlock": "0x0"})
141+
if logsErr != nil {
142+
return fmt.Errorf("eth_getLogs method not supported: %v", logsErr)
143+
}
144+
log.Debug().Msg("eth_getLogs method supported")
125145
}
126-
log.Debug().Msg("eth_getLogs method supported")
127146

128147
var traceBlockResult interface{}
129148
if config.Cfg.RPC.Traces.Enabled {
@@ -147,33 +166,44 @@ func (rpc *Client) setChainID() error {
147166

148167
func (rpc *Client) GetFullBlocks(blockNumbers []*big.Int) []GetFullBlockResult {
149168
var wg sync.WaitGroup
150-
var blocks []RPCFetchBatchResult[common.RawBlock]
151-
var logs []RPCFetchBatchResult[common.RawLogs]
152-
var traces []RPCFetchBatchResult[common.RawTraces]
153-
169+
var blocks *[]RPCFetchBatchResult[common.RawBlock]
170+
var logs *[]RPCFetchBatchResult[common.RawLogs]
171+
var traces *[]RPCFetchBatchResult[common.RawTraces]
172+
var receipts *[]RPCFetchBatchResult[common.RawReceipts]
154173
wg.Add(2)
155174

156175
go func() {
157176
defer wg.Done()
158-
blocks = RPCFetchBatch[common.RawBlock](rpc, blockNumbers, "eth_getBlockByNumber", GetBlockWithTransactionsParams)
177+
result := RPCFetchBatch[common.RawBlock](rpc, blockNumbers, "eth_getBlockByNumber", GetBlockWithTransactionsParams)
178+
blocks = &result
159179
}()
160180

161-
go func() {
162-
defer wg.Done()
163-
logs = RPCFetchInBatches[common.RawLogs](rpc, blockNumbers, rpc.blocksPerRequest.Logs, config.Cfg.RPC.Logs.BatchDelay, "eth_getLogs", GetLogsParams)
164-
}()
181+
if rpc.supportsBlockReceipts {
182+
go func() {
183+
defer wg.Done()
184+
result := RPCFetchInBatches[common.RawReceipts](rpc, blockNumbers, rpc.blocksPerRequest.Receipts, config.Cfg.RPC.BlockReceipts.BatchDelay, "eth_getBlockReceipts", GetBlockReceiptsParams)
185+
receipts = &result
186+
}()
187+
} else {
188+
go func() {
189+
defer wg.Done()
190+
result := RPCFetchInBatches[common.RawLogs](rpc, blockNumbers, rpc.blocksPerRequest.Logs, config.Cfg.RPC.Logs.BatchDelay, "eth_getLogs", GetLogsParams)
191+
logs = &result
192+
}()
193+
}
165194

166195
if rpc.supportsTraceBlock {
167196
wg.Add(1)
168197
go func() {
169198
defer wg.Done()
170-
traces = RPCFetchInBatches[common.RawTraces](rpc, blockNumbers, rpc.blocksPerRequest.Traces, config.Cfg.RPC.Traces.BatchDelay, "trace_block", TraceBlockParams)
199+
result := RPCFetchInBatches[common.RawTraces](rpc, blockNumbers, rpc.blocksPerRequest.Traces, config.Cfg.RPC.Traces.BatchDelay, "trace_block", TraceBlockParams)
200+
traces = &result
171201
}()
172202
}
173203

174204
wg.Wait()
175205

176-
return SerializeFullBlocks(rpc.chainID, blocks, logs, traces)
206+
return SerializeFullBlocks(rpc.chainID, blocks, logs, traces, receipts)
177207
}
178208

179209
func (rpc *Client) GetBlocks(blockNumbers []*big.Int) []GetBlocksResult {

0 commit comments

Comments
 (0)