Commit ff9a287d authored by protolambda's avatar protolambda

op-node: support erigon_getBlockReceiptsByBlockHash

parent 129032f1
...@@ -179,6 +179,7 @@ func (r ReceiptsFetchingMethod) String() string { ...@@ -179,6 +179,7 @@ func (r ReceiptsFetchingMethod) String() string {
addMaybe(DebugGetRawReceipts, "debug_getRawReceipts") addMaybe(DebugGetRawReceipts, "debug_getRawReceipts")
addMaybe(ParityGetBlockReceipts, "parity_getBlockReceipts") addMaybe(ParityGetBlockReceipts, "parity_getBlockReceipts")
addMaybe(EthGetBlockReceipts, "eth_getBlockReceipts") addMaybe(EthGetBlockReceipts, "eth_getBlockReceipts")
addMaybe(ErigonGetBlockReceiptsByBlockHash, "erigon_getBlockReceiptsByBlockHash")
addMaybe(^ReceiptsFetchingMethod(0), "unknown") // if anything is left, describe it as unknown addMaybe(^ReceiptsFetchingMethod(0), "unknown") // if anything is left, describe it as unknown
return out return out
} }
...@@ -230,10 +231,9 @@ const ( ...@@ -230,10 +231,9 @@ const (
// - Nethermind: https://docs.nethermind.io/nethermind/ethereum-client/json-rpc/parity#parity_getblockreceipts // - Nethermind: https://docs.nethermind.io/nethermind/ethereum-client/json-rpc/parity#parity_getblockreceipts
ParityGetBlockReceipts ParityGetBlockReceipts
// EthGetBlockReceipts is a non-standard receipt fetching method in the eth namespace, // 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: // Available in:
// - Alchemy: 500 CU total (and deprecated) // - Alchemy: 500 CU total (and deprecated)
// - Erigon: free
// - QuickNode: 59 credits total (does not seem to work with block hash arg, inaccurate docs) // - QuickNode: 59 credits total (does not seem to work with block hash arg, inaccurate docs)
// Method: eth_getBlockReceipts // Method: eth_getBlockReceipts
// Params: // Params:
...@@ -243,7 +243,21 @@ const ( ...@@ -243,7 +243,21 @@ const (
// See: // See:
// - QuickNode: https://www.quicknode.com/docs/ethereum/eth_getBlockReceipts // - QuickNode: https://www.quicknode.com/docs/ethereum/eth_getBlockReceipts
// - Alchemy: https://docs.alchemy.com/reference/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 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: // Other:
// - 250 credits, not supported, strictly worse than other options. In quicknode price-table. // - 250 credits, not supported, strictly worse than other options. In quicknode price-table.
...@@ -269,13 +283,14 @@ func AvailableReceiptsFetchingMethods(kind RPCProviderKind) ReceiptsFetchingMeth ...@@ -269,13 +283,14 @@ func AvailableReceiptsFetchingMethods(kind RPCProviderKind) ReceiptsFetchingMeth
case RPCKindDebugGeth: case RPCKindDebugGeth:
return DebugGetRawReceipts | EthGetTransactionReceiptBatch return DebugGetRawReceipts | EthGetTransactionReceiptBatch
case RPCKindErigon: case RPCKindErigon:
return EthGetBlockReceipts | EthGetTransactionReceiptBatch return ErigonGetBlockReceiptsByBlockHash | EthGetTransactionReceiptBatch
case RPCKindBasic: case RPCKindBasic:
return EthGetTransactionReceiptBatch return EthGetTransactionReceiptBatch
case RPCKindAny: case RPCKindAny:
// if it's any kind of RPC provider, then try all methods // if it's any kind of RPC provider, then try all methods
return AlchemyGetTransactionReceipts | EthGetBlockReceipts | return AlchemyGetTransactionReceipts | EthGetBlockReceipts |
DebugGetRawReceipts | ParityGetBlockReceipts | EthGetTransactionReceiptBatch DebugGetRawReceipts | ErigonGetBlockReceiptsByBlockHash |
ParityGetBlockReceipts | EthGetTransactionReceiptBatch
default: default:
return EthGetTransactionReceiptBatch return EthGetTransactionReceiptBatch
} }
...@@ -310,6 +325,9 @@ func PickBestReceiptsFetchingMethod(kind RPCProviderKind, available ReceiptsFetc ...@@ -310,6 +325,9 @@ func PickBestReceiptsFetchingMethod(kind RPCProviderKind, available ReceiptsFetc
if available&DebugGetRawReceipts != 0 { if available&DebugGetRawReceipts != 0 {
return DebugGetRawReceipts return DebugGetRawReceipts
} }
if available&ErigonGetBlockReceiptsByBlockHash != 0 {
return ErigonGetBlockReceiptsByBlockHash
}
if available&EthGetBlockReceipts != 0 { if available&EthGetBlockReceipts != 0 {
return EthGetBlockReceipts return EthGetBlockReceipts
} }
...@@ -428,6 +446,8 @@ func (job *receiptsFetchingJob) runAltMethod(ctx context.Context, m ReceiptsFetc ...@@ -428,6 +446,8 @@ func (job *receiptsFetchingJob) runAltMethod(ctx context.Context, m ReceiptsFetc
err = job.client.CallContext(ctx, &result, "parity_getBlockReceipts", job.block.Hash) err = job.client.CallContext(ctx, &result, "parity_getBlockReceipts", job.block.Hash)
case EthGetBlockReceipts: case EthGetBlockReceipts:
err = job.client.CallContext(ctx, &result, "eth_getBlockReceipts", job.block.Hash) 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: default:
err = fmt.Errorf("unknown receipt fetching method: %d", uint64(m)) err = fmt.Errorf("unknown receipt fetching method: %d", uint64(m))
} }
......
...@@ -40,6 +40,15 @@ func (b *ethBackend) GetBlockReceipts(id string) ([]*types.Receipt, error) { ...@@ -40,6 +40,15 @@ func (b *ethBackend) GetBlockReceipts(id string) ([]*types.Receipt, error) {
return out[0].([]*types.Receipt), *out[1].(*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 { type alchemyBackend struct {
*mock.Mock *mock.Mock
} }
...@@ -99,6 +108,7 @@ func (tc *ReceiptsTestCase) Run(t *testing.T) { ...@@ -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("alchemy", &alchemyBackend{Mock: m}))
require.NoError(t, srv.RegisterName("debug", &debugBackend{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("parity", &parityBackend{Mock: m}))
require.NoError(t, srv.RegisterName("erigon", &erigonBackend{Mock: m}))
block, requests := tc.setup(t) block, requests := tc.setup(t)
...@@ -127,6 +137,8 @@ func (tc *ReceiptsTestCase) Run(t *testing.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) m.On("parity_getBlockReceipts", block.Hash.String()).Once().Return(req.result, &req.err)
case EthGetBlockReceipts: case EthGetBlockReceipts:
m.On("eth_getBlockReceipts", block.Hash.String()).Once().Return(req.result, &req.err) 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: default:
t.Fatalf("unrecognized request method: %d", uint64(req.method)) t.Fatalf("unrecognized request method: %d", uint64(req.method))
} }
...@@ -286,7 +298,7 @@ func TestEthClient_FetchReceipts(t *testing.T) { ...@@ -286,7 +298,7 @@ func TestEthClient_FetchReceipts(t *testing.T) {
{ {
name: "erigon", name: "erigon",
providerKind: RPCKindErigon, providerKind: RPCKindErigon,
setup: fallbackCase(4, EthGetBlockReceipts), setup: fallbackCase(4, ErigonGetBlockReceiptsByBlockHash),
}, },
{ {
name: "basic", name: "basic",
...@@ -305,6 +317,7 @@ func TestEthClient_FetchReceipts(t *testing.T) { ...@@ -305,6 +317,7 @@ func TestEthClient_FetchReceipts(t *testing.T) {
setup: fallbackCase(4, setup: fallbackCase(4,
AlchemyGetTransactionReceipts, AlchemyGetTransactionReceipts,
DebugGetRawReceipts, DebugGetRawReceipts,
ErigonGetBlockReceiptsByBlockHash,
EthGetBlockReceipts, EthGetBlockReceipts,
ParityGetBlockReceipts, 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