Load ERC20 events in eth.GetBlock
This commit is contained in:
parent
089346a4bb
commit
fad7ea326c
@ -27,26 +27,26 @@ func NewEthereumParser() *EthereumParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type rpcHeader struct {
|
type rpcHeader struct {
|
||||||
Hash ethcommon.Hash `json:"hash"`
|
Hash string `json:"hash"`
|
||||||
Difficulty string `json:"difficulty"`
|
Difficulty string `json:"difficulty"`
|
||||||
Number string `json:"number"`
|
Number string `json:"number"`
|
||||||
Time string `json:"timestamp"`
|
Time string `json:"timestamp"`
|
||||||
Size string `json:"size"`
|
Size string `json:"size"`
|
||||||
Nonce string `json:"nonce"`
|
Nonce string `json:"nonce"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type rpcTransaction struct {
|
type rpcTransaction struct {
|
||||||
AccountNonce string `json:"nonce"`
|
AccountNonce string `json:"nonce"`
|
||||||
GasPrice string `json:"gasPrice"`
|
GasPrice string `json:"gasPrice"`
|
||||||
GasLimit string `json:"gas"`
|
GasLimit string `json:"gas"`
|
||||||
To string `json:"to" rlp:"nil"` // nil means contract creation
|
To string `json:"to"` // nil means contract creation
|
||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
Payload string `json:"input"`
|
Payload string `json:"input"`
|
||||||
Hash ethcommon.Hash `json:"hash" rlp:"-"`
|
Hash string `json:"hash"`
|
||||||
BlockNumber string `json:"blockNumber"`
|
BlockNumber string `json:"blockNumber"`
|
||||||
BlockHash *ethcommon.Hash `json:"blockHash,omitempty"`
|
BlockHash string `json:"blockHash,omitempty"`
|
||||||
From string `json:"from"`
|
From string `json:"from"`
|
||||||
TransactionIndex string `json:"transactionIndex"`
|
TransactionIndex string `json:"transactionIndex"`
|
||||||
// Signature values - ignored
|
// Signature values - ignored
|
||||||
// V string `json:"v"`
|
// V string `json:"v"`
|
||||||
// R string `json:"r"`
|
// R string `json:"r"`
|
||||||
@ -59,6 +59,11 @@ type rpcLog struct {
|
|||||||
Data string `json:"data"`
|
Data string `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type rpcLogWithTxHash struct {
|
||||||
|
rpcLog
|
||||||
|
Hash string `json:"transactionHash"`
|
||||||
|
}
|
||||||
|
|
||||||
type rpcReceipt struct {
|
type rpcReceipt struct {
|
||||||
GasUsed string `json:"gasUsed"`
|
GasUsed string `json:"gasUsed"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
@ -86,7 +91,7 @@ func ethNumber(n string) (int64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *EthereumParser) ethTxToTx(tx *rpcTransaction, receipt *rpcReceipt, blocktime int64, confirmations uint32, marshallHex bool) (*bchain.Tx, error) {
|
func (p *EthereumParser) ethTxToTx(tx *rpcTransaction, receipt *rpcReceipt, blocktime int64, confirmations uint32, marshallHex bool) (*bchain.Tx, error) {
|
||||||
txid := tx.Hash.Hex()
|
txid := tx.Hash
|
||||||
var (
|
var (
|
||||||
fa, ta []string
|
fa, ta []string
|
||||||
err error
|
err error
|
||||||
@ -105,7 +110,7 @@ func (p *EthereumParser) ethTxToTx(tx *rpcTransaction, receipt *rpcReceipt, bloc
|
|||||||
if marshallHex {
|
if marshallHex {
|
||||||
// completeTransaction without BlockHash is marshalled and hex encoded to bchain.Tx.Hex
|
// completeTransaction without BlockHash is marshalled and hex encoded to bchain.Tx.Hex
|
||||||
bh := tx.BlockHash
|
bh := tx.BlockHash
|
||||||
tx.BlockHash = nil
|
tx.BlockHash = ""
|
||||||
b, err := json.Marshal(ct)
|
b, err := json.Marshal(ct)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -235,7 +240,9 @@ func (p *EthereumParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) (
|
|||||||
if pt.Tx.GasLimit, err = hexutil.DecodeUint64(r.Tx.GasLimit); err != nil {
|
if pt.Tx.GasLimit, err = hexutil.DecodeUint64(r.Tx.GasLimit); err != nil {
|
||||||
return nil, errors.Annotatef(err, "GasLimit %v", r.Tx.GasLimit)
|
return nil, errors.Annotatef(err, "GasLimit %v", r.Tx.GasLimit)
|
||||||
}
|
}
|
||||||
pt.Tx.Hash = r.Tx.Hash.Bytes()
|
if pt.Tx.Hash, err = hexDecode(r.Tx.Hash); err != nil {
|
||||||
|
return nil, errors.Annotatef(err, "Hash %v", r.Tx.Hash)
|
||||||
|
}
|
||||||
if pt.Tx.Payload, err = hexDecode(r.Tx.Payload); err != nil {
|
if pt.Tx.Payload, err = hexDecode(r.Tx.Payload); err != nil {
|
||||||
return nil, errors.Annotatef(err, "Payload %v", r.Tx.Payload)
|
return nil, errors.Annotatef(err, "Payload %v", r.Tx.Payload)
|
||||||
}
|
}
|
||||||
@ -306,7 +313,7 @@ func (p *EthereumParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
|
|||||||
BlockNumber: hexutil.EncodeUint64(uint64(pt.BlockNumber)),
|
BlockNumber: hexutil.EncodeUint64(uint64(pt.BlockNumber)),
|
||||||
From: hexutil.Encode(pt.Tx.From),
|
From: hexutil.Encode(pt.Tx.From),
|
||||||
GasLimit: hexutil.EncodeUint64(pt.Tx.GasLimit),
|
GasLimit: hexutil.EncodeUint64(pt.Tx.GasLimit),
|
||||||
Hash: ethcommon.BytesToHash(pt.Tx.Hash),
|
Hash: hexutil.Encode(pt.Tx.Hash),
|
||||||
Payload: hexutil.Encode(pt.Tx.Payload),
|
Payload: hexutil.Encode(pt.Tx.Payload),
|
||||||
GasPrice: hexEncodeBig(pt.Tx.GasPrice),
|
GasPrice: hexEncodeBig(pt.Tx.GasPrice),
|
||||||
// R: hexEncodeBig(pt.R),
|
// R: hexEncodeBig(pt.R),
|
||||||
|
|||||||
@ -374,7 +374,7 @@ func (b *EthereumRPC) ethHeaderToBlockHeader(h *rpcHeader) (*bchain.BlockHeader,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &bchain.BlockHeader{
|
return &bchain.BlockHeader{
|
||||||
Hash: h.Hash.Hex(),
|
Hash: h.Hash,
|
||||||
Height: uint32(height),
|
Height: uint32(height),
|
||||||
Confirmations: int(c),
|
Confirmations: int(c),
|
||||||
Time: time,
|
Time: time,
|
||||||
@ -427,6 +427,25 @@ func (b *EthereumRPC) getBlockRaw(hash string, height uint32, fullTxs bool) (jso
|
|||||||
return raw, nil
|
return raw, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *EthereumRPC) getERC20EventsForBlock(blockNumber string) (map[string][]*rpcLog, error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), b.timeout)
|
||||||
|
defer cancel()
|
||||||
|
var logs []rpcLogWithTxHash
|
||||||
|
err := b.rpc.CallContext(ctx, &logs, "eth_getLogs", map[string]interface{}{
|
||||||
|
"fromBlock": blockNumber,
|
||||||
|
"toBlock": blockNumber,
|
||||||
|
"topics": []string{erc20EventTransferSignature},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Annotatef(err, "blockNumber %v", blockNumber)
|
||||||
|
}
|
||||||
|
r := make(map[string][]*rpcLog)
|
||||||
|
for _, l := range logs {
|
||||||
|
r[l.Hash] = append(r[l.Hash], &l.rpcLog)
|
||||||
|
}
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetBlock returns block with given hash or height, hash has precedence if both passed
|
// GetBlock returns block with given hash or height, hash has precedence if both passed
|
||||||
func (b *EthereumRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
|
func (b *EthereumRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
|
||||||
raw, err := b.getBlockRaw(hash, height, true)
|
raw, err := b.getBlockRaw(hash, height, true)
|
||||||
@ -445,12 +464,16 @@ func (b *EthereumRPC) GetBlock(hash string, height uint32) (*bchain.Block, error
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Annotatef(err, "hash %v, height %v", hash, height)
|
return nil, errors.Annotatef(err, "hash %v, height %v", hash, height)
|
||||||
}
|
}
|
||||||
// TODO - get ERC20 events
|
// get ERC20 events
|
||||||
|
logs, err := b.getERC20EventsForBlock(head.Number)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
btxs := make([]bchain.Tx, len(body.Transactions))
|
btxs := make([]bchain.Tx, len(body.Transactions))
|
||||||
for i, tx := range body.Transactions {
|
for i, tx := range body.Transactions {
|
||||||
btx, err := b.Parser.ethTxToTx(&tx, nil, bbh.Time, uint32(bbh.Confirmations), false)
|
btx, err := b.Parser.ethTxToTx(&tx, &rpcReceipt{Logs: logs[tx.Hash]}, bbh.Time, uint32(bbh.Confirmations), false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Annotatef(err, "hash %v, height %v, txid %v", hash, height, tx.Hash.String())
|
return nil, errors.Annotatef(err, "hash %v, height %v, txid %v", hash, height, tx.Hash)
|
||||||
}
|
}
|
||||||
btxs[i] = *btx
|
btxs[i] = *btx
|
||||||
}
|
}
|
||||||
@ -511,7 +534,7 @@ func (b *EthereumRPC) GetTransaction(txid string) (*bchain.Tx, error) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// non mempool tx - we must read the block header to get the block time
|
// non mempool tx - we must read the block header to get the block time
|
||||||
raw, err := b.getBlockRaw(tx.BlockHash.Hex(), 0, false)
|
raw, err := b.getBlockRaw(tx.BlockHash, 0, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user