diff --git a/core/state/state_object.go b/core/state/state_object.go index 0379af2de2..81ff205b86 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -96,8 +96,7 @@ type Account struct { Root common.Hash // merkle root of the storage trie CodeHash []byte - // TODO(fjl): track code size here to get it into the cache - // codeSize int + codeSize *int } // NewObject creates a state object. @@ -269,9 +268,20 @@ func (self *StateObject) Code(db trie.Database) []byte { return code } +// CodeSize returns the size of the contract code associated with this object. +func (self *StateObject) CodeSize(db trie.Database) int { + if self.data.codeSize == nil { + self.data.codeSize = new(int) + *self.data.codeSize = len(self.Code(db)) + } + return *self.data.codeSize +} + func (self *StateObject) SetCode(code []byte) { self.code = code self.data.CodeHash = crypto.Keccak256(code) + self.data.codeSize = new(int) + *self.data.codeSize = len(code) self.dirty, self.dirtyCode = true, true } diff --git a/core/state/statedb.go b/core/state/statedb.go index 097e5a1a6f..2dd833f584 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -171,6 +171,14 @@ func (self *StateDB) GetCode(addr common.Address) []byte { return nil } +func (self *StateDB) GetCodeSize(addr common.Address) int { + stateObject := self.GetStateObject(addr) + if stateObject != nil { + return stateObject.CodeSize(self.db) + } + return 0 +} + func (self *StateDB) GetState(a common.Address, b common.Hash) common.Hash { stateObject := self.GetStateObject(a) if stateObject != nil { diff --git a/core/vm/environment.go b/core/vm/environment.go index 747627565e..4bd03de7eb 100644 --- a/core/vm/environment.go +++ b/core/vm/environment.go @@ -94,6 +94,7 @@ type Database interface { GetNonce(common.Address) uint64 SetNonce(common.Address, uint64) + GetCodeSize(common.Address) int GetCode(common.Address) []byte SetCode(common.Address, []byte) diff --git a/core/vm/instructions.go b/core/vm/instructions.go index a95ba26c52..849a8463cc 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -363,7 +363,7 @@ func opCalldataCopy(instr instruction, pc *uint64, env Environment, contract *Co func opExtCodeSize(instr instruction, pc *uint64, env Environment, contract *Contract, memory *Memory, stack *Stack) { addr := common.BigToAddress(stack.pop()) - l := big.NewInt(int64(len(env.Db().GetCode(addr)))) + l := big.NewInt(int64(env.Db().GetCodeSize(addr))) stack.push(l) }