Skip to content

Commit

Permalink
consensus: abort upon rewards calculation error
Browse files Browse the repository at this point in the history
  • Loading branch information
sadoci committed Mar 21, 2022
1 parent c116cc5 commit a0e66b5
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 20 deletions.
5 changes: 3 additions & 2 deletions consensus/beacon/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,16 +264,17 @@ func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.H
}

// Finalize implements consensus.Engine, setting the final state on the header
func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) {
func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) error {
// Finalize is different with Prepare, it can be used in both block generation
// and verification. So determine the consensus rules by header type.
if !beacon.IsPoSHeader(header) {
beacon.ethone.Finalize(chain, header, state, txs, uncles)
return
return nil
}
// The block reward is no longer handled here. It's done by the
// external consensus engine.
header.Root = state.IntermediateRoot(true)
return nil
}

// FinalizeAndAssemble implements consensus.Engine, setting the final state and
Expand Down
3 changes: 2 additions & 1 deletion consensus/clique/clique.go
Original file line number Diff line number Diff line change
Expand Up @@ -561,10 +561,11 @@ func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header

// Finalize implements consensus.Engine, ensuring no uncles are set, nor block
// rewards given.
func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) {
func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) error {
// No block rewards in PoA, so the state remains as is and uncles are dropped
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
header.UncleHash = types.CalcUncleHash(nil)
return nil
}

// FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set,
Expand Down
2 changes: 1 addition & 1 deletion consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ type Engine interface {
// Note: The block header and state database might be updated to reflect any
// consensus rules that happen at finalization (e.g. block rewards).
Finalize(chain ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
uncles []*types.Header)
uncles []*types.Header) error

// FinalizeAndAssemble runs any post-transaction state modifications (e.g. block
// rewards) and assembles the final block.
Expand Down
32 changes: 16 additions & 16 deletions consensus/ethash/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -600,17 +600,22 @@ func (ethash *Ethash) Prepare(chain consensus.ChainHeaderReader, header *types.H

// Finalize implements consensus.Engine, accumulating the block and uncle rewards,
// setting the final state on the header
func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) {
func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) error {
// Accumulate any block and uncle rewards and commit the final state root
accumulateRewards(chain.Config(), state, header, uncles)
if err := accumulateRewards(chain.Config(), state, header, uncles); err != nil {
return err
}
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
return nil
}

// FinalizeAndAssemble implements consensus.Engine, accumulating the block and
// uncle rewards, setting the final state and assembling the block.
func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
// Finalize block
ethash.Finalize(chain, header, state, txs, uncles)
if err := ethash.Finalize(chain, header, state, txs, uncles); err != nil {
return nil, err
}

// sign header.Root with node's private key
if !metaminer.IsPoW() {
Expand Down Expand Up @@ -663,7 +668,7 @@ var (
// AccumulateRewards credits the coinbase of the given block with the mining
// reward. The total reward consists of the static block reward and rewards for
// included uncles. The coinbase of each uncle block is also rewarded.
func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) {
func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) error {
// Select the correct block reward based on chain progression
blockReward := FrontierBlockReward
if config.IsByzantium(header.Number) {
Expand Down Expand Up @@ -695,18 +700,13 @@ func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header
func(addr common.Address, amt *big.Int) {
state.AddBalance(addr, amt)
})
if err == nil {
header.Rewards = rewards
if coinbase != nil {
header.Coinbase = *coinbase
}
} else {
// upon error, rewards go to the coinbase
reward := new(big.Int)
if header.Fees != nil {
reward.Add(blockReward, header.Fees)
}
state.AddBalance(header.Coinbase, reward)
if err != nil {
return err
}
header.Rewards = rewards
if coinbase != nil {
header.Coinbase = *coinbase
}
}
return nil
}

0 comments on commit a0e66b5

Please sign in to comment.