Commit d69cb12f authored by OptimismBot's avatar OptimismBot Committed by GitHub

Merge pull request #5935 from ethereum-optimism/erigon-receipt-fetching

op-node: support erigon_getBlockReceiptsByBlockHash
parents a80c4d67 c9879ada
......@@ -179,6 +179,7 @@ func (r ReceiptsFetchingMethod) String() string {
addMaybe(DebugGetRawReceipts, "debug_getRawReceipts")
addMaybe(ParityGetBlockReceipts, "parity_getBlockReceipts")
addMaybe(EthGetBlockReceipts, "eth_getBlockReceipts")
addMaybe(ErigonGetBlockReceiptsByBlockHash, "erigon_getBlockReceiptsByBlockHash")
addMaybe(^ReceiptsFetchingMethod(0), "unknown") // if anything is left, describe it as unknown
return out
}
......@@ -230,10 +231,9 @@ const (
// - Nethermind: https://docs.nethermind.io/nethermind/ethereum-client/json-rpc/parity#parity_getblockreceipts
ParityGetBlockReceipts
// EthGetBlockReceipts is a non-standard receipt fetching method in the eth namespace,
// supported by some RPC platforms and Erigon.
// supported by some RPC platforms.
// Available in:
// - Alchemy: 500 CU total (and deprecated)
// - Erigon: free
// - QuickNode: 59 credits total (does not seem to work with block hash arg, inaccurate docs)
// Method: eth_getBlockReceipts
// Params:
......@@ -243,7 +243,21 @@ const (
// See:
// - QuickNode: https://www.quicknode.com/docs/ethereum/eth_getBlockReceipts
// - Alchemy: https://docs.alchemy.com/reference/eth-getblockreceipts
// Erigon has this available, but does not support block-hash argument to the method:
// https://github.com/ledgerwatch/erigon/blob/287a3d1d6c90fc6a7a088b5ae320f93600d5a167/cmd/rpcdaemon/commands/eth_receipts.go#L571
EthGetBlockReceipts
// ErigonGetBlockReceiptsByBlockHash is an Erigon-specific receipt fetching method,
// the same as EthGetBlockReceipts but supporting a block-hash argument.
// Available in:
// - Erigon
// Method: erigon_getBlockReceiptsByBlockHash
// Params:
// - Erigon: string, hex-encoded block hash
// Returns:
// - Erigon: array of json-ified receipts
// See:
// https://github.com/ledgerwatch/erigon/blob/287a3d1d6c90fc6a7a088b5ae320f93600d5a167/cmd/rpcdaemon/commands/erigon_receipts.go#LL391C24-L391C51
ErigonGetBlockReceiptsByBlockHash
// Other:
// - 250 credits, not supported, strictly worse than other options. In quicknode price-table.
......@@ -269,13 +283,14 @@ func AvailableReceiptsFetchingMethods(kind RPCProviderKind) ReceiptsFetchingMeth
case RPCKindDebugGeth:
return DebugGetRawReceipts | EthGetTransactionReceiptBatch
case RPCKindErigon:
return EthGetBlockReceipts | EthGetTransactionReceiptBatch
return ErigonGetBlockReceiptsByBlockHash | EthGetTransactionReceiptBatch
case RPCKindBasic:
return EthGetTransactionReceiptBatch
case RPCKindAny:
// if it's any kind of RPC provider, then try all methods
return AlchemyGetTransactionReceipts | EthGetBlockReceipts |
DebugGetRawReceipts | ParityGetBlockReceipts | EthGetTransactionReceiptBatch
DebugGetRawReceipts | ErigonGetBlockReceiptsByBlockHash |
ParityGetBlockReceipts | EthGetTransactionReceiptBatch
default:
return EthGetTransactionReceiptBatch
}
......@@ -310,6 +325,9 @@ func PickBestReceiptsFetchingMethod(kind RPCProviderKind, available ReceiptsFetc
if available&DebugGetRawReceipts != 0 {
return DebugGetRawReceipts
}
if available&ErigonGetBlockReceiptsByBlockHash != 0 {
return ErigonGetBlockReceiptsByBlockHash
}
if available&EthGetBlockReceipts != 0 {
return EthGetBlockReceipts
}
......@@ -428,6 +446,8 @@ func (job *receiptsFetchingJob) runAltMethod(ctx context.Context, m ReceiptsFetc
err = job.client.CallContext(ctx, &result, "parity_getBlockReceipts", job.block.Hash)
case EthGetBlockReceipts:
err = job.client.CallContext(ctx, &result, "eth_getBlockReceipts", job.block.Hash)
case ErigonGetBlockReceiptsByBlockHash:
err = job.client.CallContext(ctx, &result, "erigon_getBlockReceiptsByBlockHash", job.block.Hash)
default:
err = fmt.Errorf("unknown receipt fetching method: %d", uint64(m))
}
......
......@@ -40,6 +40,15 @@ func (b *ethBackend) GetBlockReceipts(id string) ([]*types.Receipt, error) {
return out[0].([]*types.Receipt), *out[1].(*error)
}
type erigonBackend struct {
*mock.Mock
}
func (b *erigonBackend) GetBlockReceiptsByBlockHash(id string) ([]*types.Receipt, error) {
out := b.Mock.MethodCalled("erigon_getBlockReceiptsByBlockHash", id)
return out[0].([]*types.Receipt), *out[1].(*error)
}
type alchemyBackend struct {
*mock.Mock
}
......@@ -99,6 +108,7 @@ func (tc *ReceiptsTestCase) Run(t *testing.T) {
require.NoError(t, srv.RegisterName("alchemy", &alchemyBackend{Mock: m}))
require.NoError(t, srv.RegisterName("debug", &debugBackend{Mock: m}))
require.NoError(t, srv.RegisterName("parity", &parityBackend{Mock: m}))
require.NoError(t, srv.RegisterName("erigon", &erigonBackend{Mock: m}))
block, requests := tc.setup(t)
......@@ -127,6 +137,8 @@ func (tc *ReceiptsTestCase) Run(t *testing.T) {
m.On("parity_getBlockReceipts", block.Hash.String()).Once().Return(req.result, &req.err)
case EthGetBlockReceipts:
m.On("eth_getBlockReceipts", block.Hash.String()).Once().Return(req.result, &req.err)
case ErigonGetBlockReceiptsByBlockHash:
m.On("erigon_getBlockReceiptsByBlockHash", block.Hash.String()).Once().Return(req.result, &req.err)
default:
t.Fatalf("unrecognized request method: %d", uint64(req.method))
}
......@@ -286,7 +298,7 @@ func TestEthClient_FetchReceipts(t *testing.T) {
{
name: "erigon",
providerKind: RPCKindErigon,
setup: fallbackCase(4, EthGetBlockReceipts),
setup: fallbackCase(4, ErigonGetBlockReceiptsByBlockHash),
},
{
name: "basic",
......@@ -305,6 +317,7 @@ func TestEthClient_FetchReceipts(t *testing.T) {
setup: fallbackCase(4,
AlchemyGetTransactionReceipts,
DebugGetRawReceipts,
ErigonGetBlockReceiptsByBlockHash,
EthGetBlockReceipts,
ParityGetBlockReceipts,
),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment