gorge/pkg/block/fetch.go

93 lines
2.3 KiB
Go

package block
import (
"context"
"encoding/hex"
"math/big"
"github.com/ethereum/go-ethereum/core/types"
"github.com/lmittmann/w3"
"github.com/lmittmann/w3/module/eth"
"github.com/lmittmann/w3/w3types"
)
type BlockFetcherOpts struct {
W3Client *w3.Client
Signer types.Signer
}
type BlockFetcher struct {
opts BlockFetcherOpts
}
func NewBlockFetcher(o BlockFetcherOpts) *BlockFetcher {
return &BlockFetcher{o}
}
func (bf *BlockFetcher) FetchBlock(ctx context.Context, blockNumber *big.Int) (*FetchResponse, error) {
var (
block types.Block
)
if err := bf.opts.W3Client.CallCtx(ctx, eth.BlockByNumber(blockNumber).Returns(&block)); err != nil {
return &FetchResponse{}, err
}
var (
txsCount = len(block.Transactions())
batchedCalls = make([]w3types.Caller, txsCount*2)
txs = make([]types.Transaction, txsCount)
receipts = make([]types.Receipt, txsCount)
minimalTxs = make([]MinimalTransaction, txsCount)
)
for i, block := range block.Transactions() {
batchedCalls[i] = eth.Tx(block.Hash()).Returns(&txs[i])
batchedCalls[txsCount+i] = eth.TxReceipt(block.Hash()).Returns(&receipts[i])
}
if err := bf.opts.W3Client.CallCtx(ctx, batchedCalls...); err != nil {
return &FetchResponse{}, err
}
fetchResponse := &FetchResponse{
Block: MinimalBlock{
Hash: block.Hash(),
Number: block.Number(),
Bloom: block.Bloom(),
GasLimit: block.GasLimit(),
GasUsed: block.GasUsed(),
Time: block.Time(),
},
TransactionsCount: txsCount,
}
for i := 0; i < txsCount; i++ {
msg, err := txs[i].AsMessage(bf.opts.Signer, nil)
if err != nil {
return &FetchResponse{}, err
}
minimalTxs[i] = MinimalTransaction{
Hash: txs[i].Hash(),
From: msg.From(),
To: msg.To(),
Gas: msg.Gas(),
GasPrice: msg.GasPrice(),
Nonce: msg.Nonce(),
Value: txs[i].Value(),
InputData: hex.EncodeToString(msg.Data()),
TransactionIndex: receipts[i].TransactionIndex,
Status: receipts[i].Status,
GasUsed: receipts[i].GasUsed,
Bloom: receipts[i].Bloom,
Logs: receipts[i].Logs,
ContractAddress: receipts[i].ContractAddress,
}
}
fetchResponse.Transactions = minimalTxs
return fetchResponse, nil
}