diff --git a/core/block_processor.go b/core/block_processor.go index d16bef8f6b..b5f96f9a7f 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -89,7 +89,7 @@ func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, stated } // Update the state with pending changes - statedb.SyncIntermediate(header.Coinbase, header.GasLimit) + statedb.SyncIntermediate(coinbase) usedGas.Add(usedGas, gas) receipt := types.NewReceipt(statedb.Root().Bytes(), usedGas) diff --git a/core/chain_makers.go b/core/chain_makers.go index b826113668..1e33a6f574 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -93,7 +93,7 @@ func (b *BlockGen) AddTx(tx *types.Transaction) { if err != nil { panic(err) } - b.statedb.SyncIntermediate(common.Address{}, b.header.GasLimit) + b.statedb.SyncIntermediate(b.coinbase) b.header.GasUsed.Add(b.header.GasUsed, gas) receipt := types.NewReceipt(b.statedb.Root().Bytes(), b.header.GasUsed) 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) } AccumulateRewards(statedb, h, b.uncles) - statedb.SyncIntermediate(h.Coinbase, h.GasLimit) + statedb.SyncIntermediate(b.coinbase) h.Root = statedb.Root() return types.NewBlock(h, b.txs, b.uncles, b.receipts) } diff --git a/core/state/state_test.go b/core/state/state_test.go index 5972d266a9..bfe764ed72 100644 --- a/core/state/state_test.go +++ b/core/state/state_test.go @@ -88,7 +88,7 @@ func TestNull(t *testing.T) { //value := common.FromHex("0x823140710bf13990e4500136726d8b55") var value common.Hash state.SetState(address, common.Hash{}, value) - state.SyncIntermediate() + state.SyncIntermediate(nil) state.Sync() value = state.GetState(address, common.Hash{}) if !common.EmptyHash(value) { diff --git a/core/state/statedb.go b/core/state/statedb.go index ca73618412..c14a4893da 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -349,18 +349,20 @@ func (self *StateDB) Refunds() *big.Int { } // SyncIntermediate updates the intermediate state and all mid steps -func (self *StateDB) SyncIntermediate(headerCoinbase common.Address, headerGasLimit *big.Int) { +func (self *StateDB) SyncIntermediate(coinbase *StateObject) { self.refund = new(big.Int) for _, stateObject := range self.stateObjects { if stateObject.dirty { if stateObject.remove { - if stateObject.address == headerCoinbase { - gasPoolCopy := new(big.Int).Set(stateObject.gasPool) + if stateObject == coinbase { + // Save the original address and remaining gas + address, gas := coinbase.Address(), new(big.Int).Set(coinbase.gasPool) self.DeleteStateObject(stateObject) - coinbase := self.CreateAccount(headerCoinbase) - coinbase.SetGasLimit(headerGasLimit) - coinbase.gasPool = gasPoolCopy + + // Resurrect the coinbase and restore the gas allowance + *coinbase = *self.CreateAccount(address) + coinbase.SetGasLimit(gas) } else { self.DeleteStateObject(stateObject) }