Skip to content

Commit 972a505

Browse files
committed
add rpc function to fetch transactions by hashes
1 parent 210ebd3 commit 972a505

File tree

6 files changed

+130
-12
lines changed

6 files changed

+130
-12
lines changed

internal/common/transaction.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
"github.com/rs/zerolog/log"
1212
)
1313

14+
type RawTransaction = map[string]interface{}
15+
1416
type Transaction struct {
1517
ChainId *big.Int `json:"chain_id" ch:"chain_id" swaggertype:"string"`
1618
Hash string `json:"hash" ch:"hash"`

internal/rpc/batcher.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ type RPCFetchBatchResult[T any] struct {
1919

2020
func RPCFetchInBatches[T any](rpc *Client, blockNumbers []*big.Int, batchSize int, batchDelay int, method string, argsFunc func(*big.Int) []interface{}) []RPCFetchBatchResult[T] {
2121
if len(blockNumbers) <= batchSize {
22-
return RPCFetchBatch[T](rpc, blockNumbers, method, argsFunc)
22+
return RPCFetchSingleBatch[*big.Int, T](rpc, blockNumbers, method, argsFunc)
2323
}
2424
chunks := common.BigIntSliceToChunks(blockNumbers, batchSize)
2525

@@ -32,7 +32,7 @@ func RPCFetchInBatches[T any](rpc *Client, blockNumbers []*big.Int, batchSize in
3232
wg.Add(1)
3333
go func(chunk []*big.Int) {
3434
defer wg.Done()
35-
resultsCh <- RPCFetchBatch[T](rpc, chunk, method, argsFunc)
35+
resultsCh <- RPCFetchSingleBatch[*big.Int, T](rpc, chunk, method, argsFunc)
3636
if batchDelay > 0 {
3737
time.Sleep(time.Duration(batchDelay) * time.Millisecond)
3838
}
@@ -51,17 +51,15 @@ func RPCFetchInBatches[T any](rpc *Client, blockNumbers []*big.Int, batchSize in
5151
return results
5252
}
5353

54-
func RPCFetchBatch[T any](rpc *Client, blockNumbers []*big.Int, method string, argsFunc func(*big.Int) []interface{}) []RPCFetchBatchResult[T] {
55-
batch := make([]gethRpc.BatchElem, len(blockNumbers))
56-
results := make([]RPCFetchBatchResult[T], len(blockNumbers))
54+
func RPCFetchSingleBatch[K any, T any](rpc *Client, keys []K, method string, argsFunc func(K) []interface{}) []RPCFetchBatchResult[T] {
55+
batch := make([]gethRpc.BatchElem, len(keys))
56+
results := make([]RPCFetchBatchResult[T], len(keys))
5757

58-
for i, blockNum := range blockNumbers {
59-
results[i] = RPCFetchBatchResult[T]{
60-
BlockNumber: blockNum,
61-
}
58+
for i, key := range keys {
59+
results[i] = RPCFetchBatchResult[T]{}
6260
batch[i] = gethRpc.BatchElem{
6361
Method: method,
64-
Args: argsFunc(blockNum),
62+
Args: argsFunc(key),
6563
Result: new(T),
6664
}
6765
}

internal/rpc/params.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ func GetBlockWithTransactionsParams(blockNum *big.Int) []interface{} {
1010
return []interface{}{hexutil.EncodeBig(blockNum), true}
1111
}
1212

13+
func GetTransactionParams(txHash string) []interface{} {
14+
return []interface{}{txHash}
15+
}
16+
1317
func GetBlockWithoutTransactionsParams(blockNum *big.Int) []interface{} {
1418
return []interface{}{hexutil.EncodeBig(blockNum), false}
1519
}

internal/rpc/rpc.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ type GetBlocksResult struct {
2727
Data common.Block
2828
}
2929

30+
type GetTransactionsResult struct {
31+
Error error
32+
Data common.Transaction
33+
}
34+
3035
type BlocksPerRequestConfig struct {
3136
Blocks int
3237
Logs int
@@ -37,13 +42,15 @@ type BlocksPerRequestConfig struct {
3742
type IRPCClient interface {
3843
GetFullBlocks(blockNumbers []*big.Int) []GetFullBlockResult
3944
GetBlocks(blockNumbers []*big.Int) []GetBlocksResult
45+
GetTransactions(txHashes []string) []GetTransactionsResult
4046
GetLatestBlockNumber() (*big.Int, error)
4147
GetChainID() *big.Int
4248
GetURL() string
4349
GetBlocksPerRequest() BlocksPerRequestConfig
4450
IsWebsocket() bool
4551
SupportsTraceBlock() bool
4652
HasCode(address string) (bool, error)
53+
Close()
4754
}
4855

4956
type Client struct {
@@ -221,7 +228,7 @@ func (rpc *Client) GetFullBlocks(blockNumbers []*big.Int) []GetFullBlockResult {
221228

222229
go func() {
223230
defer wg.Done()
224-
result := RPCFetchBatch[common.RawBlock](rpc, blockNumbers, "eth_getBlockByNumber", GetBlockWithTransactionsParams)
231+
result := RPCFetchSingleBatch[*big.Int, common.RawBlock](rpc, blockNumbers, "eth_getBlockByNumber", GetBlockWithTransactionsParams)
225232
blocks = result
226233
}()
227234

@@ -261,13 +268,28 @@ func (rpc *Client) GetBlocks(blockNumbers []*big.Int) []GetBlocksResult {
261268

262269
go func() {
263270
defer wg.Done()
264-
blocks = RPCFetchBatch[common.RawBlock](rpc, blockNumbers, "eth_getBlockByNumber", GetBlockWithoutTransactionsParams)
271+
blocks = RPCFetchSingleBatch[*big.Int, common.RawBlock](rpc, blockNumbers, "eth_getBlockByNumber", GetBlockWithoutTransactionsParams)
265272
}()
266273
wg.Wait()
267274

268275
return SerializeBlocks(rpc.chainID, blocks)
269276
}
270277

278+
func (rpc *Client) GetTransactions(txHashes []string) []GetTransactionsResult {
279+
var wg sync.WaitGroup
280+
var transactions []RPCFetchBatchResult[common.RawTransaction]
281+
282+
wg.Add(1)
283+
284+
go func() {
285+
defer wg.Done()
286+
transactions = RPCFetchSingleBatch[string, common.RawTransaction](rpc, txHashes, "eth_getTransactionByHash", GetTransactionParams)
287+
}()
288+
wg.Wait()
289+
290+
return SerializeTransactions(rpc.chainID, transactions)
291+
}
292+
271293
func (rpc *Client) GetLatestBlockNumber() (*big.Int, error) {
272294
blockNumber, err := rpc.EthClient.BlockNumber(context.Background())
273295
if err != nil {

internal/rpc/serializer.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,3 +473,15 @@ func interfaceToJsonString(value interface{}) string {
473473
}
474474
return string(jsonString)
475475
}
476+
477+
func SerializeTransactions(chainId *big.Int, transactions []RPCFetchBatchResult[common.RawTransaction]) []GetTransactionsResult {
478+
results := make([]GetTransactionsResult, 0, len(transactions))
479+
for _, transaction := range transactions {
480+
result := GetTransactionsResult{
481+
Error: transaction.Error,
482+
Data: serializeTransaction(chainId, transaction.Result, time.Time{}, nil),
483+
}
484+
results = append(results, result)
485+
}
486+
return results
487+
}

test/mocks/MockIRPCClient.go

Lines changed: 80 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)