mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
Series of changes to get backport to 1.13.5 working
This commit is contained in:
parent
28a80d617f
commit
3834f135a9
17 changed files with 161 additions and 142 deletions
|
|
@ -35,6 +35,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/bloombits"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/eth/filters"
|
||||
|
|
@ -681,7 +682,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
|
|||
|
||||
// Set infinite balance to the fake caller account.
|
||||
from := stateDB.GetOrNewStateObject(call.From)
|
||||
from.SetBalance(math.MaxBig256, state.BalanceChangeUnspecified)
|
||||
from.SetBalance(math.MaxBig256, tracing.BalanceChangeUnspecified)
|
||||
|
||||
// Execute the call.
|
||||
msg := &core.Message{
|
||||
|
|
|
|||
|
|
@ -186,9 +186,7 @@ func Transition(ctx *cli.Context) error {
|
|||
}
|
||||
prestate.Env = *inputData.Env
|
||||
|
||||
vmConfig := vm.Config{
|
||||
Tracer: tracer,
|
||||
}
|
||||
vmConfig := vm.Config{}
|
||||
// Construct the chainconfig
|
||||
var chainConfig *params.ChainConfig
|
||||
if cConf, extraEips, err := tests.GetChainConfig(ctx.String(ForknameFlag.Name)); err != nil {
|
||||
|
|
|
|||
|
|
@ -568,11 +568,10 @@ func dumpState(ctx *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
da := &state.DumpAccount{
|
||||
Balance: account.Balance.String(),
|
||||
Nonce: account.Nonce,
|
||||
Root: account.Root.Bytes(),
|
||||
CodeHash: account.CodeHash,
|
||||
SecureKey: accIt.Hash().Bytes(),
|
||||
Balance: account.Balance.String(),
|
||||
Nonce: account.Nonce,
|
||||
Root: account.Root.Bytes(),
|
||||
CodeHash: account.CodeHash,
|
||||
}
|
||||
if !conf.SkipCode && !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) {
|
||||
da.Code = rawdb.ReadCode(db, common.BytesToHash(account.CodeHash))
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package core
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
|
@ -41,7 +40,6 @@ import (
|
|||
)
|
||||
|
||||
//go:generate go run github.com/fjl/gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go
|
||||
//go:generate go run github.com/fjl/gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go
|
||||
|
||||
var errGenesisNoConfig = errors.New("genesis has no chain configuration")
|
||||
|
||||
|
|
@ -106,23 +104,14 @@ func ReadGenesis(db ethdb.Database) (*Genesis, error) {
|
|||
return &genesis, nil
|
||||
}
|
||||
|
||||
// GenesisAlloc specifies the initial state that is part of the genesis block.
|
||||
type GenesisAlloc map[common.Address]GenesisAccount
|
||||
// Deprecated: use types.GenesisAccount instead.
|
||||
type GenesisAccount = types.Account
|
||||
|
||||
func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error {
|
||||
m := make(map[common.UnprefixedAddress]GenesisAccount)
|
||||
if err := json.Unmarshal(data, &m); err != nil {
|
||||
return err
|
||||
}
|
||||
*ga = make(GenesisAlloc)
|
||||
for addr, a := range m {
|
||||
(*ga)[common.Address(addr)] = a
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// Deprecated: use types.GenesisAlloc instead.
|
||||
type GenesisAlloc = types.GenesisAlloc
|
||||
|
||||
// hash computes the state root according to the genesis specification.
|
||||
func (ga *GenesisAlloc) hash() (common.Hash, error) {
|
||||
// hashAlloc computes the state root according to the genesis specification.
|
||||
func hashAlloc(ga *types.GenesisAlloc) (common.Hash, error) {
|
||||
// Create an ephemeral in-memory database for computing hash,
|
||||
// all the derived states will be discarded to not pollute disk.
|
||||
db := state.NewDatabase(rawdb.NewMemoryDatabase())
|
||||
|
|
@ -143,10 +132,10 @@ func (ga *GenesisAlloc) hash() (common.Hash, error) {
|
|||
return statedb.Commit(0, false)
|
||||
}
|
||||
|
||||
// flush is very similar with hash, but the main difference is all the generated
|
||||
// flushAlloc is very similar with hash, but the main difference is all the generated
|
||||
// states will be persisted into the given database. Also, the genesis state
|
||||
// specification will be flushed as well.
|
||||
func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database, blockhash common.Hash) error {
|
||||
func flushAlloc(ga *types.GenesisAlloc, db ethdb.Database, triedb *trie.Database, blockhash common.Hash) error {
|
||||
statedb, err := state.New(types.EmptyRootHash, state.NewDatabaseWithNodeDB(db, triedb), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -215,15 +204,6 @@ func getGenesisState(db ethdb.Database, blockhash common.Hash) (alloc GenesisAll
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
// GenesisAccount is an account in the state of the genesis block.
|
||||
type GenesisAccount struct {
|
||||
Code []byte `json:"code,omitempty"`
|
||||
Storage map[common.Hash]common.Hash `json:"storage,omitempty"`
|
||||
Balance *big.Int `json:"balance" gencodec:"required"`
|
||||
Nonce uint64 `json:"nonce,omitempty"`
|
||||
PrivateKey []byte `json:"secretKey,omitempty"` // for tests
|
||||
}
|
||||
|
||||
// field type overrides for gencodec
|
||||
type genesisSpecMarshaling struct {
|
||||
Nonce math.HexOrDecimal64
|
||||
|
|
@ -239,34 +219,6 @@ type genesisSpecMarshaling struct {
|
|||
BlobGasUsed *math.HexOrDecimal64
|
||||
}
|
||||
|
||||
type genesisAccountMarshaling struct {
|
||||
Code hexutil.Bytes
|
||||
Balance *math.HexOrDecimal256
|
||||
Nonce math.HexOrDecimal64
|
||||
Storage map[storageJSON]storageJSON
|
||||
PrivateKey hexutil.Bytes
|
||||
}
|
||||
|
||||
// storageJSON represents a 256 bit byte array, but allows less than 256 bits when
|
||||
// unmarshaling from hex.
|
||||
type storageJSON common.Hash
|
||||
|
||||
func (h *storageJSON) UnmarshalText(text []byte) error {
|
||||
text = bytes.TrimPrefix(text, []byte("0x"))
|
||||
if len(text) > 64 {
|
||||
return fmt.Errorf("too many hex characters in storage key/value %q", text)
|
||||
}
|
||||
offset := len(h) - len(text)/2 // pad on the left
|
||||
if _, err := hex.Decode(h[offset:], text); err != nil {
|
||||
return fmt.Errorf("invalid hex storage key/value %q", text)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h storageJSON) MarshalText() ([]byte, error) {
|
||||
return hexutil.Bytes(h[:]).MarshalText()
|
||||
}
|
||||
|
||||
// GenesisMismatchError is raised when trying to overwrite an existing
|
||||
// genesis block with an incompatible one.
|
||||
type GenesisMismatchError struct {
|
||||
|
|
@ -449,7 +401,7 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
|
|||
|
||||
// ToBlock returns the genesis block according to genesis specification.
|
||||
func (g *Genesis) ToBlock() *types.Block {
|
||||
root, err := g.Alloc.hash()
|
||||
root, err := hashAlloc(&g.Alloc)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
@ -526,7 +478,7 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *trie.Database) (*types.Block
|
|||
// All the checks has passed, flush the states derived from the genesis
|
||||
// specification as well as the specification itself into the provided
|
||||
// database.
|
||||
if err := g.Alloc.flush(db, triedb, block.Hash()); err != nil {
|
||||
if err := flushAlloc(&g.Alloc, db, triedb, block.Hash()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rawdb.WriteTd(db, block.Hash(), block.NumberU64(), block.Difficulty())
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ func TestReadWriteGenesisAlloc(t *testing.T) {
|
|||
{1}: {Balance: big.NewInt(1), Storage: map[common.Hash]common.Hash{{1}: {1}}},
|
||||
{2}: {Balance: big.NewInt(2), Storage: map[common.Hash]common.Hash{{2}: {2}}},
|
||||
}
|
||||
hash, _ = alloc.hash()
|
||||
hash, _ = hashAlloc(alloc)
|
||||
)
|
||||
blob, _ := json.Marshal(alloc)
|
||||
rawdb.WriteGenesisStateSpec(db, hash, blob)
|
||||
|
|
|
|||
|
|
@ -104,14 +104,13 @@ type iterativeDump struct {
|
|||
// OnAccount implements DumpCollector interface
|
||||
func (d iterativeDump) OnAccount(addr *common.Address, account DumpAccount) {
|
||||
dumpAccount := &DumpAccount{
|
||||
Balance: account.Balance,
|
||||
Nonce: account.Nonce,
|
||||
Root: account.Root,
|
||||
CodeHash: account.CodeHash,
|
||||
Code: account.Code,
|
||||
Storage: account.Storage,
|
||||
SecureKey: account.SecureKey,
|
||||
Address: addr,
|
||||
Balance: account.Balance,
|
||||
Nonce: account.Nonce,
|
||||
Root: account.Root,
|
||||
CodeHash: account.CodeHash,
|
||||
Code: account.Code,
|
||||
Storage: account.Storage,
|
||||
Address: addr,
|
||||
}
|
||||
d.Encode(dumpAccount)
|
||||
}
|
||||
|
|
@ -150,11 +149,10 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []
|
|||
panic(err)
|
||||
}
|
||||
account := DumpAccount{
|
||||
Balance: data.Balance.String(),
|
||||
Nonce: data.Nonce,
|
||||
Root: data.Root[:],
|
||||
CodeHash: data.CodeHash,
|
||||
SecureKey: it.Key,
|
||||
Balance: data.Balance.String(),
|
||||
Nonce: data.Nonce,
|
||||
Root: data.Root[:],
|
||||
CodeHash: data.CodeHash,
|
||||
}
|
||||
var (
|
||||
addrBytes = s.trie.GetKey(it.Key)
|
||||
|
|
|
|||
|
|
@ -420,7 +420,7 @@ func (s *stateObject) AddBalance(amount *big.Int, reason tracing.BalanceChangeRe
|
|||
// SubBalance removes amount from s's balance.
|
||||
// It is used to remove funds from the origin account of a transfer.
|
||||
func (s *stateObject) SubBalance(amount *big.Int, reason tracing.BalanceChangeReason) {
|
||||
if amount.IsZero() {
|
||||
if amount.Sign() == 0 {
|
||||
return
|
||||
}
|
||||
s.SetBalance(new(big.Int).Sub(s.Balance(), amount), reason)
|
||||
|
|
|
|||
|
|
@ -384,7 +384,7 @@ func (s *StateDB) HasSelfDestructed(addr common.Address) bool {
|
|||
|
||||
// AddBalance adds amount to the account associated with addr.
|
||||
func (s *StateDB) AddBalance(addr common.Address, amount *big.Int, reason tracing.BalanceChangeReason) {
|
||||
stateObject := s.getOrNewStateObject(addr)
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.AddBalance(amount, reason)
|
||||
}
|
||||
|
|
@ -392,14 +392,14 @@ func (s *StateDB) AddBalance(addr common.Address, amount *big.Int, reason tracin
|
|||
|
||||
// SubBalance subtracts amount from the account associated with addr.
|
||||
func (s *StateDB) SubBalance(addr common.Address, amount *big.Int, reason tracing.BalanceChangeReason) {
|
||||
stateObject := s.getOrNewStateObject(addr)
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SubBalance(amount, reason)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *StateDB) SetBalance(addr common.Address, amount *big.Int, reason tracing.BalanceChangeReason) {
|
||||
stateObject := s.getOrNewStateObject(addr)
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SetBalance(amount, reason)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,13 +22,14 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
// OpContext provides the context at which the opcode is being
|
||||
// executed in, including the memory, stack and various contract-level information.
|
||||
type OpContext interface {
|
||||
MemoryData() []byte
|
||||
StackData() []big.Int
|
||||
StackData() []uint256.Int
|
||||
Caller() common.Address
|
||||
Address() common.Address
|
||||
CallValue() *big.Int
|
||||
|
|
|
|||
87
core/types/account.go
Normal file
87
core/types/account.go
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright 2024 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
)
|
||||
|
||||
//go:generate go run github.com/fjl/gencodec -type Account -field-override accountMarshaling -out gen_account.go
|
||||
|
||||
// Account represents an Ethereum account and its attached data.
|
||||
// This type is used to specify accounts in the genesis block state, and
|
||||
// is also useful for JSON encoding/decoding of accounts.
|
||||
type Account struct {
|
||||
Code []byte `json:"code,omitempty"`
|
||||
Storage map[common.Hash]common.Hash `json:"storage,omitempty"`
|
||||
Balance *big.Int `json:"balance" gencodec:"required"`
|
||||
Nonce uint64 `json:"nonce,omitempty"`
|
||||
|
||||
// used in tests
|
||||
PrivateKey []byte `json:"secretKey,omitempty"`
|
||||
}
|
||||
|
||||
type accountMarshaling struct {
|
||||
Code hexutil.Bytes
|
||||
Balance *math.HexOrDecimal256
|
||||
Nonce math.HexOrDecimal64
|
||||
Storage map[storageJSON]storageJSON
|
||||
PrivateKey hexutil.Bytes
|
||||
}
|
||||
|
||||
// storageJSON represents a 256 bit byte array, but allows less than 256 bits when
|
||||
// unmarshaling from hex.
|
||||
type storageJSON common.Hash
|
||||
|
||||
func (h *storageJSON) UnmarshalText(text []byte) error {
|
||||
text = bytes.TrimPrefix(text, []byte("0x"))
|
||||
if len(text) > 64 {
|
||||
return fmt.Errorf("too many hex characters in storage key/value %q", text)
|
||||
}
|
||||
offset := len(h) - len(text)/2 // pad on the left
|
||||
if _, err := hex.Decode(h[offset:], text); err != nil {
|
||||
return fmt.Errorf("invalid hex storage key/value %q", text)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h storageJSON) MarshalText() ([]byte, error) {
|
||||
return hexutil.Bytes(h[:]).MarshalText()
|
||||
}
|
||||
|
||||
// GenesisAlloc specifies the initial state of a genesis block.
|
||||
type GenesisAlloc map[common.Address]Account
|
||||
|
||||
func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error {
|
||||
m := make(map[common.UnprefixedAddress]Account)
|
||||
if err := json.Unmarshal(data, &m); err != nil {
|
||||
return err
|
||||
}
|
||||
*ga = make(GenesisAlloc)
|
||||
for addr, a := range m {
|
||||
(*ga)[common.Address(addr)] = a
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
|
||||
|
||||
package core
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
|
@ -12,62 +12,62 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common/math"
|
||||
)
|
||||
|
||||
var _ = (*genesisAccountMarshaling)(nil)
|
||||
var _ = (*accountMarshaling)(nil)
|
||||
|
||||
// MarshalJSON marshals as JSON.
|
||||
func (g GenesisAccount) MarshalJSON() ([]byte, error) {
|
||||
type GenesisAccount struct {
|
||||
func (a Account) MarshalJSON() ([]byte, error) {
|
||||
type Account struct {
|
||||
Code hexutil.Bytes `json:"code,omitempty"`
|
||||
Storage map[storageJSON]storageJSON `json:"storage,omitempty"`
|
||||
Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"`
|
||||
Nonce math.HexOrDecimal64 `json:"nonce,omitempty"`
|
||||
PrivateKey hexutil.Bytes `json:"secretKey,omitempty"`
|
||||
}
|
||||
var enc GenesisAccount
|
||||
enc.Code = g.Code
|
||||
if g.Storage != nil {
|
||||
enc.Storage = make(map[storageJSON]storageJSON, len(g.Storage))
|
||||
for k, v := range g.Storage {
|
||||
var enc Account
|
||||
enc.Code = a.Code
|
||||
if a.Storage != nil {
|
||||
enc.Storage = make(map[storageJSON]storageJSON, len(a.Storage))
|
||||
for k, v := range a.Storage {
|
||||
enc.Storage[storageJSON(k)] = storageJSON(v)
|
||||
}
|
||||
}
|
||||
enc.Balance = (*math.HexOrDecimal256)(g.Balance)
|
||||
enc.Nonce = math.HexOrDecimal64(g.Nonce)
|
||||
enc.PrivateKey = g.PrivateKey
|
||||
enc.Balance = (*math.HexOrDecimal256)(a.Balance)
|
||||
enc.Nonce = math.HexOrDecimal64(a.Nonce)
|
||||
enc.PrivateKey = a.PrivateKey
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals from JSON.
|
||||
func (g *GenesisAccount) UnmarshalJSON(input []byte) error {
|
||||
type GenesisAccount struct {
|
||||
func (a *Account) UnmarshalJSON(input []byte) error {
|
||||
type Account struct {
|
||||
Code *hexutil.Bytes `json:"code,omitempty"`
|
||||
Storage map[storageJSON]storageJSON `json:"storage,omitempty"`
|
||||
Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"`
|
||||
Nonce *math.HexOrDecimal64 `json:"nonce,omitempty"`
|
||||
PrivateKey *hexutil.Bytes `json:"secretKey,omitempty"`
|
||||
}
|
||||
var dec GenesisAccount
|
||||
var dec Account
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
return err
|
||||
}
|
||||
if dec.Code != nil {
|
||||
g.Code = *dec.Code
|
||||
a.Code = *dec.Code
|
||||
}
|
||||
if dec.Storage != nil {
|
||||
g.Storage = make(map[common.Hash]common.Hash, len(dec.Storage))
|
||||
a.Storage = make(map[common.Hash]common.Hash, len(dec.Storage))
|
||||
for k, v := range dec.Storage {
|
||||
g.Storage[common.Hash(k)] = common.Hash(v)
|
||||
a.Storage[common.Hash(k)] = common.Hash(v)
|
||||
}
|
||||
}
|
||||
if dec.Balance == nil {
|
||||
return errors.New("missing required field 'balance' for GenesisAccount")
|
||||
return errors.New("missing required field 'balance' for Account")
|
||||
}
|
||||
g.Balance = (*big.Int)(dec.Balance)
|
||||
a.Balance = (*big.Int)(dec.Balance)
|
||||
if dec.Nonce != nil {
|
||||
g.Nonce = uint64(*dec.Nonce)
|
||||
a.Nonce = uint64(*dec.Nonce)
|
||||
}
|
||||
if dec.PrivateKey != nil {
|
||||
g.PrivateKey = *dec.PrivateKey
|
||||
a.PrivateKey = *dec.PrivateKey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -835,7 +835,7 @@ func opSelfdestruct(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext
|
|||
tracer.OnEnter(interpreter.evm.depth, byte(SELFDESTRUCT), scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance)
|
||||
}
|
||||
if tracer.OnExit != nil {
|
||||
tracer.OnExit([]byte{}, 0, nil, false)
|
||||
tracer.OnExit(interpreter.evm.depth, []byte{}, 0, nil, false)
|
||||
}
|
||||
}
|
||||
return nil, errStopToken
|
||||
|
|
@ -855,7 +855,7 @@ func opSelfdestruct6780(pc *uint64, interpreter *EVMInterpreter, scope *ScopeCon
|
|||
tracer.OnEnter(interpreter.evm.depth, byte(SELFDESTRUCT), scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance)
|
||||
}
|
||||
if tracer.OnExit != nil {
|
||||
tracer.OnExit([]byte{}, 0, nil, false)
|
||||
tracer.OnExit(interpreter.evm.depth, []byte{}, 0, nil, false)
|
||||
}
|
||||
}
|
||||
return nil, errStopToken
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
package vm
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
|
|
@ -63,7 +65,7 @@ func (ctx *ScopeContext) Address() common.Address {
|
|||
return ctx.Contract.Address()
|
||||
}
|
||||
|
||||
func (ctx *ScopeContext) CallValue() *uint256.Int {
|
||||
func (ctx *ScopeContext) CallValue() *big.Int {
|
||||
return ctx.Contract.Value()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ func runTrace(tracer *directory.Tracer, vmctx *vmContext, chaincfg *params.Chain
|
|||
tracer.OnTxStart(env.GetVMContext(), types.NewTx(&types.LegacyTx{Gas: gasLimit}), contract.Caller())
|
||||
tracer.OnEnter(0, byte(vm.CALL), contract.Caller(), contract.Address(), []byte{}, startGas, value)
|
||||
ret, err := env.Interpreter().Run(contract, []byte{}, false)
|
||||
tracer.OnEnd(ret, startGas-contract.Gas, err, true)
|
||||
tracer.OnExit(0, ret, startGas-contract.Gas, err, true)
|
||||
// Rest gas assumes no refund
|
||||
tracer.OnTxEnd(&types.Receipt{GasUsed: gasLimit - contract.Gas}, nil)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -147,32 +147,7 @@ func newCallTracerObject(ctx *directory.Context, cfg json.RawMessage) (*callTrac
|
|||
}
|
||||
// First callframe contains tx context info
|
||||
// and is populated on start and end.
|
||||
return &callTracer{callstack: make([]callFrame, 1), config: config}, nil
|
||||
}
|
||||
|
||||
// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
|
||||
func (t *callTracer) CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
|
||||
toCopy := to
|
||||
t.callstack[0] = callFrame{
|
||||
Type: vm.CALL,
|
||||
From: from,
|
||||
To: &toCopy,
|
||||
Input: common.CopyBytes(input),
|
||||
Gas: t.gasLimit,
|
||||
Value: value,
|
||||
}
|
||||
if create {
|
||||
t.callstack[0].Type = vm.CREATE
|
||||
}
|
||||
}
|
||||
|
||||
// CaptureEnd is called after the call finishes to finalize the tracing.
|
||||
func (t *callTracer) CaptureEnd(output []byte, gasUsed uint64, err error, reverted bool) {
|
||||
t.callstack[0].processOutput(output, err, reverted)
|
||||
}
|
||||
|
||||
// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
|
||||
func (t *callTracer) CaptureState(pc uint64, op tracing.OpCode, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) {
|
||||
return &callTracer{callstack: make([]callFrame, 0, 1), config: config}, nil
|
||||
}
|
||||
|
||||
// OnEnter is called when EVM enters a new scope (via call, create or selfdestruct).
|
||||
|
|
@ -195,6 +170,9 @@ func (t *callTracer) OnEnter(depth int, typ byte, from common.Address, to common
|
|||
Gas: gas,
|
||||
Value: value,
|
||||
}
|
||||
if depth == 0 {
|
||||
call.Gas = t.gasLimit
|
||||
}
|
||||
t.callstack = append(t.callstack, call)
|
||||
}
|
||||
|
||||
|
|
@ -210,17 +188,19 @@ func (t *callTracer) OnExit(depth int, output []byte, gasUsed uint64, err error,
|
|||
if t.config.OnlyTopCall {
|
||||
return
|
||||
}
|
||||
|
||||
size := len(t.callstack)
|
||||
if size <= 1 {
|
||||
return
|
||||
}
|
||||
// pop call
|
||||
// Pop call.
|
||||
call := t.callstack[size-1]
|
||||
t.callstack = t.callstack[:size-1]
|
||||
size -= 1
|
||||
|
||||
call.GasUsed = gasUsed
|
||||
call.processOutput(output, err, reverted)
|
||||
// Nest call into parent.
|
||||
t.callstack[size-1].Calls = append(t.callstack[size-1].Calls, call)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ func (t *muxTracer) OnGasChange(old, new uint64, reason tracing.GasChangeReason)
|
|||
func (t *muxTracer) OnEnter(depth int, typ byte, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
|
||||
for _, t := range t.tracers {
|
||||
if t.OnEnter != nil {
|
||||
t.OnEnter(typ, from, to, input, gas, value)
|
||||
t.OnEnter(depth, typ, from, to, input, gas, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -112,7 +112,7 @@ func (t *muxTracer) OnEnter(depth int, typ byte, from common.Address, to common.
|
|||
func (t *muxTracer) OnExit(depth int, output []byte, gasUsed uint64, err error, reverted bool) {
|
||||
for _, t := range t.tracers {
|
||||
if t.OnExit != nil {
|
||||
t.OnExit(output, gasUsed, err, reverted)
|
||||
t.OnExit(depth, output, gasUsed, err, reverted)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
|
|
@ -201,7 +202,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
|
|||
}
|
||||
|
||||
// Perform read-only call.
|
||||
st.SetBalance(testBankAddress, math.MaxBig256, state.BalanceChangeUnspecified)
|
||||
st.SetBalance(testBankAddress, math.MaxBig256, tracing.BalanceChangeUnspecified)
|
||||
msg := &core.Message{
|
||||
From: testBankAddress,
|
||||
To: &testContractAddr,
|
||||
|
|
|
|||
Loading…
Reference in a new issue