This commit is contained in:
Gustav Simonsson 2015-09-01 18:16:14 +00:00
commit 40e1f8bbd5
5 changed files with 22 additions and 15 deletions

View file

@ -73,23 +73,21 @@ func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block
coinbase.SetGasLimit(block.GasLimit()) coinbase.SetGasLimit(block.GasLimit())
// Process the transactions on to parent state // Process the transactions on to parent state
receipts, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), transientProcess) receipts, err = sm.ApplyTransactions(&coinbase, statedb, block, block.Transactions(), transientProcess)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return receipts, nil return receipts, nil
} }
func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, transientProcess bool) (*types.Receipt, *big.Int, error) { func (self *BlockProcessor) ApplyTransaction(coinbasePtr **state.StateObject, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, transientProcess bool) (*types.Receipt, *big.Int, error) {
cb := statedb.GetStateObject(coinbase.Address()) cb := statedb.GetStateObject((*coinbasePtr).Address())
_, gas, err := ApplyMessage(NewEnv(statedb, self.bc, tx, header), tx, cb) _, gas, err := ApplyMessage(NewEnv(statedb, self.bc, tx, header), tx, cb)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
// Update the state with pending changes // Update the state with pending changes
statedb.SyncIntermediate() statedb.SyncIntermediate(coinbasePtr)
usedGas.Add(usedGas, gas) usedGas.Add(usedGas, gas)
receipt := types.NewReceipt(statedb.Root().Bytes(), usedGas) receipt := types.NewReceipt(statedb.Root().Bytes(), usedGas)
@ -118,7 +116,7 @@ func (self *BlockProcessor) ChainManager() *ChainManager {
return self.bc return self.bc
} }
func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, statedb *state.StateDB, block *types.Block, txs types.Transactions, transientProcess bool) (types.Receipts, error) { func (self *BlockProcessor) ApplyTransactions(coinbasePtr **state.StateObject, statedb *state.StateDB, block *types.Block, txs types.Transactions, transientProcess bool) (types.Receipts, error) {
var ( var (
receipts types.Receipts receipts types.Receipts
totalUsedGas = big.NewInt(0) totalUsedGas = big.NewInt(0)
@ -130,7 +128,7 @@ func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state
for i, tx := range txs { for i, tx := range txs {
statedb.StartRecord(tx.Hash(), block.Hash(), i) statedb.StartRecord(tx.Hash(), block.Hash(), i)
receipt, txGas, err := self.ApplyTransaction(coinbase, statedb, header, tx, totalUsedGas, transientProcess) receipt, txGas, err := self.ApplyTransaction(coinbasePtr, statedb, header, tx, totalUsedGas, transientProcess)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -93,7 +93,7 @@ func (b *BlockGen) AddTx(tx *types.Transaction) {
if err != nil { if err != nil {
panic(err) panic(err)
} }
b.statedb.SyncIntermediate() b.statedb.SyncIntermediate(&b.coinbase)
b.header.GasUsed.Add(b.header.GasUsed, gas) b.header.GasUsed.Add(b.header.GasUsed, gas)
receipt := types.NewReceipt(b.statedb.Root().Bytes(), b.header.GasUsed) receipt := types.NewReceipt(b.statedb.Root().Bytes(), b.header.GasUsed)
logs := b.statedb.GetLogs(tx.Hash()) logs := b.statedb.GetLogs(tx.Hash())
@ -151,7 +151,7 @@ func GenerateChain(parent *types.Block, db common.Database, n int, gen func(int,
gen(i, b) gen(i, b)
} }
AccumulateRewards(statedb, h, b.uncles) AccumulateRewards(statedb, h, b.uncles)
statedb.SyncIntermediate() statedb.SyncIntermediate(&b.coinbase)
h.Root = statedb.Root() h.Root = statedb.Root()
return types.NewBlock(h, b.txs, b.uncles, b.receipts) return types.NewBlock(h, b.txs, b.uncles, b.receipts)
} }

View file

@ -88,7 +88,7 @@ func TestNull(t *testing.T) {
//value := common.FromHex("0x823140710bf13990e4500136726d8b55") //value := common.FromHex("0x823140710bf13990e4500136726d8b55")
var value common.Hash var value common.Hash
state.SetState(address, common.Hash{}, value) state.SetState(address, common.Hash{}, value)
state.SyncIntermediate() state.SyncIntermediate(nil)
state.Sync() state.Sync()
value = state.GetState(address, common.Hash{}) value = state.GetState(address, common.Hash{})
if !common.EmptyHash(value) { if !common.EmptyHash(value) {

View file

@ -349,16 +349,25 @@ func (self *StateDB) Refunds() *big.Int {
} }
// SyncIntermediate updates the intermediate state and all mid steps // SyncIntermediate updates the intermediate state and all mid steps
func (self *StateDB) SyncIntermediate() { func (self *StateDB) SyncIntermediate(coinbaseRef **StateObject) {
self.refund = new(big.Int) self.refund = new(big.Int)
for _, stateObject := range self.stateObjects { for _, stateObject := range self.stateObjects {
if stateObject.dirty { if stateObject.dirty {
if stateObject.remove { if stateObject.remove {
self.DeleteStateObject(stateObject) if stateObject == (*coinbaseRef) {
// Save the original address and remaining gas
address, gas := (*coinbaseRef).Address(), new(big.Int).Set((*coinbaseRef).gasPool)
self.DeleteStateObject(stateObject)
// Resurrect the coinbase and restore the gas allowance
*coinbaseRef = self.CreateAccount(address)
(*coinbaseRef).SetGasLimit(gas)
} else {
self.DeleteStateObject(stateObject)
}
} else { } else {
stateObject.Update() stateObject.Update()
self.UpdateStateObject(stateObject) self.UpdateStateObject(stateObject)
} }
stateObject.dirty = false stateObject.dirty = false

View file

@ -619,7 +619,7 @@ func (env *Work) commitTransactions(transactions types.Transactions, gasPrice *b
func (env *Work) commitTransaction(tx *types.Transaction, proc *core.BlockProcessor) error { func (env *Work) commitTransaction(tx *types.Transaction, proc *core.BlockProcessor) error {
snap := env.state.Copy() snap := env.state.Copy()
receipt, _, err := proc.ApplyTransaction(env.coinbase, env.state, env.header, tx, env.header.GasUsed, true) receipt, _, err := proc.ApplyTransaction(&env.coinbase, env.state, env.header, tx, env.header.GasUsed, true)
if err != nil { if err != nil {
env.state.Set(snap) env.state.Set(snap)
return err return err