Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/eth/ethconfig"
"github.com/XinFinOrg/XDPoSChain/eth/filters"
"github.com/XinFinOrg/XDPoSChain/eth/gasprice"
"github.com/XinFinOrg/XDPoSChain/eth/tracers"
"github.com/XinFinOrg/XDPoSChain/ethdb"
"github.com/XinFinOrg/XDPoSChain/ethstats"
"github.com/XinFinOrg/XDPoSChain/internal/ethapi"
Expand Down Expand Up @@ -1644,14 +1645,13 @@ func RegisterEthService(stack *node.Node, cfg *ethconfig.Config, XDCXServ *XDCx.
if cfg.SyncMode == downloader.LightSync {
Fatalf("can't register eth service in light sync mode, light mode has been deprecated")
return nil, nil
} else {
backend, err := eth.New(stack, cfg, XDCXServ, lendingServ)
if err != nil {
Fatalf("Failed to register the Ethereum service: %v", err)
}

return backend.ApiBackend, backend
}
backend, err := eth.New(stack, cfg, XDCXServ, lendingServ)
if err != nil {
Fatalf("Failed to register the Ethereum service: %v", err)
}
stack.RegisterAPIs(tracers.APIs(backend.ApiBackend))
return backend.ApiBackend, backend
}

// RegisterEthStatsService configures the Ethereum Stats daemon and adds it to the node.
Expand Down
14 changes: 12 additions & 2 deletions core/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,18 @@ import (
"github.com/XinFinOrg/XDPoSChain/crypto"
)

// ChainContext supports retrieving headers and consensus parameters from the
// current blockchain to be used during transaction processing.
type ChainContext interface {
// Engine retrieves the chain's consensus engine.
Engine() consensus.Engine

// GetHeader returns the hash corresponding to their hash.
GetHeader(common.Hash, uint64) *types.Header
}

// NewEVMBlockContext creates a new context for use in the EVM.
func NewEVMBlockContext(header *types.Header, chain consensus.ChainContext, author *common.Address) vm.BlockContext {
func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common.Address) vm.BlockContext {
// If we don't have an explicit author (i.e. not mining), extract from the header
var (
beneficiary common.Address
Expand Down Expand Up @@ -67,7 +77,7 @@ func NewEVMTxContext(msg Message) vm.TxContext {
}

// GetHashFn returns a GetHashFunc which retrieves header hashes by number
func GetHashFn(ref *types.Header, chain consensus.ChainContext) func(n uint64) common.Hash {
func GetHashFn(ref *types.Header, chain ChainContext) func(n uint64) common.Hash {
// Cache will initially contain [refHash.parent],
// Then fill up with [refHash.p, refHash.pp, refHash.ppp, ...]
var cache []common.Hash
Expand Down
9 changes: 7 additions & 2 deletions eth/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,13 @@ type storageEntry struct {
}

// StorageRangeAt returns the storage at the given block height and transaction index.
func (api *DebugAPI) StorageRangeAt(blockHash common.Hash, txIndex int, contractAddress common.Address, keyStart hexutil.Bytes, maxResult int) (StorageRangeResult, error) {
_, _, statedb, err := api.computeTxEnv(blockHash, txIndex, 0)
func (api *DebugAPI) StorageRangeAt(ctx context.Context, blockHash common.Hash, txIndex int, contractAddress common.Address, keyStart hexutil.Bytes, maxResult int) (StorageRangeResult, error) {
// Retrieve the block
block := api.eth.blockchain.GetBlockByHash(blockHash)
if block == nil {
return StorageRangeResult{}, fmt.Errorf("block %#x not found", blockHash)
}
_, _, statedb, err := api.eth.stateAtTransaction(block, txIndex, 0)
if err != nil {
return StorageRangeResult{}, err
}
Expand Down
17 changes: 13 additions & 4 deletions eth/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,11 @@ func (b *EthAPIBackend) GetPoolTransaction(hash common.Hash) *types.Transaction
return b.eth.txPool.Get(hash)
}

func (b *EthAPIBackend) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
tx, blockHash, blockNumber, index := rawdb.ReadTransaction(b.eth.ChainDb(), txHash)
return tx, blockHash, blockNumber, index, nil
}

func (b *EthAPIBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
return b.eth.txPool.Nonce(addr), nil
}
Expand Down Expand Up @@ -405,6 +410,14 @@ func (b *EthAPIBackend) Miner() *miner.Miner {
return b.eth.Miner()
}

func (b *EthAPIBackend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, checkLive bool) (*state.StateDB, error) {
return b.eth.stateAtBlock(block, reexec, base, checkLive)
}

func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, error) {
return b.eth.stateAtTransaction(block, txIndex, reexec)
}

func (b *EthAPIBackend) GetIPCClient() (bind.ContractBackend, error) {
// func (b *EthApiBackend) GetIPCClient() (*ethclient.Client, error) {
client, err := b.eth.blockchain.GetClient()
Expand All @@ -419,10 +432,6 @@ func (b *EthAPIBackend) CurrentHeader() *types.Header {
return b.eth.blockchain.CurrentHeader()
}

func (b *EthAPIBackend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, checkLive bool) (*state.StateDB, error) {
return b.eth.stateAtBlock(block, reexec, base, checkLive)
}

func (s *EthAPIBackend) GetRewardByHash(hash common.Hash) map[string]map[string]map[string]*big.Int {
header := s.eth.blockchain.GetHeaderByHash(hash)
if header != nil {
Expand Down
57 changes: 56 additions & 1 deletion eth/state_accessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ package eth
import (
"errors"
"fmt"
"math/big"
"time"

"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/core"
"github.com/XinFinOrg/XDPoSChain/core/state"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/core/vm"
Expand Down Expand Up @@ -59,6 +61,7 @@ func (eth *Ethereum) stateAtBlock(block *types.Block, reexec uint64, base *state
// Create an ephemeral trie.Database for isolating the live one. Otherwise
// the internal junks created by tracing will be persisted into the disk.
database = state.NewDatabaseWithConfig(eth.chainDb, &trie.Config{Cache: 16, Preimages: true})

// If we didn't check the dirty database, do check the clean one, otherwise
// we would rewind past a persisted block (specific corner case is chain
// tracing from the genesis).
Expand Down Expand Up @@ -117,7 +120,8 @@ func (eth *Ethereum) stateAtBlock(block *types.Block, reexec uint64, base *state
// Finalize the state so any modifications are written to the trie
root, err := statedb.Commit(eth.blockchain.Config().IsEIP158(current.Number()))
if err != nil {
return nil, err
return nil, fmt.Errorf("stateAtBlock commit failed, number %d root %v: %w",
current.NumberU64(), current.Root().Hex(), err)
}
statedb, err = state.New(root, database)
if err != nil {
Expand All @@ -135,3 +139,54 @@ func (eth *Ethereum) stateAtBlock(block *types.Block, reexec uint64, base *state
}
return statedb, nil
}

// stateAtTransaction returns the execution environment of a certain transaction.
func (eth *Ethereum) stateAtTransaction(block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, error) {
// Short circuit if it's genesis block.
if block.NumberU64() == 0 {
return nil, vm.BlockContext{}, nil, errors.New("no transaction in genesis")
}
// Create the parent state database
parent := eth.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1)
if parent == nil {
return nil, vm.BlockContext{}, nil, fmt.Errorf("parent %#x not found", block.ParentHash())
}
// Lookup the statedb of parent block from the live database,
// otherwise regenerate it on the flight.
statedb, err := eth.stateAtBlock(parent, reexec, nil, true)
if err != nil {
return nil, vm.BlockContext{}, nil, err
}
if txIndex == 0 && len(block.Transactions()) == 0 {
return nil, vm.BlockContext{}, statedb, nil
}
// Recompute transactions up to the target index.
signer := types.MakeSigner(eth.blockchain.Config(), block.Number())
feeCapacity := state.GetTRC21FeeCapacityFromState(statedb)
for idx, tx := range block.Transactions() {
var balance *big.Int
if tx.To() != nil {
if value, ok := feeCapacity[*tx.To()]; ok {
balance = value
}
}
// Assemble the transaction call message and return if the requested offset
msg, _ := tx.AsMessage(signer, balance, block.Number(), block.BaseFee())
txContext := core.NewEVMTxContext(msg)
context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
if idx == txIndex {
return msg, context, statedb, nil
}
// Not yet the searched for transaction, execute on top of the current state
vmenv := vm.NewEVM(context, txContext, statedb, nil, eth.blockchain.Config(), vm.Config{})
statedb.SetTxContext(tx.Hash(), idx)
owner := common.Address{}
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas()), owner); err != nil {
return nil, vm.BlockContext{}, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
}
// Ensure any modifications are committed to the state
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
}
return nil, vm.BlockContext{}, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash())
}
Loading