Fix invalid code commitment

This commit is contained in:
Aleksandr Bezobchuk 2018-10-22 22:30:13 -04:00
parent 0c3975ef5c
commit f938f74cf0
2 changed files with 27 additions and 12 deletions

View File

@ -222,6 +222,13 @@ func (so *stateObject) commitState() {
// TODO: Set the account (storage) root (but we probably don't need this) // TODO: Set the account (storage) root (but we probably don't need this)
} }
// commitCode persists the state object's code to the KVStore.
func (so *stateObject) commitCode() {
ctx := so.stateDB.ctx
store := ctx.KVStore(so.stateDB.codeKey)
store.Set(so.CodeHash(), so.code)
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Getters // Getters
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -299,8 +306,6 @@ func (so *stateObject) GetCommittedState(_ ethstate.Database, key ethcmn.Hash) e
store := ctx.KVStore(so.stateDB.storageKey) store := ctx.KVStore(so.stateDB.storageKey)
rawValue := store.Get(prefixKey.Bytes()) rawValue := store.Get(prefixKey.Bytes())
// TODO: Do we need to RLP split/decode?
if len(rawValue) > 0 { if len(rawValue) > 0 {
value.SetBytes(rawValue) value.SetBytes(rawValue)
} }

View File

@ -327,6 +327,7 @@ func (csdb *CommitStateDB) Commit(deleteEmptyObjects bool) (root ethcmn.Hash, er
// set the state objects // set the state objects
for addr, so := range csdb.stateObjects { for addr, so := range csdb.stateObjects {
_, isDirty := csdb.stateObjectsDirty[addr] _, isDirty := csdb.stateObjectsDirty[addr]
switch { switch {
case so.suicided || (isDirty && deleteEmptyObjects && so.empty()): case so.suicided || (isDirty && deleteEmptyObjects && so.empty()):
// If the state object has been removed, don't bother syncing it and just // If the state object has been removed, don't bother syncing it and just
@ -336,7 +337,7 @@ func (csdb *CommitStateDB) Commit(deleteEmptyObjects bool) (root ethcmn.Hash, er
case isDirty: case isDirty:
// write any contract code associated with the state object // write any contract code associated with the state object
if so.code != nil && so.dirtyCode { if so.code != nil && so.dirtyCode {
csdb.SetCode(so.Address(), so.code) so.commitCode()
so.dirtyCode = false so.dirtyCode = false
} }
@ -415,7 +416,15 @@ func (csdb *CommitStateDB) deleteStateObject(so *stateObject) {
func (csdb *CommitStateDB) Snapshot() int { func (csdb *CommitStateDB) Snapshot() int {
id := csdb.nextRevisionID id := csdb.nextRevisionID
csdb.nextRevisionID++ csdb.nextRevisionID++
csdb.validRevisions = append(csdb.validRevisions, ethstate.Revision{id, csdb.journal.length()})
csdb.validRevisions = append(
csdb.validRevisions,
ethstate.Revision{
ID: id,
JournalIndex: csdb.journal.length(),
},
)
return id return id
} }
@ -665,12 +674,12 @@ func (csdb *CommitStateDB) setError(err error) {
// Returns nil and sets an error if not found. // Returns nil and sets an error if not found.
func (csdb *CommitStateDB) getStateObject(addr ethcmn.Address) (stateObject *stateObject) { func (csdb *CommitStateDB) getStateObject(addr ethcmn.Address) (stateObject *stateObject) {
// prefer 'live' (cached) objects // prefer 'live' (cached) objects
if obj := csdb.stateObjects[addr]; obj != nil { if so := csdb.stateObjects[addr]; so != nil {
if obj.deleted { if so.deleted {
return nil return nil
} }
return obj return so
} }
// otherwise, attempt to fetch the account from the account mapper // otherwise, attempt to fetch the account from the account mapper
@ -681,11 +690,12 @@ func (csdb *CommitStateDB) getStateObject(addr ethcmn.Address) (stateObject *sta
} }
// insert the state object into the live set // insert the state object into the live set
obj := newObject(csdb, acc) so := newObject(csdb, acc)
csdb.setStateObject(obj) csdb.setStateObject(so)
return obj
return so
} }
func (csdb *CommitStateDB) setStateObject(object *stateObject) { func (csdb *CommitStateDB) setStateObject(so *stateObject) {
csdb.stateObjects[object.Address()] = object csdb.stateObjects[so.Address()] = so
} }