init: PoC

* only supports legacy transactions
This commit is contained in:
2022-11-23 12:48:52 +03:00
commit 4c2f90f16c
6 changed files with 385 additions and 0 deletions

40
pkg/block/block.go Normal file
View File

@@ -0,0 +1,40 @@
package block
import (
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
)
type FetchResponse struct {
Block MinimalBlock `json:"block"`
TransactionsCount int `json:"transactionsCount"`
Transactions []MinimalTransaction `json:"transactions"`
}
type MinimalBlock struct {
Hash common.Hash `json:"hash"`
Number *big.Int `json:"number"`
Bloom types.Bloom `json:"logsBloom"`
GasLimit uint64 `json:"gasLimit"`
GasUsed uint64 `json:"gasUsed"`
Time uint64 `json:"timestamp"`
}
type MinimalTransaction struct {
Hash common.Hash `json:"hash"`
From common.Address `json:"from"`
To *common.Address `json:"to"`
Gas uint64 `json:"gas"`
GasPrice *big.Int `json:"gasPrice"`
Nonce uint64 `json:"nonce"`
Value *big.Int `json:"value"`
InputData string `json:"input"`
TransactionIndex uint `json:"transactionIndex"`
Status uint64 `json:"status"`
GasUsed uint64 `json:"gasUsed"`
Bloom types.Bloom `json:"logsBloom"`
Logs []*types.Log `json:"logs"`
ContractAddress common.Address `json:"contractAddress"`
}

92
pkg/block/fetch.go Normal file
View File

@@ -0,0 +1,92 @@
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
}