inline-docs: Describe RPC fetcher

This commit is contained in:
Mohamed Sohail 2023-01-19 11:36:38 +03:00
parent f29e2a9ce7
commit a465c57f1b
Signed by: kamikazechaser
GPG Key ID: 7DD45520C01CD85D

View File

@ -12,26 +12,28 @@ import (
"github.com/grassrootseconomics/w3-celo-patch/w3types" "github.com/grassrootseconomics/w3-celo-patch/w3types"
) )
// RPCOpts reprsents the required paramters for an RPC fetcher.
type RPCOpts struct { type RPCOpts struct {
RPCProvider *celo.Provider RPCProvider *celo.Provider
} }
// RPC is a RPC based block and transaction fetcher.
type RPC struct { type RPC struct {
provider *celo.Provider provider *celo.Provider
} }
// NewRPCFetcher returns a new RPC fetcher which implemnts Fetch.
// Note: No rate limiting feeature.
func NewRPCFetcher(o RPCOpts) Fetch { func NewRPCFetcher(o RPCOpts) Fetch {
return &RPC{ return &RPC{
provider: o.RPCProvider, provider: o.RPCProvider,
} }
} }
// This method makes 2 calls. 1 for the block and 1 batched call for txs + receipts. // Block fetches via RPC and transforms the response to adapt to the GraphQL JSON response struct.
// Should work on free tier RPC services.
func (f *RPC) Block(ctx context.Context, blockNumber uint64) (FetchResponse, error) { func (f *RPC) Block(ctx context.Context, blockNumber uint64) (FetchResponse, error) {
var ( var (
block types.Block block types.Block
fetchResponse FetchResponse fetchResponse FetchResponse
) )
@ -39,7 +41,7 @@ func (f *RPC) Block(ctx context.Context, blockNumber uint64) (FetchResponse, err
ctx, ctx,
eth.BlockByNumber(big.NewInt(int64(blockNumber))).Returns(&block), eth.BlockByNumber(big.NewInt(int64(blockNumber))).Returns(&block),
); err != nil { ); err != nil {
return FetchResponse{}, err return fetchResponse, err
} }
txCount := len(block.Transactions()) txCount := len(block.Transactions())
@ -48,6 +50,7 @@ func (f *RPC) Block(ctx context.Context, blockNumber uint64) (FetchResponse, err
txs := make([]types.Transaction, txCount) txs := make([]types.Transaction, txCount)
txsReceipt := make([]types.Receipt, txCount) txsReceipt := make([]types.Receipt, txCount)
// Prepare batch calls.
for i, tx := range block.Transactions() { for i, tx := range block.Transactions() {
batchCalls[i] = eth.Tx(tx.Hash()).Returns(&txs[i]) batchCalls[i] = eth.Tx(tx.Hash()).Returns(&txs[i])
batchCalls[txCount+i] = eth.TxReceipt(tx.Hash()).Returns(&txsReceipt[i]) batchCalls[txCount+i] = eth.TxReceipt(tx.Hash()).Returns(&txsReceipt[i])
@ -57,32 +60,36 @@ func (f *RPC) Block(ctx context.Context, blockNumber uint64) (FetchResponse, err
ctx, ctx,
batchCalls..., batchCalls...,
); err != nil { ); err != nil {
return FetchResponse{}, nil return fetchResponse, err
} }
// Transform response and adapt to FetchResponse.
for i := 0; i < txCount; i++ { for i := 0; i < txCount; i++ {
tx := Transaction{} var txObject Transaction
tx.Block.Number = block.NumberU64() txObject.Block.Number = block.NumberU64()
tx.Block.Timestamp = hexutil.EncodeUint64(block.Time()) txObject.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]) from, err := types.Sender(types.LatestSignerForChainID(txs[i].ChainId()), &txs[i])
if err != nil { if err != nil {
return FetchResponse{}, err return fetchResponse, err
} }
txObject.From.Address = strings.ToLower(from.Hex())
// This check ignores contract deployment transactions.
if txs[i].To() != nil {
txObject.To.Address = strings.ToLower(txs[i].To().Hex())
}
txObject.Value = hexutil.EncodeBig(txs[i].Value())
txObject.InputData = hexutil.Encode(txs[i].Data())
tx.From.Address = strings.ToLower(from.Hex()) txObject.Hash = txsReceipt[i].TxHash.Hex()
tx.To.Address = strings.ToLower(txs[i].To().Hex()) txObject.Index = txsReceipt[i].TransactionIndex
tx.Value = hexutil.EncodeBig(txs[i].Value()) txObject.Status = txsReceipt[i].Status
tx.InputData = hexutil.Encode(txs[i].Data()) txObject.GasUsed = txsReceipt[i].GasUsed
tx.Status = txsReceipt[i].Status
tx.GasUsed = txsReceipt[i].GasUsed
fetchResponse.Data.Block.Transactions = append( fetchResponse.Data.Block.Transactions = append(
fetchResponse.Data.Block.Transactions, fetchResponse.Data.Block.Transactions,
tx, txObject,
) )
} }