Merge branch 'slasher-flix' into 'master'

Fix for "Slash validator failed"

See merge request pulsechaincom/go-pulse!43
This commit is contained in:
sjb933 2022-03-28 20:19:15 +00:00
commit 30e781c936
8 changed files with 22 additions and 15 deletions

View File

@ -284,11 +284,11 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.
// FinalizeAndAssemble implements consensus.Engine, setting the final state and
// assembling the block.
func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, finalUpdate bool) (*types.Block, []*types.Receipt, error) {
func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, []*types.Receipt, error) {
// FinalizeAndAssemble 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) {
return beacon.ethone.FinalizeAndAssemble(chain, header, state, txs, uncles, receipts, finalUpdate)
return beacon.ethone.FinalizeAndAssemble(chain, header, state, txs, uncles, receipts)
}
// Finalize and assemble the block
beacon.Finalize(chain, header, state, &txs, uncles, nil, nil, nil)

View File

@ -572,7 +572,7 @@ func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Heade
// FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set,
// nor block rewards given, and returns the final block.
func (c *Clique) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB,
txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, finalUpdate bool) (*types.Block, []*types.Receipt, error) {
txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, []*types.Receipt, error) {
// Finalize block
c.Finalize(chain, header, state, &txs, uncles, nil, nil, nil)

View File

@ -103,7 +103,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).
FinalizeAndAssemble(chain ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
uncles []*types.Header, receipts []*types.Receipt, firstPass bool) (*types.Block, []*types.Receipt, error)
uncles []*types.Header, receipts []*types.Receipt) (*types.Block, []*types.Receipt, error)
// Seal generates a new sealing request for the given input block and pushes
// the result into the given channel.

View File

@ -601,7 +601,7 @@ func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types.
// 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, finalUpdate bool) (*types.Block, []*types.Receipt, error) {
txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, []*types.Receipt, error) {
ethash.Finalize(chain, header, state, &txs, uncles, nil, nil, nil)

View File

@ -810,7 +810,7 @@ func (p *Parlia) Finalize(chain consensus.ChainHeaderReader, header *types.Heade
// FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set,
// nor block rewards given, and returns the final block.
func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB,
txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, firstPass bool) (*types.Block, []*types.Receipt, error) {
txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, []*types.Receipt, error) {
// No block rewards in PoA, so the state remains as is and uncles are dropped
cx := chainContext{Chain: chain, parlia: p}
if txs == nil {
@ -819,12 +819,13 @@ func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *
if receipts == nil {
receipts = make([]*types.Receipt, 0)
}
usedGas := header.GasUsed
number := header.Number.Uint64()
if header.Number.Cmp(common.Big1) == 0 || p.chainConfig.IsPrimordialPulseBlock(number) {
log.Info("Initializing system contracts", "number", header.Number)
if err := p.initContracts(state, header, cx, &txs, &receipts, nil, &header.GasUsed, true); err != nil {
if err := p.initContracts(state, header, cx, &txs, &receipts, nil, &usedGas, true); err != nil {
log.Error("Failed to initialize system contracts")
}
@ -838,13 +839,13 @@ func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *
// on the next block (epoch), the authorization snapshot will be updated
if (number+1)%(p.config.Epoch*p.config.Era) == 0 {
log.Info("Triggering staked validator rotation", "number", number)
err := p.rotateValidators(state, header, cx, &txs, &receipts, nil, &header.GasUsed, true)
err := p.rotateValidators(state, header, cx, &txs, &receipts, nil, &usedGas, true)
if err != nil {
log.Error("Staked validator rotation failed", "number", number, "err", err)
}
}
if firstPass && header.Difficulty.Cmp(diffInTurn) != 0 {
if header.Difficulty.Cmp(diffInTurn) != 0 {
snap, err := p.snapshot(chain, number-1, header.ParentHash, nil)
if err != nil {
panic(err)
@ -858,7 +859,7 @@ func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *
}
}
if !signedRecently {
err = p.slash(spoiledVal, state, header, cx, &txs, &receipts, nil, &header.GasUsed, true)
err = p.slash(spoiledVal, state, header, cx, &txs, &receipts, nil, &usedGas, true)
if err != nil {
// it is possible that slash validator failed because of the slash channel is disabled.
log.Error("Slash validator failed", "block hash", header.Hash(), "address", spoiledVal, "err", err)
@ -866,14 +867,18 @@ func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *
}
}
err := p.distributeIncoming(p.val, state, header, cx, &txs, &receipts, nil, &header.GasUsed, true)
err := p.distributeIncoming(p.val, state, header, cx, &txs, &receipts, nil, &usedGas, true)
if err != nil {
panic(err)
}
// should not happen. Once happen, stop the node is better than broadcast the block
if header.GasLimit < header.GasUsed {
if header.GasLimit < usedGas {
panic("Gas consumption of system txs exceed the gas limit")
}
// CAUTION: header is currently passed by reference, so these changes mutate the caller's value.
if !p.chainConfig.IsSystemZero(header.Number) {
header.GasUsed = usedGas
}
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
header.UncleHash = types.CalcUncleHash(nil)

View File

@ -261,7 +261,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
}
if b.engine != nil {
// Finalize and seal the block
block, _, _ := b.engine.FinalizeAndAssemble(chainreader, b.header, statedb, b.txs, b.uncles, b.receipts, true)
block, _, _ := b.engine.FinalizeAndAssemble(chainreader, b.header, statedb, b.txs, b.uncles, b.receipts)
// Write state changes to db
root, err := statedb.Commit(config.IsEIP158(b.header.Number))

View File

@ -380,7 +380,7 @@ func (api *ConsensusAPI) assembleBlock(parentHash common.Hash, params *PayloadAt
}
}
// Create the block.
block, _, err := api.eth.Engine().FinalizeAndAssemble(bc, header, env.state, transactions, nil /* uncles */, env.receipts, true)
block, _, err := api.eth.Engine().FinalizeAndAssemble(bc, header, env.state, transactions, nil /* uncles */, env.receipts)
if err != nil {
return nil, err
}

View File

@ -1049,7 +1049,9 @@ func (w *worker) commit(uncles []*types.Header, interval func(), update bool, st
// Deep copy receipts here to avoid interaction between different tasks.
receipts := copyReceipts(w.current.receipts)
s := w.current.state.Copy()
block, receipts, err := w.engine.FinalizeAndAssemble(w.chain, w.current.header, s, w.current.txs, uncles, receipts, !update)
// CAUTION: types.CopyHeader() is required due to the header being passed by
// reference, and Parlia mutates it.
block, receipts, err := w.engine.FinalizeAndAssemble(w.chain, types.CopyHeader(w.current.header), s, w.current.txs, uncles, receipts)
if err != nil {
return err
}