core/vm: use common.Hash instead of nil, fix review comments

This commit is contained in:
Martin Holst Swende 2018-10-03 14:22:46 +02:00
parent 72f655d421
commit 5d5a01e3f3
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0
3 changed files with 19 additions and 18 deletions

View file

@ -53,7 +53,7 @@ type Contract struct {
analysis bitvec // Locally cached result of JUMPDEST analysis analysis bitvec // Locally cached result of JUMPDEST analysis
Code []byte Code []byte
CodeHash *common.Hash CodeHash common.Hash
CodeAddr *common.Address CodeAddr *common.Address
Input []byte Input []byte
@ -94,15 +94,15 @@ func (c *Contract) validJumpdest(dest *big.Int) bool {
} }
var analysis bitvec var analysis bitvec
// Do we have a contract hash already? // Do we have a contract hash already?
if c.CodeHash != nil { if c.CodeHash != emptyCodeHash {
var exist bool var exist bool
// Does parent context have the analysis? // Does parent context have the analysis?
analysis, exist = c.jumpdests[*c.CodeHash] analysis, exist = c.jumpdests[c.CodeHash]
if !exist { if !exist {
// Do the analysis // Do the analysis
analysis = codeBitmap(c.Code) analysis = codeBitmap(c.Code)
// Save in parent context // Save in parent context
c.jumpdests[*c.CodeHash] = analysis c.jumpdests[c.CodeHash] = analysis
} }
return analysis.codeSegment(udest) return analysis.codeSegment(udest)
} }
@ -173,13 +173,13 @@ func (c *Contract) Value() *big.Int {
// object // object
func (c *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) { func (c *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) {
c.Code = code c.Code = code
c.CodeHash = &hash c.CodeHash = hash
c.CodeAddr = addr c.CodeAddr = addr
} }
// SetCodeOptionalHash can be used to provide code, but it's optional to provide hash. // SetCodeOptionalHash can be used to provide code, but it's optional to provide hash.
// In case hash is not provided, the jumpdest analysis will not be saved to the parent context // In case hash is not provided, the jumpdest analysis will not be saved to the parent context
func (c *Contract) SetCodeOptionalHash(addr *common.Address, codeAndHash codeAndHash) { func (c *Contract) SetCodeOptionalHash(addr *common.Address, codeAndHash *codeAndHash) {
c.Code = codeAndHash.code c.Code = codeAndHash.code
c.CodeHash = codeAndHash.hash c.CodeHash = codeAndHash.hash
c.CodeAddr = addr c.CodeAddr = addr

View file

@ -354,19 +354,18 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
type codeAndHash struct { type codeAndHash struct {
code []byte code []byte
hash *common.Hash hash common.Hash
} }
func (c *codeAndHash) Hash() common.Hash { func (c *codeAndHash) Hash() common.Hash {
if c.hash == nil { if c.hash == emptyCodeHash {
h := crypto.Keccak256Hash(c.code) c.hash = crypto.Keccak256Hash(c.code)
c.hash = &h
} }
return *c.hash 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, codeAndHash codeAndHash, 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) {
@ -445,9 +444,8 @@ func (evm *EVM) create(caller ContractRef, codeAndHash codeAndHash, gas uint64,
// 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, codeAndHash, gas, value, contractAddr) return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr)
} }
// Create2 creates a new contract using code as deployment code. // Create2 creates a new contract using code as deployment code.
@ -455,7 +453,7 @@ 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) {
codeAndHash := codeAndHash{code: code} codeAndHash := &codeAndHash{code: code}
contractAddr = crypto.CreateAddress2(caller.Address(), common.BigToHash(salt), codeAndHash.Hash().Bytes()) contractAddr = crypto.CreateAddress2(caller.Address(), common.BigToHash(salt), codeAndHash.Hash().Bytes())
return evm.create(caller, codeAndHash, gas, endowment, contractAddr) return evm.create(caller, codeAndHash, gas, endowment, contractAddr)
} }

View file

@ -390,10 +390,13 @@ func (api *PrivateDebugAPI) TraceBlockFromFile(ctx context.Context, file string,
} }
return api.TraceBlock(ctx, blob, config) return api.TraceBlock(ctx, blob, config)
} }
// TraceBadBlock returns the structured logs created during the execution of a block
// within the blockchain 'badblocks' cache
func (api *PrivateDebugAPI) TraceBadBlock(ctx context.Context, index int, config *TraceConfig) ([]*txTraceResult, error) { func (api *PrivateDebugAPI) TraceBadBlock(ctx context.Context, index int, config *TraceConfig) ([]*txTraceResult, error) {
if len := len(api.eth.blockchain.BadBlocks()); index < len { badBlocks := api.eth.blockchain.BadBlocks()
block := api.eth.blockchain.BadBlocks()[index] if l := len(badBlocks); index < l {
return api.traceBlock(ctx, block, config) return api.traceBlock(ctx, badBlocks[index], config)
} }
return nil, fmt.Errorf("index out of range") return nil, fmt.Errorf("index out of range")
} }