mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
core/vm: do less hashing in CREATE2
This commit is contained in:
parent
c4e3625209
commit
efc32877de
2 changed files with 24 additions and 9 deletions
|
|
@ -352,8 +352,21 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
|
||||||
return ret, contract.Gas, err
|
return ret, contract.Gas, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type codeAndHash struct {
|
||||||
|
code []byte
|
||||||
|
hash *common.Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *codeAndHash) Hash() common.Hash {
|
||||||
|
if c.hash == nil {
|
||||||
|
h := crypto.Keccak256Hash(c.code)
|
||||||
|
c.hash = &h
|
||||||
|
}
|
||||||
|
return *c.hash
|
||||||
|
}
|
||||||
|
|
||||||
// create creates a new contract using code as deployment code.
|
// create creates a new contract using code as deployment code.
|
||||||
func (evm *EVM) create(caller ContractRef, code []byte, gas uint64, value *big.Int, address common.Address) ([]byte, common.Address, uint64, error) {
|
func (evm *EVM) create(caller ContractRef, codeAndHash codeAndHash, gas uint64, value *big.Int, address common.Address) ([]byte, common.Address, uint64, error) {
|
||||||
// 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.
|
||||||
if evm.depth > int(params.CallCreateDepth) {
|
if evm.depth > int(params.CallCreateDepth) {
|
||||||
|
|
@ -382,14 +395,14 @@ func (evm *EVM) create(caller ContractRef, code []byte, gas uint64, value *big.I
|
||||||
// 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 := NewContract(caller, AccountRef(address), value, gas)
|
contract := NewContract(caller, AccountRef(address), value, gas)
|
||||||
contract.SetCallCode(&address, crypto.Keccak256Hash(code), code)
|
contract.SetCallCode(&address, codeAndHash.Hash(), codeAndHash.code)
|
||||||
|
|
||||||
if evm.vmConfig.NoRecursion && evm.depth > 0 {
|
if evm.vmConfig.NoRecursion && evm.depth > 0 {
|
||||||
return nil, address, gas, nil
|
return nil, address, gas, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if evm.vmConfig.Debug && evm.depth == 0 {
|
if evm.vmConfig.Debug && evm.depth == 0 {
|
||||||
evm.vmConfig.Tracer.CaptureStart(caller.Address(), address, true, code, gas, value)
|
evm.vmConfig.Tracer.CaptureStart(caller.Address(), address, true, codeAndHash.code, gas, value)
|
||||||
}
|
}
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
|
|
@ -432,8 +445,9 @@ func (evm *EVM) create(caller ContractRef, code []byte, gas uint64, value *big.I
|
||||||
|
|
||||||
// Create creates a new contract using code as deployment code.
|
// Create creates a new contract using code as deployment code.
|
||||||
func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
|
func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
|
||||||
|
codeAndHash := codeAndHash{code: code}
|
||||||
contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address()))
|
contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address()))
|
||||||
return evm.create(caller, code, gas, value, contractAddr)
|
return evm.create(caller, codeAndHash, gas, value, contractAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create2 creates a new contract using code as deployment code.
|
// Create2 creates a new contract using code as deployment code.
|
||||||
|
|
@ -441,8 +455,9 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I
|
||||||
// The different between Create2 with Create is Create2 uses sha3(0xff ++ msg.sender ++ salt ++ sha3(init_code))[12:]
|
// The different between Create2 with Create is Create2 uses sha3(0xff ++ msg.sender ++ salt ++ sha3(init_code))[12:]
|
||||||
// instead of the usual sender-and-nonce-hash as the address where the contract is initialized at.
|
// instead of the usual sender-and-nonce-hash as the address where the contract is initialized at.
|
||||||
func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *big.Int, salt *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
|
func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *big.Int, salt *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
|
||||||
contractAddr = crypto.CreateAddress2(caller.Address(), common.BigToHash(salt), code)
|
codeAndHash := codeAndHash{code: code}
|
||||||
return evm.create(caller, code, gas, endowment, contractAddr)
|
contractAddr = crypto.CreateAddress2(caller.Address(), common.BigToHash(salt), codeAndHash.Hash().Bytes())
|
||||||
|
return evm.create(caller, codeAndHash, gas, endowment, contractAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChainConfig returns the environment's chain configuration
|
// ChainConfig returns the environment's chain configuration
|
||||||
|
|
|
||||||
|
|
@ -77,9 +77,9 @@ func CreateAddress(b common.Address, nonce uint64) common.Address {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateAddress2 creates an ethereum address given the address bytes, initial
|
// CreateAddress2 creates an ethereum address given the address bytes, initial
|
||||||
// contract code and a salt.
|
// contract code hash and a salt.
|
||||||
func CreateAddress2(b common.Address, salt [32]byte, code []byte) common.Address {
|
func CreateAddress2(b common.Address, salt [32]byte, inithash []byte) common.Address {
|
||||||
return common.BytesToAddress(Keccak256([]byte{0xff}, b.Bytes(), salt[:], Keccak256(code))[12:])
|
return common.BytesToAddress(Keccak256([]byte{0xff}, b.Bytes(), salt[:], inithash)[12:])
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToECDSA creates a private key with the given D value.
|
// ToECDSA creates a private key with the given D value.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue