mirror of
https://github.com/grassrootseconomics/cic-chain-events.git
synced 2025-07-01 00:32:49 +02:00
* move filters to internal folder * rpc block fetcher * add benchmarks: goos: linux goarch: amd64 pkg: github.com/grassrootseconomics/cic-chain-events/pkg/fetch cpu: AMD EPYC Processor Benchmark_RPC Benchmark_RPC/RPC_Block_Fetcher_Benchmark Benchmark_RPC/RPC_Block_Fetcher_Benchmark-4 25 46000646 ns/op 221697 B/op 844 allocs/op Benchmark_GraphQL Benchmark_GraphQL/GraphQL_Block_Fetcher_Benchmark Benchmark_GraphQL/GraphQL_Block_Fetcher_Benchmark-4 56 21219962 ns/op 56686 B/op 94 allocs/op PASS ok github.com/grassrootseconomics/cic-chain-events/pkg/fetch 2.920s
91 lines
2.1 KiB
Go
91 lines
2.1 KiB
Go
package fetch
|
|
|
|
import (
|
|
"context"
|
|
"math/big"
|
|
"strings"
|
|
|
|
"github.com/celo-org/celo-blockchain/common/hexutil"
|
|
"github.com/celo-org/celo-blockchain/core/types"
|
|
celo "github.com/grassrootseconomics/cic-celo-sdk"
|
|
"github.com/grassrootseconomics/w3-celo-patch/module/eth"
|
|
"github.com/grassrootseconomics/w3-celo-patch/w3types"
|
|
)
|
|
|
|
type RPCOpts struct {
|
|
RPCProvider *celo.Provider
|
|
}
|
|
|
|
type RPC struct {
|
|
provider *celo.Provider
|
|
}
|
|
|
|
func NewRPCFetcher(o RPCOpts) Fetch {
|
|
return &RPC{
|
|
provider: o.RPCProvider,
|
|
}
|
|
}
|
|
|
|
// This method makes 2 calls. 1 for the block and 1 batched call for txs + receipts.
|
|
// Should work on free tier RPC services.
|
|
func (f *RPC) Block(ctx context.Context, blockNumber uint64) (FetchResponse, error) {
|
|
var (
|
|
block types.Block
|
|
|
|
fetchResponse FetchResponse
|
|
)
|
|
|
|
if err := f.provider.Client.CallCtx(
|
|
ctx,
|
|
eth.BlockByNumber(big.NewInt(int64(blockNumber))).Returns(&block),
|
|
); err != nil {
|
|
return FetchResponse{}, err
|
|
}
|
|
|
|
txCount := len(block.Transactions())
|
|
batchCalls := make([]w3types.Caller, txCount*2)
|
|
|
|
txs := make([]types.Transaction, txCount)
|
|
txsReceipt := make([]types.Receipt, txCount)
|
|
|
|
for i, tx := range block.Transactions() {
|
|
batchCalls[i] = eth.Tx(tx.Hash()).Returns(&txs[i])
|
|
batchCalls[txCount+i] = eth.TxReceipt(tx.Hash()).Returns(&txsReceipt[i])
|
|
}
|
|
|
|
if err := f.provider.Client.CallCtx(
|
|
ctx,
|
|
batchCalls...,
|
|
); err != nil {
|
|
return FetchResponse{}, nil
|
|
}
|
|
|
|
for i := 0; i < txCount; i++ {
|
|
tx := Transaction{}
|
|
|
|
tx.Block.Number = block.NumberU64()
|
|
tx.Block.Timestamp = hexutil.EncodeUint64(block.Time())
|
|
tx.Hash = txsReceipt[i].TxHash.Hex()
|
|
tx.Index = txsReceipt[i].TransactionIndex
|
|
|
|
from, err := types.Sender(types.LatestSignerForChainID(txs[i].ChainId()), &txs[i])
|
|
if err != nil {
|
|
return FetchResponse{}, err
|
|
}
|
|
|
|
tx.From.Address = strings.ToLower(from.Hex())
|
|
tx.To.Address = strings.ToLower(txs[i].To().Hex())
|
|
tx.Value = hexutil.EncodeBig(txs[i].Value())
|
|
tx.InputData = hexutil.Encode(txs[i].Data())
|
|
tx.Status = txsReceipt[i].Status
|
|
tx.GasUsed = txsReceipt[i].GasUsed
|
|
|
|
fetchResponse.Data.Block.Transactions = append(
|
|
fetchResponse.Data.Block.Transactions,
|
|
tx,
|
|
)
|
|
}
|
|
|
|
return fetchResponse, nil
|
|
}
|