Merge pull request #3067 from karalabe/vm-avoid-hashing
cmd, core, internal, light, tests: avoid hashing the code in the VM
This commit is contained in:
commit
0731b44809
|
@ -30,6 +30,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"gopkg.in/urfave/cli.v1"
|
"gopkg.in/urfave/cli.v1"
|
||||||
|
@ -146,7 +147,9 @@ func run(ctx *cli.Context) error {
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
receiver := statedb.CreateAccount(common.StringToAddress("receiver"))
|
receiver := statedb.CreateAccount(common.StringToAddress("receiver"))
|
||||||
receiver.SetCode(common.Hex2Bytes(ctx.GlobalString(CodeFlag.Name)))
|
|
||||||
|
code := common.Hex2Bytes(ctx.GlobalString(CodeFlag.Name))
|
||||||
|
receiver.SetCode(crypto.Keccak256Hash(code), code)
|
||||||
ret, err = vmenv.Call(
|
ret, err = vmenv.Call(
|
||||||
sender,
|
sender,
|
||||||
receiver.Address(),
|
receiver.Address(),
|
||||||
|
|
|
@ -27,14 +27,14 @@ import (
|
||||||
|
|
||||||
// Call executes within the given contract
|
// Call executes within the given contract
|
||||||
func Call(env vm.Environment, caller vm.ContractRef, addr common.Address, input []byte, gas, gasPrice, value *big.Int) (ret []byte, err error) {
|
func Call(env vm.Environment, caller vm.ContractRef, addr common.Address, input []byte, gas, gasPrice, value *big.Int) (ret []byte, err error) {
|
||||||
ret, _, err = exec(env, caller, &addr, &addr, input, env.Db().GetCode(addr), gas, gasPrice, value)
|
ret, _, err = exec(env, caller, &addr, &addr, env.Db().GetCodeHash(addr), input, env.Db().GetCode(addr), gas, gasPrice, value)
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CallCode executes the given address' code as the given contract address
|
// CallCode executes the given address' code as the given contract address
|
||||||
func CallCode(env vm.Environment, caller vm.ContractRef, addr common.Address, input []byte, gas, gasPrice, value *big.Int) (ret []byte, err error) {
|
func CallCode(env vm.Environment, caller vm.ContractRef, addr common.Address, input []byte, gas, gasPrice, value *big.Int) (ret []byte, err error) {
|
||||||
callerAddr := caller.Address()
|
callerAddr := caller.Address()
|
||||||
ret, _, err = exec(env, caller, &callerAddr, &addr, input, env.Db().GetCode(addr), gas, gasPrice, value)
|
ret, _, err = exec(env, caller, &callerAddr, &addr, env.Db().GetCodeHash(addr), input, env.Db().GetCode(addr), gas, gasPrice, value)
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,13 +43,13 @@ func DelegateCall(env vm.Environment, caller vm.ContractRef, addr common.Address
|
||||||
callerAddr := caller.Address()
|
callerAddr := caller.Address()
|
||||||
originAddr := env.Origin()
|
originAddr := env.Origin()
|
||||||
callerValue := caller.Value()
|
callerValue := caller.Value()
|
||||||
ret, _, err = execDelegateCall(env, caller, &originAddr, &callerAddr, &addr, input, env.Db().GetCode(addr), gas, gasPrice, callerValue)
|
ret, _, err = execDelegateCall(env, caller, &originAddr, &callerAddr, &addr, env.Db().GetCodeHash(addr), input, env.Db().GetCode(addr), gas, gasPrice, callerValue)
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates a new contract with the given code
|
// Create creates a new contract with the given code
|
||||||
func Create(env vm.Environment, caller vm.ContractRef, code []byte, gas, gasPrice, value *big.Int) (ret []byte, address common.Address, err error) {
|
func Create(env vm.Environment, caller vm.ContractRef, code []byte, gas, gasPrice, value *big.Int) (ret []byte, address common.Address, err error) {
|
||||||
ret, address, err = exec(env, caller, nil, nil, nil, code, gas, gasPrice, value)
|
ret, address, err = exec(env, caller, nil, nil, crypto.Keccak256Hash(code), nil, code, gas, gasPrice, value)
|
||||||
// Here we get an error if we run into maximum stack depth,
|
// Here we get an error if we run into maximum stack depth,
|
||||||
// See: https://github.com/ethereum/yellowpaper/pull/131
|
// See: https://github.com/ethereum/yellowpaper/pull/131
|
||||||
// and YP definitions for CREATE instruction
|
// and YP definitions for CREATE instruction
|
||||||
|
@ -59,7 +59,7 @@ func Create(env vm.Environment, caller vm.ContractRef, code []byte, gas, gasPric
|
||||||
return ret, address, err
|
return ret, address, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func exec(env vm.Environment, caller vm.ContractRef, address, codeAddr *common.Address, input, code []byte, gas, gasPrice, value *big.Int) (ret []byte, addr common.Address, err error) {
|
func exec(env vm.Environment, caller vm.ContractRef, address, codeAddr *common.Address, codeHash common.Hash, input, code []byte, gas, gasPrice, value *big.Int) (ret []byte, addr common.Address, err error) {
|
||||||
evm := env.Vm()
|
evm := env.Vm()
|
||||||
// Depth check execution. Fail if we're trying to execute above the
|
// Depth check execution. Fail if we're trying to execute above the
|
||||||
// limit.
|
// limit.
|
||||||
|
@ -105,7 +105,7 @@ func exec(env vm.Environment, caller vm.ContractRef, address, codeAddr *common.A
|
||||||
// EVM. The contract is a scoped environment for this execution context
|
// EVM. The contract is a scoped environment for this execution context
|
||||||
// only.
|
// only.
|
||||||
contract := vm.NewContract(caller, to, value, gas, gasPrice)
|
contract := vm.NewContract(caller, to, value, gas, gasPrice)
|
||||||
contract.SetCallCode(codeAddr, code)
|
contract.SetCallCode(codeAddr, codeHash, code)
|
||||||
defer contract.Finalise()
|
defer contract.Finalise()
|
||||||
|
|
||||||
ret, err = evm.Run(contract, input)
|
ret, err = evm.Run(contract, input)
|
||||||
|
@ -135,7 +135,7 @@ func exec(env vm.Environment, caller vm.ContractRef, address, codeAddr *common.A
|
||||||
return ret, addr, err
|
return ret, addr, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func execDelegateCall(env vm.Environment, caller vm.ContractRef, originAddr, toAddr, codeAddr *common.Address, input, code []byte, gas, gasPrice, value *big.Int) (ret []byte, addr common.Address, err error) {
|
func execDelegateCall(env vm.Environment, caller vm.ContractRef, originAddr, toAddr, codeAddr *common.Address, codeHash common.Hash, input, code []byte, gas, gasPrice, value *big.Int) (ret []byte, addr common.Address, err error) {
|
||||||
evm := env.Vm()
|
evm := env.Vm()
|
||||||
// Depth check execution. Fail if we're trying to execute above the
|
// Depth check execution. Fail if we're trying to execute above the
|
||||||
// limit.
|
// limit.
|
||||||
|
@ -155,7 +155,7 @@ func execDelegateCall(env vm.Environment, caller vm.ContractRef, originAddr, toA
|
||||||
|
|
||||||
// Iinitialise a new contract and make initialise the delegate values
|
// Iinitialise a new contract and make initialise the delegate values
|
||||||
contract := vm.NewContract(caller, to, value, gas, gasPrice).AsDelegate()
|
contract := vm.NewContract(caller, to, value, gas, gasPrice).AsDelegate()
|
||||||
contract.SetCallCode(codeAddr, code)
|
contract.SetCallCode(codeAddr, codeHash, code)
|
||||||
defer contract.Finalise()
|
defer contract.Finalise()
|
||||||
|
|
||||||
ret, err = evm.Run(contract, input)
|
ret, err = evm.Run(contract, input)
|
||||||
|
|
|
@ -273,9 +273,9 @@ func (self *StateObject) Code(db trie.Database) []byte {
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateObject) SetCode(code []byte) {
|
func (self *StateObject) SetCode(codeHash common.Hash, code []byte) {
|
||||||
self.code = code
|
self.code = code
|
||||||
self.data.CodeHash = crypto.Keccak256(code)
|
self.data.CodeHash = codeHash[:]
|
||||||
self.dirtyCode = true
|
self.dirtyCode = true
|
||||||
if self.onDirty != nil {
|
if self.onDirty != nil {
|
||||||
self.onDirty(self.Address())
|
self.onDirty(self.Address())
|
||||||
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
checker "gopkg.in/check.v1"
|
checker "gopkg.in/check.v1"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ func (s *StateSuite) TestDump(c *checker.C) {
|
||||||
obj1 := s.state.GetOrNewStateObject(toAddr([]byte{0x01}))
|
obj1 := s.state.GetOrNewStateObject(toAddr([]byte{0x01}))
|
||||||
obj1.AddBalance(big.NewInt(22))
|
obj1.AddBalance(big.NewInt(22))
|
||||||
obj2 := s.state.GetOrNewStateObject(toAddr([]byte{0x01, 0x02}))
|
obj2 := s.state.GetOrNewStateObject(toAddr([]byte{0x01, 0x02}))
|
||||||
obj2.SetCode([]byte{3, 3, 3, 3, 3, 3, 3})
|
obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3})
|
||||||
obj3 := s.state.GetOrNewStateObject(toAddr([]byte{0x02}))
|
obj3 := s.state.GetOrNewStateObject(toAddr([]byte{0x02}))
|
||||||
obj3.SetBalance(big.NewInt(44))
|
obj3.SetBalance(big.NewInt(44))
|
||||||
|
|
||||||
|
@ -148,7 +149,7 @@ func TestSnapshot2(t *testing.T) {
|
||||||
so0 := state.GetStateObject(stateobjaddr0)
|
so0 := state.GetStateObject(stateobjaddr0)
|
||||||
so0.SetBalance(big.NewInt(42))
|
so0.SetBalance(big.NewInt(42))
|
||||||
so0.SetNonce(43)
|
so0.SetNonce(43)
|
||||||
so0.SetCode([]byte{'c', 'a', 'f', 'e'})
|
so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'})
|
||||||
so0.remove = false
|
so0.remove = false
|
||||||
so0.deleted = false
|
so0.deleted = false
|
||||||
state.SetStateObject(so0)
|
state.SetStateObject(so0)
|
||||||
|
@ -160,7 +161,7 @@ func TestSnapshot2(t *testing.T) {
|
||||||
so1 := state.GetStateObject(stateobjaddr1)
|
so1 := state.GetStateObject(stateobjaddr1)
|
||||||
so1.SetBalance(big.NewInt(52))
|
so1.SetBalance(big.NewInt(52))
|
||||||
so1.SetNonce(53)
|
so1.SetNonce(53)
|
||||||
so1.SetCode([]byte{'c', 'a', 'f', 'e', '2'})
|
so1.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e', '2'}), []byte{'c', 'a', 'f', 'e', '2'})
|
||||||
so1.remove = true
|
so1.remove = true
|
||||||
so1.deleted = true
|
so1.deleted = true
|
||||||
state.SetStateObject(so1)
|
state.SetStateObject(so1)
|
||||||
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
@ -246,6 +247,14 @@ func (self *StateDB) GetCodeSize(addr common.Address) int {
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *StateDB) GetCodeHash(addr common.Address) common.Hash {
|
||||||
|
stateObject := self.GetStateObject(addr)
|
||||||
|
if stateObject == nil {
|
||||||
|
return common.Hash{}
|
||||||
|
}
|
||||||
|
return common.BytesToHash(stateObject.CodeHash())
|
||||||
|
}
|
||||||
|
|
||||||
func (self *StateDB) GetState(a common.Address, b common.Hash) common.Hash {
|
func (self *StateDB) GetState(a common.Address, b common.Hash) common.Hash {
|
||||||
stateObject := self.GetStateObject(a)
|
stateObject := self.GetStateObject(a)
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
|
@ -283,7 +292,7 @@ func (self *StateDB) SetNonce(addr common.Address, nonce uint64) {
|
||||||
func (self *StateDB) SetCode(addr common.Address, code []byte) {
|
func (self *StateDB) SetCode(addr common.Address, code []byte) {
|
||||||
stateObject := self.GetOrNewStateObject(addr)
|
stateObject := self.GetOrNewStateObject(addr)
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
stateObject.SetCode(code)
|
stateObject.SetCode(crypto.Keccak256Hash(code), code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ func TestUpdateLeaks(t *testing.T) {
|
||||||
obj.SetState(common.BytesToHash([]byte{i, i, i}), common.BytesToHash([]byte{i, i, i, i}))
|
obj.SetState(common.BytesToHash([]byte{i, i, i}), common.BytesToHash([]byte{i, i, i, i}))
|
||||||
}
|
}
|
||||||
if i%3 == 0 {
|
if i%3 == 0 {
|
||||||
obj.SetCode([]byte{i, i, i, i, i})
|
obj.SetCode(crypto.Keccak256Hash([]byte{i, i, i, i, i}), []byte{i, i, i, i, i})
|
||||||
}
|
}
|
||||||
state.UpdateStateObject(obj)
|
state.UpdateStateObject(obj)
|
||||||
}
|
}
|
||||||
|
@ -70,7 +71,7 @@ func TestIntermediateLeaks(t *testing.T) {
|
||||||
obj.SetState(common.BytesToHash([]byte{i, i, i, 0}), common.BytesToHash([]byte{i, i, i, i, 0}))
|
obj.SetState(common.BytesToHash([]byte{i, i, i, 0}), common.BytesToHash([]byte{i, i, i, i, 0}))
|
||||||
}
|
}
|
||||||
if i%3 == 0 {
|
if i%3 == 0 {
|
||||||
obj.SetCode([]byte{i, i, i, i, i, 0})
|
obj.SetCode(crypto.Keccak256Hash([]byte{i, i, i, i, i, 0}), []byte{i, i, i, i, i, 0})
|
||||||
}
|
}
|
||||||
transState.UpdateStateObject(obj)
|
transState.UpdateStateObject(obj)
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@ func TestIntermediateLeaks(t *testing.T) {
|
||||||
obj.SetState(common.BytesToHash([]byte{i, i, i, 1}), common.BytesToHash([]byte{i, i, i, i, 1}))
|
obj.SetState(common.BytesToHash([]byte{i, i, i, 1}), common.BytesToHash([]byte{i, i, i, i, 1}))
|
||||||
}
|
}
|
||||||
if i%3 == 0 {
|
if i%3 == 0 {
|
||||||
obj.SetCode([]byte{i, i, i, i, i, 1})
|
obj.SetCode(crypto.Keccak256Hash([]byte{i, i, i, i, i, 1}), []byte{i, i, i, i, i, 1})
|
||||||
}
|
}
|
||||||
transState.UpdateStateObject(obj)
|
transState.UpdateStateObject(obj)
|
||||||
|
|
||||||
|
@ -94,7 +95,7 @@ func TestIntermediateLeaks(t *testing.T) {
|
||||||
obj.SetState(common.BytesToHash([]byte{i, i, i, 1}), common.BytesToHash([]byte{i, i, i, i, 1}))
|
obj.SetState(common.BytesToHash([]byte{i, i, i, 1}), common.BytesToHash([]byte{i, i, i, i, 1}))
|
||||||
}
|
}
|
||||||
if i%3 == 0 {
|
if i%3 == 0 {
|
||||||
obj.SetCode([]byte{i, i, i, i, i, 1})
|
obj.SetCode(crypto.Keccak256Hash([]byte{i, i, i, i, i, 1}), []byte{i, i, i, i, i, 1})
|
||||||
}
|
}
|
||||||
finalState.UpdateStateObject(obj)
|
finalState.UpdateStateObject(obj)
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ func makeTestState() (ethdb.Database, common.Hash, []*testAccount) {
|
||||||
acc.nonce = uint64(42 * i)
|
acc.nonce = uint64(42 * i)
|
||||||
|
|
||||||
if i%3 == 0 {
|
if i%3 == 0 {
|
||||||
obj.SetCode([]byte{i, i, i, i, i})
|
obj.SetCode(crypto.Keccak256Hash([]byte{i, i, i, i, i}), []byte{i, i, i, i, i})
|
||||||
acc.code = []byte{i, i, i, i, i}
|
acc.code = []byte{i, i, i, i, i}
|
||||||
}
|
}
|
||||||
state.UpdateStateObject(obj)
|
state.UpdateStateObject(obj)
|
||||||
|
|
|
@ -27,7 +27,7 @@ type ContractRef interface {
|
||||||
ReturnGas(*big.Int, *big.Int)
|
ReturnGas(*big.Int, *big.Int)
|
||||||
Address() common.Address
|
Address() common.Address
|
||||||
Value() *big.Int
|
Value() *big.Int
|
||||||
SetCode([]byte)
|
SetCode(common.Hash, []byte)
|
||||||
ForEachStorage(callback func(key, value common.Hash) bool)
|
ForEachStorage(callback func(key, value common.Hash) bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +44,9 @@ type Contract struct {
|
||||||
jumpdests destinations // result of JUMPDEST analysis.
|
jumpdests destinations // result of JUMPDEST analysis.
|
||||||
|
|
||||||
Code []byte
|
Code []byte
|
||||||
Input []byte
|
CodeHash common.Hash
|
||||||
CodeAddr *common.Address
|
CodeAddr *common.Address
|
||||||
|
Input []byte
|
||||||
|
|
||||||
value, Gas, UsedGas, Price *big.Int
|
value, Gas, UsedGas, Price *big.Int
|
||||||
|
|
||||||
|
@ -143,14 +144,16 @@ func (c *Contract) Value() *big.Int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCode sets the code to the contract
|
// SetCode sets the code to the contract
|
||||||
func (self *Contract) SetCode(code []byte) {
|
func (self *Contract) SetCode(hash common.Hash, code []byte) {
|
||||||
self.Code = code
|
self.Code = code
|
||||||
|
self.CodeHash = hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCallCode sets the code of the contract and address of the backing data
|
// SetCallCode sets the code of the contract and address of the backing data
|
||||||
// object
|
// object
|
||||||
func (self *Contract) SetCallCode(addr *common.Address, code []byte) {
|
func (self *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) {
|
||||||
self.Code = code
|
self.Code = code
|
||||||
|
self.CodeHash = hash
|
||||||
self.CodeAddr = addr
|
self.CodeAddr = addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,7 @@ type Database interface {
|
||||||
GetNonce(common.Address) uint64
|
GetNonce(common.Address) uint64
|
||||||
SetNonce(common.Address, uint64)
|
SetNonce(common.Address, uint64)
|
||||||
|
|
||||||
|
GetCodeHash(common.Address) common.Hash
|
||||||
GetCodeSize(common.Address) int
|
GetCodeSize(common.Address) int
|
||||||
GetCode(common.Address) []byte
|
GetCode(common.Address) []byte
|
||||||
SetCode(common.Address, []byte)
|
SetCode(common.Address, []byte)
|
||||||
|
@ -118,7 +119,7 @@ type Account interface {
|
||||||
Balance() *big.Int
|
Balance() *big.Int
|
||||||
Address() common.Address
|
Address() common.Address
|
||||||
ReturnGas(*big.Int, *big.Int)
|
ReturnGas(*big.Int, *big.Int)
|
||||||
SetCode([]byte)
|
SetCode(common.Hash, []byte)
|
||||||
ForEachStorage(cb func(key, value common.Hash) bool)
|
ForEachStorage(cb func(key, value common.Hash) bool)
|
||||||
Value() *big.Int
|
Value() *big.Int
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ func (account) SetNonce(uint64) {}
|
||||||
func (account) Balance() *big.Int { return nil }
|
func (account) Balance() *big.Int { return nil }
|
||||||
func (account) Address() common.Address { return common.Address{} }
|
func (account) Address() common.Address { return common.Address{} }
|
||||||
func (account) ReturnGas(*big.Int, *big.Int) {}
|
func (account) ReturnGas(*big.Int, *big.Int) {}
|
||||||
func (account) SetCode([]byte) {}
|
func (account) SetCode(common.Hash, []byte) {}
|
||||||
func (account) ForEachStorage(cb func(key, value common.Hash) bool) {}
|
func (account) ForEachStorage(cb func(key, value common.Hash) bool) {}
|
||||||
|
|
||||||
func runVmBench(test vmBench, b *testing.B) {
|
func runVmBench(test vmBench, b *testing.B) {
|
||||||
|
|
|
@ -30,7 +30,7 @@ type dummyContractRef struct {
|
||||||
func (dummyContractRef) ReturnGas(*big.Int, *big.Int) {}
|
func (dummyContractRef) ReturnGas(*big.Int, *big.Int) {}
|
||||||
func (dummyContractRef) Address() common.Address { return common.Address{} }
|
func (dummyContractRef) Address() common.Address { return common.Address{} }
|
||||||
func (dummyContractRef) Value() *big.Int { return new(big.Int) }
|
func (dummyContractRef) Value() *big.Int { return new(big.Int) }
|
||||||
func (dummyContractRef) SetCode([]byte) {}
|
func (dummyContractRef) SetCode(common.Hash, []byte) {}
|
||||||
func (d *dummyContractRef) ForEachStorage(callback func(key, value common.Hash) bool) {
|
func (d *dummyContractRef) ForEachStorage(callback func(key, value common.Hash) bool) {
|
||||||
d.calledForEach = true
|
d.calledForEach = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
||||||
receiver = cfg.State.CreateAccount(common.StringToAddress("contract"))
|
receiver = cfg.State.CreateAccount(common.StringToAddress("contract"))
|
||||||
)
|
)
|
||||||
// set the receiver's (the executing contract) code for execution.
|
// set the receiver's (the executing contract) code for execution.
|
||||||
receiver.SetCode(code)
|
receiver.SetCode(crypto.Keccak256Hash(code), code)
|
||||||
|
|
||||||
// Call the code with the given configuration.
|
// Call the code with the given configuration.
|
||||||
ret, err := vmenv.Call(
|
ret, err := vmenv.Call(
|
||||||
|
|
|
@ -71,10 +71,11 @@ func (evm *EVM) Run(contract *Contract, input []byte) (ret []byte, err error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
codehash := contract.CodeHash // codehash is used when doing jump dest caching
|
||||||
codehash = crypto.Keccak256Hash(contract.Code) // codehash is used when doing jump dest caching
|
if codehash == (common.Hash{}) {
|
||||||
program *Program
|
codehash = crypto.Keccak256Hash(contract.Code)
|
||||||
)
|
}
|
||||||
|
var program *Program
|
||||||
if evm.cfg.EnableJit {
|
if evm.cfg.EnableJit {
|
||||||
// If the JIT is enabled check the status of the JIT program,
|
// If the JIT is enabled check the status of the JIT program,
|
||||||
// if it doesn't exist compile a new program in a separate
|
// if it doesn't exist compile a new program in a separate
|
||||||
|
|
|
@ -93,7 +93,7 @@ func (account) SetNonce(uint64) {}
|
||||||
func (account) Balance() *big.Int { return nil }
|
func (account) Balance() *big.Int { return nil }
|
||||||
func (account) Address() common.Address { return common.Address{} }
|
func (account) Address() common.Address { return common.Address{} }
|
||||||
func (account) ReturnGas(*big.Int, *big.Int) {}
|
func (account) ReturnGas(*big.Int, *big.Int) {}
|
||||||
func (account) SetCode([]byte) {}
|
func (account) SetCode(common.Hash, []byte) {}
|
||||||
func (account) ForEachStorage(cb func(key, value common.Hash) bool) {}
|
func (account) ForEachStorage(cb func(key, value common.Hash) bool) {}
|
||||||
|
|
||||||
func runTrace(tracer *JavascriptTracer) (interface{}, error) {
|
func runTrace(tracer *JavascriptTracer) (interface{}, error) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
@ -60,7 +61,7 @@ func makeTestState() (common.Hash, ethdb.Database) {
|
||||||
so.SetNonce(100)
|
so.SetNonce(100)
|
||||||
}
|
}
|
||||||
so.AddBalance(big.NewInt(int64(i)))
|
so.AddBalance(big.NewInt(int64(i)))
|
||||||
so.SetCode([]byte{i, i, i})
|
so.SetCode(crypto.Keccak256Hash([]byte{i, i, i}), []byte{i, i, i})
|
||||||
so.UpdateRoot(sdb)
|
so.UpdateRoot(sdb)
|
||||||
st.UpdateStateObject(so)
|
st.UpdateStateObject(so)
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
@ -219,7 +220,7 @@ func (t *BlockTest) InsertPreState(db ethdb.Database) (*state.StateDB, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
obj := statedb.CreateAccount(common.HexToAddress(addrString))
|
obj := statedb.CreateAccount(common.HexToAddress(addrString))
|
||||||
obj.SetCode(code)
|
obj.SetCode(crypto.Keccak256Hash(code), code)
|
||||||
obj.SetBalance(balance)
|
obj.SetBalance(balance)
|
||||||
obj.SetNonce(nonce)
|
obj.SetNonce(nonce)
|
||||||
for k, v := range acct.Storage {
|
for k, v := range acct.Storage {
|
||||||
|
|
|
@ -108,12 +108,13 @@ func StateObjectFromAccount(db ethdb.Database, addr string, account Account, onD
|
||||||
account.Code = account.Code[2:]
|
account.Code = account.Code[2:]
|
||||||
}
|
}
|
||||||
code := common.Hex2Bytes(account.Code)
|
code := common.Hex2Bytes(account.Code)
|
||||||
|
codeHash := crypto.Keccak256Hash(code)
|
||||||
obj := state.NewObject(common.HexToAddress(addr), state.Account{
|
obj := state.NewObject(common.HexToAddress(addr), state.Account{
|
||||||
Balance: common.Big(account.Balance),
|
Balance: common.Big(account.Balance),
|
||||||
CodeHash: crypto.Keccak256(code),
|
CodeHash: codeHash[:],
|
||||||
Nonce: common.Big(account.Nonce).Uint64(),
|
Nonce: common.Big(account.Nonce).Uint64(),
|
||||||
}, onDirty)
|
}, onDirty)
|
||||||
obj.SetCode(code)
|
obj.SetCode(codeHash, code)
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue