mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-25 21:17:16 +00:00
cf799157cc
* Jumpdest skipping optimisation * Fix formatting * Move skipAnalysis into vmConfig, introduce tracing ability * Improve detection logging * Added release instructions * Fix lint
132 lines
4.1 KiB
Go
132 lines
4.1 KiB
Go
package commands
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/ledgerwatch/turbo-geth/common"
|
|
"github.com/ledgerwatch/turbo-geth/common/hexutil"
|
|
"github.com/ledgerwatch/turbo-geth/core"
|
|
"github.com/ledgerwatch/turbo-geth/core/rawdb"
|
|
"github.com/ledgerwatch/turbo-geth/core/types"
|
|
"github.com/ledgerwatch/turbo-geth/core/vm"
|
|
"github.com/ledgerwatch/turbo-geth/ethdb"
|
|
"github.com/ledgerwatch/turbo-geth/params"
|
|
)
|
|
|
|
func GetReceipts(ctx context.Context, db rawdb.DatabaseReader, cfg *params.ChainConfig, hash common.Hash) (types.Receipts, error) {
|
|
number := rawdb.ReadHeaderNumber(db, hash)
|
|
if number == nil {
|
|
return nil, fmt.Errorf("block not found: %x", hash)
|
|
}
|
|
|
|
block := rawdb.ReadBlock(db, hash, *number)
|
|
if cached := rawdb.ReadReceipts(db, block.Hash(), block.NumberU64(), cfg); cached != nil {
|
|
return cached, nil
|
|
}
|
|
|
|
bc := &blockGetter{db}
|
|
_, _, ibs, dbstate, err := ComputeTxEnv(ctx, bc, params.MainnetChainConfig, &chainContext{db: db}, db.(ethdb.HasKV).KV(), hash, 0)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var receipts types.Receipts
|
|
cc := &chainContext{db}
|
|
gp := new(core.GasPool).AddGas(block.GasLimit())
|
|
var usedGas = new(uint64)
|
|
for i, tx := range block.Transactions() {
|
|
ibs.Prepare(tx.Hash(), block.Hash(), i)
|
|
|
|
header := rawdb.ReadHeader(db, hash, *number)
|
|
receipt, err := core.ApplyTransaction(params.MainnetChainConfig, cc, nil, gp, ibs, dbstate, header, tx, usedGas, vm.Config{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
receipts = append(receipts, receipt)
|
|
}
|
|
|
|
return receipts, nil
|
|
}
|
|
|
|
func (api *APIImpl) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
|
|
number := rawdb.ReadHeaderNumber(api.dbReader, hash)
|
|
if number == nil {
|
|
return nil, fmt.Errorf("block not found: %x", hash)
|
|
}
|
|
|
|
receipts, err := GetReceipts(ctx, api.dbReader, params.MainnetChainConfig, hash)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("getReceipt error: %v", err)
|
|
}
|
|
logs := make([][]*types.Log, len(receipts))
|
|
for i, receipt := range receipts {
|
|
logs[i] = receipt.Logs
|
|
}
|
|
return logs, nil
|
|
}
|
|
|
|
func (api *APIImpl) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) {
|
|
// Retrieve the transaction and assemble its EVM context
|
|
tx, blockHash, blockNumber, txIndex := rawdb.ReadTransaction(api.dbReader, hash)
|
|
if tx == nil {
|
|
return nil, fmt.Errorf("transaction %#x not found", hash)
|
|
}
|
|
|
|
receipts, err := GetReceipts(ctx, api.dbReader, params.MainnetChainConfig, blockHash)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("getReceipt error: %v", err)
|
|
}
|
|
if len(receipts) <= int(txIndex) {
|
|
return nil, fmt.Errorf("block has less receipts than expected: %d <= %d, block: %d", len(receipts), int(txIndex), blockNumber)
|
|
}
|
|
receipt := receipts[txIndex]
|
|
|
|
var signer types.Signer = types.FrontierSigner{}
|
|
if tx.Protected() {
|
|
signer = types.NewEIP155Signer(tx.ChainID().ToBig())
|
|
}
|
|
from, _ := types.Sender(signer, tx)
|
|
|
|
// Fill in the derived information in the logs
|
|
if receipt.Logs != nil {
|
|
for i, log := range receipt.Logs {
|
|
log.BlockNumber = blockNumber
|
|
log.TxHash = hash
|
|
log.TxIndex = uint(txIndex)
|
|
log.BlockHash = blockHash
|
|
log.Index = uint(i)
|
|
}
|
|
}
|
|
|
|
// Now reconstruct the bloom filter
|
|
fields := map[string]interface{}{
|
|
"blockHash": blockHash,
|
|
"blockNumber": hexutil.Uint64(blockNumber),
|
|
"transactionHash": hash,
|
|
"transactionIndex": hexutil.Uint64(txIndex),
|
|
"from": from,
|
|
"to": tx.To(),
|
|
"gasUsed": hexutil.Uint64(receipt.GasUsed),
|
|
"cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed),
|
|
"contractAddress": nil,
|
|
"logs": receipt.Logs,
|
|
"logsBloom": receipt.Bloom,
|
|
}
|
|
|
|
// Assign receipt status or post state.
|
|
if len(receipt.PostState) > 0 {
|
|
fields["root"] = hexutil.Bytes(receipt.PostState)
|
|
} else {
|
|
fields["status"] = hexutil.Uint(receipt.Status)
|
|
}
|
|
if receipt.Logs == nil {
|
|
fields["logs"] = [][]*types.Log{}
|
|
}
|
|
// If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation
|
|
if receipt.ContractAddress != (common.Address{}) {
|
|
fields["contractAddress"] = receipt.ContractAddress
|
|
}
|
|
return fields, nil
|
|
}
|