forked from cerc-io/plugeth
Merge tag 'v1.10.5' into plugeth
This commit is contained in:
@@ -102,7 +102,7 @@ func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) {
|
||||
if b.gasPool == nil {
|
||||
b.SetCoinbase(common.Address{})
|
||||
}
|
||||
b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs))
|
||||
b.statedb.Prepare(tx.Hash(), len(b.txs))
|
||||
receipt, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vm.Config{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
@@ -61,8 +61,10 @@ func TestCreation(t *testing.T) {
|
||||
{9199999, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // Last Istanbul and first Muir Glacier block
|
||||
{9200000, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // First Muir Glacier block
|
||||
{12243999, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // Last Muir Glacier block
|
||||
{12244000, ID{Hash: checksumToBytes(0x0eb440f6), Next: 0}}, // First Berlin block
|
||||
{20000000, ID{Hash: checksumToBytes(0x0eb440f6), Next: 0}}, // Future Berlin block
|
||||
{12244000, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // First Berlin block
|
||||
{12964999, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // Last Berlin block
|
||||
{12965000, ID{Hash: checksumToBytes(0xb715077d), Next: 0}}, // First London block
|
||||
{20000000, ID{Hash: checksumToBytes(0xb715077d), Next: 0}}, // Future London block
|
||||
},
|
||||
},
|
||||
// Ropsten test cases
|
||||
@@ -203,11 +205,11 @@ func TestValidation(t *testing.T) {
|
||||
// Local is mainnet Petersburg, remote is Rinkeby Petersburg.
|
||||
{7987396, ID{Hash: checksumToBytes(0xafec6b27), Next: 0}, ErrLocalIncompatibleOrStale},
|
||||
|
||||
// Local is mainnet Berlin, far in the future. Remote announces Gopherium (non existing fork)
|
||||
// Local is mainnet London, far in the future. Remote announces Gopherium (non existing fork)
|
||||
// at some future block 88888888, for itself, but past block for local. Local is incompatible.
|
||||
//
|
||||
// This case detects non-upgraded nodes with majority hash power (typical Ropsten mess).
|
||||
{88888888, ID{Hash: checksumToBytes(0x0eb440f6), Next: 88888888}, ErrLocalIncompatibleOrStale},
|
||||
{88888888, ID{Hash: checksumToBytes(0xb715077d), Next: 88888888}, ErrLocalIncompatibleOrStale},
|
||||
|
||||
// Local is mainnet Byzantium. Remote is also in Byzantium, but announces Gopherium (non existing
|
||||
// fork) at block 7279999, before Petersburg. Local is incompatible.
|
||||
|
||||
+4
-1
@@ -415,7 +415,10 @@ func DefaultCalaverasGenesisBlock() *Genesis {
|
||||
func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis {
|
||||
// Override the default period to the user requested one
|
||||
config := *params.AllCliqueProtocolChanges
|
||||
config.Clique.Period = period
|
||||
config.Clique = ¶ms.CliqueConfig{
|
||||
Period: period,
|
||||
Epoch: config.Clique.Epoch,
|
||||
}
|
||||
|
||||
// Assemble and return the genesis with the precompiles and faucet pre-funded
|
||||
return &Genesis{
|
||||
|
||||
+6
-2
@@ -165,6 +165,7 @@ func (hc *HeaderChain) writeHeaders(headers []*types.Header) (result *headerWrit
|
||||
)
|
||||
|
||||
batch := hc.chainDb.NewBatch()
|
||||
parentKnown := true // Set to true to force hc.HasHeader check the first iteration
|
||||
for i, header := range headers {
|
||||
var hash common.Hash
|
||||
// The headers have already been validated at this point, so we already
|
||||
@@ -178,8 +179,10 @@ func (hc *HeaderChain) writeHeaders(headers []*types.Header) (result *headerWrit
|
||||
number := header.Number.Uint64()
|
||||
newTD.Add(newTD, header.Difficulty)
|
||||
|
||||
// If the parent was not present, store it
|
||||
// If the header is already known, skip it, otherwise store
|
||||
if !hc.HasHeader(hash, number) {
|
||||
alreadyKnown := parentKnown && hc.HasHeader(hash, number)
|
||||
if !alreadyKnown {
|
||||
// Irrelevant of the canonical status, write the TD and header to the database.
|
||||
rawdb.WriteTd(batch, hash, number, newTD)
|
||||
hc.tdCache.Add(hash, new(big.Int).Set(newTD))
|
||||
@@ -192,6 +195,7 @@ func (hc *HeaderChain) writeHeaders(headers []*types.Header) (result *headerWrit
|
||||
firstInserted = i
|
||||
}
|
||||
}
|
||||
parentKnown = alreadyKnown
|
||||
lastHeader, lastHash, lastNumber = header, hash, number
|
||||
}
|
||||
|
||||
@@ -570,7 +574,7 @@ func (hc *HeaderChain) SetHead(head uint64, updateFn UpdateHeadBlocksCallback, d
|
||||
if parent == nil {
|
||||
parent = hc.genesisHeader
|
||||
}
|
||||
parentHash = hdr.ParentHash
|
||||
parentHash = parent.Hash()
|
||||
|
||||
// Notably, since geth has the possibility for setting the head to a low
|
||||
// height which is even lower than ancient head.
|
||||
|
||||
@@ -450,9 +450,6 @@ func (s *stateObject) setBalance(amount *big.Int) {
|
||||
s.data.Balance = amount
|
||||
}
|
||||
|
||||
// Return the gas back to the origin. Used by the Virtual machine or Closures
|
||||
func (s *stateObject) ReturnGas(gas *big.Int) {}
|
||||
|
||||
func (s *stateObject) deepCopy(db *StateDB) *stateObject {
|
||||
stateObject := newObject(db, s.address, s.data)
|
||||
if s.trie != nil {
|
||||
|
||||
+11
-26
@@ -89,10 +89,10 @@ type StateDB struct {
|
||||
// The refund counter, also used by state transitioning.
|
||||
refund uint64
|
||||
|
||||
thash, bhash common.Hash
|
||||
txIndex int
|
||||
logs map[common.Hash][]*types.Log
|
||||
logSize uint
|
||||
thash common.Hash
|
||||
txIndex int
|
||||
logs map[common.Hash][]*types.Log
|
||||
logSize uint
|
||||
|
||||
preimages map[common.Hash][]byte
|
||||
|
||||
@@ -186,15 +186,18 @@ func (s *StateDB) AddLog(log *types.Log) {
|
||||
s.journal.append(addLogChange{txhash: s.thash})
|
||||
|
||||
log.TxHash = s.thash
|
||||
log.BlockHash = s.bhash
|
||||
log.TxIndex = uint(s.txIndex)
|
||||
log.Index = s.logSize
|
||||
s.logs[s.thash] = append(s.logs[s.thash], log)
|
||||
s.logSize++
|
||||
}
|
||||
|
||||
func (s *StateDB) GetLogs(hash common.Hash) []*types.Log {
|
||||
return s.logs[hash]
|
||||
func (s *StateDB) GetLogs(hash common.Hash, blockHash common.Hash) []*types.Log {
|
||||
logs := s.logs[hash]
|
||||
for _, l := range logs {
|
||||
l.BlockHash = blockHash
|
||||
}
|
||||
return logs
|
||||
}
|
||||
|
||||
func (s *StateDB) Logs() []*types.Log {
|
||||
@@ -272,11 +275,6 @@ func (s *StateDB) TxIndex() int {
|
||||
return s.txIndex
|
||||
}
|
||||
|
||||
// BlockHash returns the current block hash set by Prepare.
|
||||
func (s *StateDB) BlockHash() common.Hash {
|
||||
return s.bhash
|
||||
}
|
||||
|
||||
func (s *StateDB) GetCode(addr common.Address) []byte {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject != nil {
|
||||
@@ -333,17 +331,6 @@ func (s *StateDB) GetStorageProof(a common.Address, key common.Hash) ([][]byte,
|
||||
return proof, err
|
||||
}
|
||||
|
||||
// GetStorageProofByHash returns the Merkle proof for given storage slot.
|
||||
func (s *StateDB) GetStorageProofByHash(a common.Address, key common.Hash) ([][]byte, error) {
|
||||
var proof proofList
|
||||
trie := s.StorageTrie(a)
|
||||
if trie == nil {
|
||||
return proof, errors.New("storage trie for requested address does not exist")
|
||||
}
|
||||
err := trie.Prove(crypto.Keccak256(key.Bytes()), 0, &proof)
|
||||
return proof, err
|
||||
}
|
||||
|
||||
// GetCommittedState retrieves a value from the given account's committed storage trie.
|
||||
func (s *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash {
|
||||
stateObject := s.getStateObject(addr)
|
||||
@@ -597,7 +584,6 @@ func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject)
|
||||
}
|
||||
}
|
||||
newobj = newObject(s, addr, Account{})
|
||||
newobj.setNonce(0) // sets the object to dirty
|
||||
if prev == nil {
|
||||
s.journal.append(createObjectChange{account: &addr})
|
||||
} else {
|
||||
@@ -894,9 +880,8 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||
|
||||
// Prepare sets the current transaction hash and index and block hash which is
|
||||
// used when the EVM emits new state logs.
|
||||
func (s *StateDB) Prepare(thash, bhash common.Hash, ti int) {
|
||||
func (s *StateDB) Prepare(thash common.Hash, ti int) {
|
||||
s.thash = thash
|
||||
s.bhash = bhash
|
||||
s.txIndex = ti
|
||||
s.accessList = newAccessList()
|
||||
}
|
||||
|
||||
@@ -463,9 +463,9 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error {
|
||||
return fmt.Errorf("got GetRefund() == %d, want GetRefund() == %d",
|
||||
state.GetRefund(), checkstate.GetRefund())
|
||||
}
|
||||
if !reflect.DeepEqual(state.GetLogs(common.Hash{}), checkstate.GetLogs(common.Hash{})) {
|
||||
if !reflect.DeepEqual(state.GetLogs(common.Hash{}, common.Hash{}), checkstate.GetLogs(common.Hash{}, common.Hash{})) {
|
||||
return fmt.Errorf("got GetLogs(common.Hash{}) == %v, want GetLogs(common.Hash{}) == %v",
|
||||
state.GetLogs(common.Hash{}), checkstate.GetLogs(common.Hash{}))
|
||||
state.GetLogs(common.Hash{}, common.Hash{}), checkstate.GetLogs(common.Hash{}, common.Hash{}))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -312,12 +312,11 @@ func (sf *subfetcher) loop() {
|
||||
|
||||
default:
|
||||
// No termination request yet, prefetch the next entry
|
||||
taskid := string(task)
|
||||
if _, ok := sf.seen[taskid]; ok {
|
||||
if _, ok := sf.seen[string(task)]; ok {
|
||||
sf.dups++
|
||||
} else {
|
||||
sf.trie.TryGet(task)
|
||||
sf.seen[taskid] = struct{}{}
|
||||
sf.seen[string(task)] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
|
||||
if err != nil {
|
||||
return // Also invalid block, bail out
|
||||
}
|
||||
statedb.Prepare(tx.Hash(), block.Hash(), i)
|
||||
statedb.Prepare(tx.Hash(), i)
|
||||
if err := precacheTransaction(msg, p.config, gaspool, statedb, header, evm); err != nil {
|
||||
return // Ugh, something went horribly wrong, bail out
|
||||
}
|
||||
|
||||
+17
-14
@@ -18,6 +18,7 @@ package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus"
|
||||
@@ -57,11 +58,13 @@ func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consen
|
||||
// transactions failed to execute due to insufficient gas it will return an error.
|
||||
func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) {
|
||||
var (
|
||||
receipts types.Receipts
|
||||
usedGas = new(uint64)
|
||||
header = block.Header()
|
||||
allLogs []*types.Log
|
||||
gp = new(GasPool).AddGas(block.GasLimit())
|
||||
receipts types.Receipts
|
||||
usedGas = new(uint64)
|
||||
header = block.Header()
|
||||
blockHash = block.Hash()
|
||||
blockNumber = block.Number()
|
||||
allLogs []*types.Log
|
||||
gp = new(GasPool).AddGas(block.GasLimit())
|
||||
)
|
||||
// Mutate the block and state according to any hard-fork specs
|
||||
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
|
||||
@@ -77,9 +80,9 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
||||
pluginBlockProcessingError(tx, block, err)
|
||||
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
|
||||
}
|
||||
statedb.Prepare(tx.Hash(), block.Hash(), i)
|
||||
statedb.Prepare(tx.Hash(), i)
|
||||
pluginPreProcessTransaction(tx, block, i)
|
||||
receipt, err := applyTransaction(msg, p.config, p.bc, nil, gp, statedb, header, tx, usedGas, vmenv)
|
||||
receipt, err := applyTransaction(msg, p.config, p.bc, nil, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv)
|
||||
if err != nil {
|
||||
pluginBlockProcessingError(tx, block, err)
|
||||
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
|
||||
@@ -94,7 +97,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
||||
return receipts, allLogs, *usedGas, nil
|
||||
}
|
||||
|
||||
func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) {
|
||||
func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) {
|
||||
// Create a new context to be used in the EVM environment.
|
||||
txContext := NewEVMTxContext(msg)
|
||||
evm.Reset(txContext, statedb)
|
||||
@@ -107,10 +110,10 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainCon
|
||||
|
||||
// Update the state with pending changes.
|
||||
var root []byte
|
||||
if config.IsByzantium(header.Number) {
|
||||
if config.IsByzantium(blockNumber) {
|
||||
statedb.Finalise(true)
|
||||
} else {
|
||||
root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes()
|
||||
root = statedb.IntermediateRoot(config.IsEIP158(blockNumber)).Bytes()
|
||||
}
|
||||
*usedGas += result.UsedGas
|
||||
|
||||
@@ -131,10 +134,10 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainCon
|
||||
}
|
||||
|
||||
// Set the receipt logs and create the bloom filter.
|
||||
receipt.Logs = statedb.GetLogs(tx.Hash())
|
||||
receipt.Logs = statedb.GetLogs(tx.Hash(), blockHash)
|
||||
receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
|
||||
receipt.BlockHash = statedb.BlockHash()
|
||||
receipt.BlockNumber = header.Number
|
||||
receipt.BlockHash = blockHash
|
||||
receipt.BlockNumber = blockNumber
|
||||
receipt.TransactionIndex = uint(statedb.TxIndex())
|
||||
return receipt, err
|
||||
}
|
||||
@@ -151,5 +154,5 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
|
||||
// Create a new context to be used in the EVM environment
|
||||
blockContext := NewEVMBlockContext(header, bc, author)
|
||||
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg)
|
||||
return applyTransaction(msg, config, bc, author, gp, statedb, header, tx, usedGas, vmenv)
|
||||
return applyTransaction(msg, config, bc, author, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv)
|
||||
}
|
||||
|
||||
+2
-2
@@ -138,7 +138,7 @@ func (journal *txJournal) rotate(all map[common.Address]types.Transactions) erro
|
||||
journal.writer = nil
|
||||
}
|
||||
// Generate a new journal with the contents of the current pool
|
||||
replacement, err := os.OpenFile(journal.path+".new", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
|
||||
replacement, err := os.OpenFile(journal.path+".new", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -158,7 +158,7 @@ func (journal *txJournal) rotate(all map[common.Address]types.Transactions) erro
|
||||
if err = os.Rename(journal.path+".new", journal.path); err != nil {
|
||||
return err
|
||||
}
|
||||
sink, err := os.OpenFile(journal.path, os.O_WRONLY|os.O_APPEND, 0755)
|
||||
sink, err := os.OpenFile(journal.path, os.O_WRONLY|os.O_APPEND, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -494,6 +494,23 @@ func (pool *TxPool) Content() (map[common.Address]types.Transactions, map[common
|
||||
return pending, queued
|
||||
}
|
||||
|
||||
// ContentFrom retrieves the data content of the transaction pool, returning the
|
||||
// pending as well as queued transactions of this address, grouped by nonce.
|
||||
func (pool *TxPool) ContentFrom(addr common.Address) (types.Transactions, types.Transactions) {
|
||||
pool.mu.RLock()
|
||||
defer pool.mu.RUnlock()
|
||||
|
||||
var pending types.Transactions
|
||||
if list, ok := pool.pending[addr]; ok {
|
||||
pending = list.Flatten()
|
||||
}
|
||||
var queued types.Transactions
|
||||
if list, ok := pool.queue[addr]; ok {
|
||||
queued = list.Flatten()
|
||||
}
|
||||
return pending, queued
|
||||
}
|
||||
|
||||
// Pending retrieves all currently processable transactions, grouped by origin
|
||||
// account and sorted by nonce. The returned transaction set is a copy and can be
|
||||
// freely modified by calling code.
|
||||
|
||||
@@ -129,6 +129,11 @@ func (h *Header) SanityCheck() error {
|
||||
if eLen := len(h.Extra); eLen > 100*1024 {
|
||||
return fmt.Errorf("too large block extradata: size %d", eLen)
|
||||
}
|
||||
if h.BaseFee != nil {
|
||||
if bfLen := h.BaseFee.BitLen(); bfLen > 256 {
|
||||
return fmt.Errorf("too large base fee: bitlen %d", bfLen)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -18,12 +18,12 @@ func (l Log) MarshalJSON() ([]byte, error) {
|
||||
Address common.Address `json:"address" gencodec:"required"`
|
||||
Topics []common.Hash `json:"topics" gencodec:"required"`
|
||||
Data hexutil.Bytes `json:"data" gencodec:"required"`
|
||||
BlockNumber hexutil.Uint64 `json:"blockNumber"`
|
||||
TxHash common.Hash `json:"transactionHash" gencodec:"required"`
|
||||
TxIndex hexutil.Uint `json:"transactionIndex"`
|
||||
BlockHash common.Hash `json:"blockHash"`
|
||||
Index hexutil.Uint `json:"logIndex"`
|
||||
Removed bool `json:"removed"`
|
||||
BlockNumber hexutil.Uint64 `json:"blockNumber" rlp:"-"`
|
||||
TxHash common.Hash `json:"transactionHash" gencodec:"required" rlp:"-"`
|
||||
TxIndex hexutil.Uint `json:"transactionIndex" rlp:"-"`
|
||||
BlockHash common.Hash `json:"blockHash" rlp:"-"`
|
||||
Index hexutil.Uint `json:"logIndex" rlp:"-"`
|
||||
Removed bool `json:"removed" rlp:"-"`
|
||||
}
|
||||
var enc Log
|
||||
enc.Address = l.Address
|
||||
@@ -44,12 +44,12 @@ func (l *Log) UnmarshalJSON(input []byte) error {
|
||||
Address *common.Address `json:"address" gencodec:"required"`
|
||||
Topics []common.Hash `json:"topics" gencodec:"required"`
|
||||
Data *hexutil.Bytes `json:"data" gencodec:"required"`
|
||||
BlockNumber *hexutil.Uint64 `json:"blockNumber"`
|
||||
TxHash *common.Hash `json:"transactionHash" gencodec:"required"`
|
||||
TxIndex *hexutil.Uint `json:"transactionIndex"`
|
||||
BlockHash *common.Hash `json:"blockHash"`
|
||||
Index *hexutil.Uint `json:"logIndex"`
|
||||
Removed *bool `json:"removed"`
|
||||
BlockNumber *hexutil.Uint64 `json:"blockNumber" rlp:"-"`
|
||||
TxHash *common.Hash `json:"transactionHash" gencodec:"required" rlp:"-"`
|
||||
TxIndex *hexutil.Uint `json:"transactionIndex" rlp:"-"`
|
||||
BlockHash *common.Hash `json:"blockHash" rlp:"-"`
|
||||
Index *hexutil.Uint `json:"logIndex" rlp:"-"`
|
||||
Removed *bool `json:"removed" rlp:"-"`
|
||||
}
|
||||
var dec Log
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
|
||||
+6
-58
@@ -17,11 +17,8 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
//go:generate gencodec -type Log -field-override logMarshaling -out gen_log_json.go
|
||||
@@ -40,19 +37,19 @@ type Log struct {
|
||||
// Derived fields. These fields are filled in by the node
|
||||
// but not secured by consensus.
|
||||
// block in which the transaction was included
|
||||
BlockNumber uint64 `json:"blockNumber"`
|
||||
BlockNumber uint64 `json:"blockNumber" rlp:"-"`
|
||||
// hash of the transaction
|
||||
TxHash common.Hash `json:"transactionHash" gencodec:"required"`
|
||||
TxHash common.Hash `json:"transactionHash" gencodec:"required" rlp:"-"`
|
||||
// index of the transaction in the block
|
||||
TxIndex uint `json:"transactionIndex"`
|
||||
TxIndex uint `json:"transactionIndex" rlp:"-"`
|
||||
// hash of the block in which the transaction was included
|
||||
BlockHash common.Hash `json:"blockHash"`
|
||||
BlockHash common.Hash `json:"blockHash" rlp:"-"`
|
||||
// index of the log in the block
|
||||
Index uint `json:"logIndex"`
|
||||
Index uint `json:"logIndex" rlp:"-"`
|
||||
|
||||
// The Removed field is true if this log was reverted due to a chain reorganisation.
|
||||
// You must pay attention to this field if you receive logs through a filter query.
|
||||
Removed bool `json:"removed"`
|
||||
Removed bool `json:"removed" rlp:"-"`
|
||||
}
|
||||
|
||||
type logMarshaling struct {
|
||||
@@ -61,52 +58,3 @@ type logMarshaling struct {
|
||||
TxIndex hexutil.Uint
|
||||
Index hexutil.Uint
|
||||
}
|
||||
|
||||
type rlpLog struct {
|
||||
Address common.Address
|
||||
Topics []common.Hash
|
||||
Data []byte
|
||||
}
|
||||
|
||||
// rlpStorageLog is the storage encoding of a log.
|
||||
type rlpStorageLog rlpLog
|
||||
|
||||
// EncodeRLP implements rlp.Encoder.
|
||||
func (l *Log) EncodeRLP(w io.Writer) error {
|
||||
return rlp.Encode(w, rlpLog{Address: l.Address, Topics: l.Topics, Data: l.Data})
|
||||
}
|
||||
|
||||
// DecodeRLP implements rlp.Decoder.
|
||||
func (l *Log) DecodeRLP(s *rlp.Stream) error {
|
||||
var dec rlpLog
|
||||
err := s.Decode(&dec)
|
||||
if err == nil {
|
||||
l.Address, l.Topics, l.Data = dec.Address, dec.Topics, dec.Data
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// LogForStorage is a wrapper around a Log that flattens and parses the entire content of
|
||||
// a log including non-consensus fields.
|
||||
type LogForStorage Log
|
||||
|
||||
// EncodeRLP implements rlp.Encoder.
|
||||
func (l *LogForStorage) EncodeRLP(w io.Writer) error {
|
||||
return rlp.Encode(w, rlpStorageLog{
|
||||
Address: l.Address,
|
||||
Topics: l.Topics,
|
||||
Data: l.Data,
|
||||
})
|
||||
}
|
||||
|
||||
// DecodeRLP implements rlp.Decoder.
|
||||
//
|
||||
// Note some redundant fields(e.g. block number, tx hash etc) will be assembled later.
|
||||
func (l *LogForStorage) DecodeRLP(s *rlp.Stream) error {
|
||||
var dec rlpStorageLog
|
||||
if err := s.Decode(&dec); err != nil {
|
||||
return err
|
||||
}
|
||||
*l = LogForStorage{Address: dec.Address, Topics: dec.Topics, Data: dec.Data}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ type receiptRLP struct {
|
||||
type storedReceiptRLP struct {
|
||||
PostStateOrStatus []byte
|
||||
CumulativeGasUsed uint64
|
||||
Logs []*LogForStorage
|
||||
Logs []*Log
|
||||
}
|
||||
|
||||
// NewReceipt creates a barebone transaction receipt, copying the init fields.
|
||||
@@ -217,10 +217,7 @@ func (r *ReceiptForStorage) EncodeRLP(w io.Writer) error {
|
||||
enc := &storedReceiptRLP{
|
||||
PostStateOrStatus: (*Receipt)(r).statusEncoding(),
|
||||
CumulativeGasUsed: r.CumulativeGasUsed,
|
||||
Logs: make([]*LogForStorage, len(r.Logs)),
|
||||
}
|
||||
for i, log := range r.Logs {
|
||||
enc.Logs[i] = (*LogForStorage)(log)
|
||||
Logs: r.Logs,
|
||||
}
|
||||
return rlp.Encode(w, enc)
|
||||
}
|
||||
@@ -235,10 +232,7 @@ func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error {
|
||||
return err
|
||||
}
|
||||
r.CumulativeGasUsed = stored.CumulativeGasUsed
|
||||
r.Logs = make([]*Log, len(stored.Logs))
|
||||
for i, log := range stored.Logs {
|
||||
r.Logs[i] = (*Log)(log)
|
||||
}
|
||||
r.Logs = stored.Logs
|
||||
r.Bloom = CreateBloom(Receipts{(*Receipt)(r)})
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ func NewTx(inner TxData) *Transaction {
|
||||
|
||||
// TxData is the underlying data of a transaction.
|
||||
//
|
||||
// This is implemented by LegacyTx and AccessListTx.
|
||||
// This is implemented by DynamicFeeTx, LegacyTx and AccessListTx.
|
||||
type TxData interface {
|
||||
txType() byte // returns the type ID
|
||||
copy() TxData // creates a deep copy and initializes all fields
|
||||
|
||||
+14
-56
@@ -17,7 +17,6 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/big"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@@ -58,24 +57,6 @@ func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
|
||||
return p, ok
|
||||
}
|
||||
|
||||
// run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter.
|
||||
func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, error) {
|
||||
for _, interpreter := range evm.interpreters {
|
||||
if interpreter.CanRun(contract.Code) {
|
||||
if evm.interpreter != interpreter {
|
||||
// Ensure that the interpreter pointer is set back
|
||||
// to its current value upon return.
|
||||
defer func(i Interpreter) {
|
||||
evm.interpreter = i
|
||||
}(evm.interpreter)
|
||||
evm.interpreter = interpreter
|
||||
}
|
||||
return interpreter.Run(contract, input, readOnly)
|
||||
}
|
||||
}
|
||||
return nil, errors.New("no compatible interpreter")
|
||||
}
|
||||
|
||||
// BlockContext provides the EVM with auxiliary information. Once provided
|
||||
// it shouldn't be modified.
|
||||
type BlockContext struct {
|
||||
@@ -131,8 +112,7 @@ type EVM struct {
|
||||
Config Config
|
||||
// global (to this context) ethereum virtual machine
|
||||
// used throughout the execution of the tx.
|
||||
interpreters []Interpreter
|
||||
interpreter Interpreter
|
||||
interpreter *EVMInterpreter
|
||||
// abort is used to abort the EVM calling operations
|
||||
// NOTE: must be set atomically
|
||||
abort int32
|
||||
@@ -146,36 +126,14 @@ type EVM struct {
|
||||
// only ever be used *once*.
|
||||
func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig *params.ChainConfig, config Config) *EVM {
|
||||
evm := &EVM{
|
||||
Context: blockCtx,
|
||||
TxContext: txCtx,
|
||||
StateDB: statedb,
|
||||
Config: config,
|
||||
chainConfig: chainConfig,
|
||||
chainRules: chainConfig.Rules(blockCtx.BlockNumber),
|
||||
interpreters: make([]Interpreter, 0, 1),
|
||||
Context: blockCtx,
|
||||
TxContext: txCtx,
|
||||
StateDB: statedb,
|
||||
Config: config,
|
||||
chainConfig: chainConfig,
|
||||
chainRules: chainConfig.Rules(blockCtx.BlockNumber),
|
||||
}
|
||||
|
||||
if chainConfig.IsEWASM(blockCtx.BlockNumber) {
|
||||
// to be implemented by EVM-C and Wagon PRs.
|
||||
// if vmConfig.EWASMInterpreter != "" {
|
||||
// extIntOpts := strings.Split(vmConfig.EWASMInterpreter, ":")
|
||||
// path := extIntOpts[0]
|
||||
// options := []string{}
|
||||
// if len(extIntOpts) > 1 {
|
||||
// options = extIntOpts[1..]
|
||||
// }
|
||||
// evm.interpreters = append(evm.interpreters, NewEVMVCInterpreter(evm, vmConfig, options))
|
||||
// } else {
|
||||
// evm.interpreters = append(evm.interpreters, NewEWASMInterpreter(evm, vmConfig))
|
||||
// }
|
||||
panic("No supported ewasm interpreter yet.")
|
||||
}
|
||||
|
||||
// vmConfig.EVMInterpreter will be used by EVM-C, it won't be checked here
|
||||
// as we always want to have the built-in EVM as the failover option.
|
||||
evm.interpreters = append(evm.interpreters, NewEVMInterpreter(evm, config))
|
||||
evm.interpreter = evm.interpreters[0]
|
||||
|
||||
evm.interpreter = NewEVMInterpreter(evm, config)
|
||||
return evm
|
||||
}
|
||||
|
||||
@@ -198,7 +156,7 @@ func (evm *EVM) Cancelled() bool {
|
||||
}
|
||||
|
||||
// Interpreter returns the current interpreter
|
||||
func (evm *EVM) Interpreter() Interpreter {
|
||||
func (evm *EVM) Interpreter() *EVMInterpreter {
|
||||
return evm.interpreter
|
||||
}
|
||||
|
||||
@@ -256,7 +214,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||
// The depth-check is already done, and precompiles handled above
|
||||
contract := NewContract(caller, AccountRef(addrCopy), value, gas)
|
||||
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code)
|
||||
ret, err = run(evm, contract, input, false)
|
||||
ret, err = evm.interpreter.Run(contract, input, false)
|
||||
gas = contract.Gas
|
||||
}
|
||||
}
|
||||
@@ -308,7 +266,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
|
||||
// The contract is a scoped environment for this execution context only.
|
||||
contract := NewContract(caller, AccountRef(caller.Address()), value, gas)
|
||||
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
|
||||
ret, err = run(evm, contract, input, false)
|
||||
ret, err = evm.interpreter.Run(contract, input, false)
|
||||
gas = contract.Gas
|
||||
}
|
||||
if err != nil {
|
||||
@@ -343,7 +301,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
|
||||
// Initialise a new contract and make initialise the delegate values
|
||||
contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate()
|
||||
contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy))
|
||||
ret, err = run(evm, contract, input, false)
|
||||
ret, err = evm.interpreter.Run(contract, input, false)
|
||||
gas = contract.Gas
|
||||
}
|
||||
if err != nil {
|
||||
@@ -394,7 +352,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
|
||||
// When an error was returned by the EVM or when setting the creation code
|
||||
// above we revert to the snapshot and consume any gas remaining. Additionally
|
||||
// when we're in Homestead this also counts for code storage gas errors.
|
||||
ret, err = run(evm, contract, input, true)
|
||||
ret, err = evm.interpreter.Run(contract, input, true)
|
||||
gas = contract.Gas
|
||||
}
|
||||
if err != nil {
|
||||
@@ -462,7 +420,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
||||
}
|
||||
start := time.Now()
|
||||
|
||||
ret, err := run(evm, contract, nil, false)
|
||||
ret, err := evm.interpreter.Run(contract, nil, false)
|
||||
|
||||
// Check whether the max code size has been exceeded, assign err if the case.
|
||||
if err == nil && evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize {
|
||||
|
||||
@@ -4,11 +4,11 @@ package vm
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
var _ = (*structLogMarshaling)(nil)
|
||||
@@ -22,8 +22,7 @@ func (s StructLog) MarshalJSON() ([]byte, error) {
|
||||
GasCost math.HexOrDecimal64 `json:"gasCost"`
|
||||
Memory hexutil.Bytes `json:"memory"`
|
||||
MemorySize int `json:"memSize"`
|
||||
Stack []*math.HexOrDecimal256 `json:"stack"`
|
||||
ReturnStack []math.HexOrDecimal64 `json:"returnStack"`
|
||||
Stack []uint256.Int `json:"stack"`
|
||||
ReturnData hexutil.Bytes `json:"returnData"`
|
||||
Storage map[common.Hash]common.Hash `json:"-"`
|
||||
Depth int `json:"depth"`
|
||||
@@ -39,12 +38,7 @@ func (s StructLog) MarshalJSON() ([]byte, error) {
|
||||
enc.GasCost = math.HexOrDecimal64(s.GasCost)
|
||||
enc.Memory = s.Memory
|
||||
enc.MemorySize = s.MemorySize
|
||||
if s.Stack != nil {
|
||||
enc.Stack = make([]*math.HexOrDecimal256, len(s.Stack))
|
||||
for k, v := range s.Stack {
|
||||
enc.Stack[k] = (*math.HexOrDecimal256)(v)
|
||||
}
|
||||
}
|
||||
enc.Stack = s.Stack
|
||||
enc.ReturnData = s.ReturnData
|
||||
enc.Storage = s.Storage
|
||||
enc.Depth = s.Depth
|
||||
@@ -64,7 +58,7 @@ func (s *StructLog) UnmarshalJSON(input []byte) error {
|
||||
GasCost *math.HexOrDecimal64 `json:"gasCost"`
|
||||
Memory *hexutil.Bytes `json:"memory"`
|
||||
MemorySize *int `json:"memSize"`
|
||||
Stack []*math.HexOrDecimal256 `json:"stack"`
|
||||
Stack []uint256.Int `json:"stack"`
|
||||
ReturnData *hexutil.Bytes `json:"returnData"`
|
||||
Storage map[common.Hash]common.Hash `json:"-"`
|
||||
Depth *int `json:"depth"`
|
||||
@@ -94,10 +88,7 @@ func (s *StructLog) UnmarshalJSON(input []byte) error {
|
||||
s.MemorySize = *dec.MemorySize
|
||||
}
|
||||
if dec.Stack != nil {
|
||||
s.Stack = make([]*big.Int, len(dec.Stack))
|
||||
for k, v := range dec.Stack {
|
||||
s.Stack[k] = (*big.Int)(v)
|
||||
}
|
||||
s.Stack = dec.Stack
|
||||
}
|
||||
if dec.ReturnData != nil {
|
||||
s.ReturnData = *dec.ReturnData
|
||||
|
||||
@@ -96,7 +96,7 @@ func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFu
|
||||
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
|
||||
stack = newstack()
|
||||
pc = uint64(0)
|
||||
evmInterpreter = env.interpreter.(*EVMInterpreter)
|
||||
evmInterpreter = env.interpreter
|
||||
)
|
||||
|
||||
for i, test := range tests {
|
||||
@@ -234,7 +234,7 @@ func getResult(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcas
|
||||
env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
|
||||
stack = newstack()
|
||||
pc = uint64(0)
|
||||
interpreter = env.interpreter.(*EVMInterpreter)
|
||||
interpreter = env.interpreter
|
||||
)
|
||||
result := make([]TwoOperandTestcase, len(args))
|
||||
for i, param := range args {
|
||||
|
||||
@@ -35,34 +35,9 @@ type Config struct {
|
||||
|
||||
JumpTable [256]*operation // EVM instruction table, automatically populated if unset
|
||||
|
||||
EWASMInterpreter string // External EWASM interpreter options
|
||||
EVMInterpreter string // External EVM interpreter options
|
||||
|
||||
ExtraEips []int // Additional EIPS that are to be enabled
|
||||
}
|
||||
|
||||
// Interpreter is used to run Ethereum based contracts and will utilise the
|
||||
// passed environment to query external sources for state information.
|
||||
// The Interpreter will run the byte code VM based on the passed
|
||||
// configuration.
|
||||
type Interpreter interface {
|
||||
// Run loops and evaluates the contract's code with the given input data and returns
|
||||
// the return byte-slice and an error if one occurred.
|
||||
Run(contract *Contract, input []byte, static bool) ([]byte, error)
|
||||
// CanRun tells if the contract, passed as an argument, can be
|
||||
// run by the current interpreter. This is meant so that the
|
||||
// caller can do something like:
|
||||
//
|
||||
// ```golang
|
||||
// for _, interpreter := range interpreters {
|
||||
// if interpreter.CanRun(contract.code) {
|
||||
// interpreter.Run(contract.code, input)
|
||||
// }
|
||||
// }
|
||||
// ```
|
||||
CanRun([]byte) bool
|
||||
}
|
||||
|
||||
// ScopeContext contains the things that are per-call, such as stack and memory,
|
||||
// but not transients like pc and gas
|
||||
type ScopeContext struct {
|
||||
@@ -303,9 +278,3 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// CanRun tells if the contract, passed as an argument, can be
|
||||
// run by the current interpreter.
|
||||
func (in *EVMInterpreter) CanRun(code []byte) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
+20
-12
@@ -29,6 +29,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
// Storage represents a contract's storage.
|
||||
@@ -66,7 +67,7 @@ type StructLog struct {
|
||||
GasCost uint64 `json:"gasCost"`
|
||||
Memory []byte `json:"memory"`
|
||||
MemorySize int `json:"memSize"`
|
||||
Stack []*big.Int `json:"stack"`
|
||||
Stack []uint256.Int `json:"stack"`
|
||||
ReturnData []byte `json:"returnData"`
|
||||
Storage map[common.Hash]common.Hash `json:"-"`
|
||||
Depth int `json:"depth"`
|
||||
@@ -76,7 +77,6 @@ type StructLog struct {
|
||||
|
||||
// overrides for gencodec
|
||||
type structLogMarshaling struct {
|
||||
Stack []*math.HexOrDecimal256
|
||||
Gas math.HexOrDecimal64
|
||||
GasCost math.HexOrDecimal64
|
||||
Memory hexutil.Bytes
|
||||
@@ -135,6 +135,14 @@ func NewStructLogger(cfg *LogConfig) *StructLogger {
|
||||
return logger
|
||||
}
|
||||
|
||||
// Reset clears the data held by the logger.
|
||||
func (l *StructLogger) Reset() {
|
||||
l.storage = make(map[common.Address]Storage)
|
||||
l.output = make([]byte, 0)
|
||||
l.logs = l.logs[:0]
|
||||
l.err = nil
|
||||
}
|
||||
|
||||
// CaptureStart implements the Tracer interface to initialize the tracing operation.
|
||||
func (l *StructLogger) CaptureStart(env *EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
|
||||
}
|
||||
@@ -157,16 +165,16 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
|
||||
copy(mem, memory.Data())
|
||||
}
|
||||
// Copy a snapshot of the current stack state to a new buffer
|
||||
var stck []*big.Int
|
||||
var stck []uint256.Int
|
||||
if !l.cfg.DisableStack {
|
||||
stck = make([]*big.Int, len(stack.Data()))
|
||||
stck = make([]uint256.Int, len(stack.Data()))
|
||||
for i, item := range stack.Data() {
|
||||
stck[i] = new(big.Int).Set(item.ToBig())
|
||||
stck[i] = item
|
||||
}
|
||||
}
|
||||
// Copy a snapshot of the current storage to a new container
|
||||
var storage Storage
|
||||
if !l.cfg.DisableStorage {
|
||||
if !l.cfg.DisableStorage && (op == SLOAD || op == SSTORE) {
|
||||
// initialise new changed values storage container for this contract
|
||||
// if not present.
|
||||
if l.storage[contract.Address()] == nil {
|
||||
@@ -179,16 +187,16 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
|
||||
value = env.StateDB.GetState(contract.Address(), address)
|
||||
)
|
||||
l.storage[contract.Address()][address] = value
|
||||
}
|
||||
// capture SSTORE opcodes and record the written entry in the local storage.
|
||||
if op == SSTORE && stack.len() >= 2 {
|
||||
storage = l.storage[contract.Address()].Copy()
|
||||
} else if op == SSTORE && stack.len() >= 2 {
|
||||
// capture SSTORE opcodes and record the written entry in the local storage.
|
||||
var (
|
||||
value = common.Hash(stack.data[stack.len()-2].Bytes32())
|
||||
address = common.Hash(stack.data[stack.len()-1].Bytes32())
|
||||
)
|
||||
l.storage[contract.Address()][address] = value
|
||||
storage = l.storage[contract.Address()].Copy()
|
||||
}
|
||||
storage = l.storage[contract.Address()].Copy()
|
||||
}
|
||||
var rdata []byte
|
||||
if !l.cfg.DisableReturnData {
|
||||
@@ -238,7 +246,7 @@ func WriteTrace(writer io.Writer, logs []StructLog) {
|
||||
if len(log.Stack) > 0 {
|
||||
fmt.Fprintln(writer, "Stack:")
|
||||
for i := len(log.Stack) - 1; i >= 0; i-- {
|
||||
fmt.Fprintf(writer, "%08d %x\n", len(log.Stack)-i-1, math.PaddedBigBytes(log.Stack[i], 32))
|
||||
fmt.Fprintf(writer, "%08d %s\n", len(log.Stack)-i-1, log.Stack[i].Hex())
|
||||
}
|
||||
}
|
||||
if len(log.Memory) > 0 {
|
||||
@@ -314,7 +322,7 @@ func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64
|
||||
// format stack
|
||||
var a []string
|
||||
for _, elem := range stack.data {
|
||||
a = append(a, fmt.Sprintf("%v", elem.String()))
|
||||
a = append(a, elem.Hex())
|
||||
}
|
||||
b := fmt.Sprintf("[%v]", strings.Join(a, ","))
|
||||
fmt.Fprintf(t.out, "%10v |", b)
|
||||
|
||||
@@ -57,7 +57,6 @@ func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint
|
||||
Gas: gas,
|
||||
GasCost: cost,
|
||||
MemorySize: memory.Len(),
|
||||
Storage: nil,
|
||||
Depth: depth,
|
||||
RefundCounter: env.StateDB.GetRefund(),
|
||||
Err: err,
|
||||
@@ -66,12 +65,7 @@ func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint
|
||||
log.Memory = memory.Data()
|
||||
}
|
||||
if !l.cfg.DisableStack {
|
||||
//TODO(@holiman) improve this
|
||||
logstack := make([]*big.Int, len(stack.Data()))
|
||||
for i, item := range stack.Data() {
|
||||
logstack[i] = item.ToBig()
|
||||
}
|
||||
log.Stack = logstack
|
||||
log.Stack = stack.data
|
||||
}
|
||||
if !l.cfg.DisableReturnData {
|
||||
log.ReturnData = rData
|
||||
|
||||
@@ -30,7 +30,6 @@ type dummyContractRef struct {
|
||||
calledForEach bool
|
||||
}
|
||||
|
||||
func (dummyContractRef) ReturnGas(*big.Int) {}
|
||||
func (dummyContractRef) Address() common.Address { return common.Address{} }
|
||||
func (dummyContractRef) Value() *big.Int { return new(big.Int) }
|
||||
func (dummyContractRef) SetCode(common.Hash, []byte) {}
|
||||
|
||||
Reference in New Issue
Block a user