mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 19:00:46 +00:00
fix masternode stop block production.
This commit is contained in:
parent
a8fc240b29
commit
916b16de71
4 changed files with 42 additions and 33 deletions
|
|
@ -114,6 +114,11 @@ var (
|
||||||
// ones).
|
// ones).
|
||||||
errInvalidCheckpointSigners = errors.New("invalid signer list on checkpoint block")
|
errInvalidCheckpointSigners = errors.New("invalid signer list on checkpoint block")
|
||||||
|
|
||||||
|
// errMismatchingCheckpointSigners is returned if a checkpoint block contains a
|
||||||
|
// list of signers different than the one the local node calculated.
|
||||||
|
errMismatchingCheckpointSigners = errors.New("mismatching signer list on checkpoint block")
|
||||||
|
|
||||||
|
|
||||||
errInvalidCheckpointPenalties = errors.New("invalid penalty list on checkpoint block")
|
errInvalidCheckpointPenalties = errors.New("invalid penalty list on checkpoint block")
|
||||||
|
|
||||||
// errInvalidMixDigest is returned if a block's mix digest is non-zero.
|
// errInvalidMixDigest is returned if a block's mix digest is non-zero.
|
||||||
|
|
@ -134,16 +139,15 @@ var (
|
||||||
// be modified via out-of-range or non-contiguous headers.
|
// be modified via out-of-range or non-contiguous headers.
|
||||||
errInvalidVotingChain = errors.New("invalid voting chain")
|
errInvalidVotingChain = errors.New("invalid voting chain")
|
||||||
|
|
||||||
// errUnauthorized is returned if a header is signed by a non-authorized entity.
|
// errUnauthorizedSigner is returned if a header is signed by a non-authorized entity.
|
||||||
errUnauthorized = errors.New("unauthorized")
|
errUnauthorizedSigner = errors.New("unauthorized signer")
|
||||||
|
|
||||||
|
// errRecentlySigned is returned if a header is signed by an authorized entity
|
||||||
|
// that already signed a header recently, thus is temporarily not allowed to.
|
||||||
|
errRecentlySigned = errors.New("recently signed")
|
||||||
|
|
||||||
errFailedDoubleValidation = errors.New("wrong pair of creator-validator in double validation")
|
errFailedDoubleValidation = errors.New("wrong pair of creator-validator in double validation")
|
||||||
|
|
||||||
// errWaitTransactions is returned if an empty block is attempted to be sealed
|
|
||||||
// on an instant chain (0 second period). It's important to refuse these as the
|
|
||||||
// block reward is zero, so an empty block just bloats the chain... fast.
|
|
||||||
errWaitTransactions = errors.New("waiting for transactions")
|
|
||||||
|
|
||||||
ErrInvalidCheckpointValidators = errors.New("invalid validators list on checkpoint block")
|
ErrInvalidCheckpointValidators = errors.New("invalid validators list on checkpoint block")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -431,7 +435,7 @@ func (c *XDPoS) verifyCascadingFields(chain consensus.ChainReader, header *types
|
||||||
validSigners := compareSignersLists(masternodesFromCheckpointHeader, signers)
|
validSigners := compareSignersLists(masternodesFromCheckpointHeader, signers)
|
||||||
if !validSigners {
|
if !validSigners {
|
||||||
log.Error("Masternodes lists are different in checkpoint header and snapshot", "number", number, "masternodes_from_checkpoint_header", masternodesFromCheckpointHeader, "masternodes_in_snapshot", signers, "penList", penPenalties)
|
log.Error("Masternodes lists are different in checkpoint header and snapshot", "number", number, "masternodes_from_checkpoint_header", masternodesFromCheckpointHeader, "masternodes_in_snapshot", signers, "penList", penPenalties)
|
||||||
return errInvalidCheckpointSigners
|
return errMismatchingCheckpointSigners
|
||||||
}
|
}
|
||||||
if c.HookVerifyMNs != nil {
|
if c.HookVerifyMNs != nil {
|
||||||
err := c.HookVerifyMNs(header, signers)
|
err := c.HookVerifyMNs(header, signers)
|
||||||
|
|
@ -702,7 +706,7 @@ func (c *XDPoS) verifySeal(chain consensus.ChainReader, header *types.Header, pa
|
||||||
}
|
}
|
||||||
if !valid {
|
if !valid {
|
||||||
log.Debug("Unauthorized creator found", "block number", number, "creator", creator.String(), "masternodes", mstring, "snapshot from parent block", nstring)
|
log.Debug("Unauthorized creator found", "block number", number, "creator", creator.String(), "masternodes", mstring, "snapshot from parent block", nstring)
|
||||||
return errUnauthorized
|
return errUnauthorizedSigner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(masternodes) > 1 {
|
if len(masternodes) > 1 {
|
||||||
|
|
@ -713,7 +717,7 @@ func (c *XDPoS) verifySeal(chain consensus.ChainReader, header *types.Header, pa
|
||||||
if limit := uint64(2); seen > number-limit {
|
if limit := uint64(2); seen > number-limit {
|
||||||
// Only take into account the non-epoch blocks
|
// Only take into account the non-epoch blocks
|
||||||
if number%c.config.Epoch != 0 {
|
if number%c.config.Epoch != 0 {
|
||||||
return errUnauthorized
|
return errRecentlySigned
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -943,7 +947,8 @@ func (c *XDPoS) Seal(chain consensus.ChainReader, block *types.Block, results ch
|
||||||
// For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing)
|
// For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing)
|
||||||
// checkpoint blocks have no tx
|
// checkpoint blocks have no tx
|
||||||
if c.config.Period == 0 && len(block.Transactions()) == 0 && number%c.config.Epoch != 0 {
|
if c.config.Period == 0 && len(block.Transactions()) == 0 && number%c.config.Epoch != 0 {
|
||||||
return errWaitTransactions
|
log.Info("Sealing paused, waiting for transactions")
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
// Don't hold the signer fields for the entire sealing procedure
|
// Don't hold the signer fields for the entire sealing procedure
|
||||||
c.lock.RLock()
|
c.lock.RLock()
|
||||||
|
|
@ -965,7 +970,7 @@ func (c *XDPoS) Seal(chain consensus.ChainReader, block *types.Block, results ch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !valid {
|
if !valid {
|
||||||
return errUnauthorized
|
return errUnauthorizedSigner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If we're amongst the recent signers, wait for the next block
|
// If we're amongst the recent signers, wait for the next block
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/consensus/clique"
|
"github.com/ethereum/go-ethereum/consensus/clique"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
lru "github.com/hashicorp/golang-lru"
|
||||||
)
|
)
|
||||||
|
|
@ -217,11 +218,16 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) {
|
||||||
//if _, ok := snap.Signers[signer]; !ok {
|
//if _, ok := snap.Signers[signer]; !ok {
|
||||||
// return nil, errUnauthorizedSigner
|
// return nil, errUnauthorizedSigner
|
||||||
//}
|
//}
|
||||||
//for _, recent := range snap.Recents {
|
for seen, recent := range snap.Recents {
|
||||||
// if recent == signer {
|
if recent == signer {
|
||||||
// return nil, errRecentlySigned
|
if limit := uint64(2); number < limit || seen > number-limit {
|
||||||
// }
|
if number%s.config.Epoch != 0 {
|
||||||
//}
|
log.Error("errRecentlySigned")
|
||||||
|
return nil, errRecentlySigned
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
snap.Recents[number] = signer
|
snap.Recents[number] = signer
|
||||||
|
|
||||||
// Header authorized, discard any previous votes from the signer
|
// Header authorized, discard any previous votes from the signer
|
||||||
|
|
|
||||||
|
|
@ -1406,10 +1406,12 @@ func (bc *BlockChain) getResultBlock(block *types.Block, verifiedM2 bool) (*Resu
|
||||||
}
|
}
|
||||||
log.Debug("Number block need calculated again", "number", block.NumberU64(), "hash", block.Hash().Hex(), "winners", len(winner))
|
log.Debug("Number block need calculated again", "number", block.NumberU64(), "hash", block.Hash().Hex(), "winners", len(winner))
|
||||||
// Import all the pruned blocks to make the state available
|
// Import all the pruned blocks to make the state available
|
||||||
|
if len(winner) > 0 {
|
||||||
_, _, _, err := bc.insertChain(winner, false)
|
_, _, _, err := bc.insertChain(winner, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case err != nil:
|
case err != nil:
|
||||||
bc.reportBlock(block, nil, err)
|
bc.reportBlock(block, nil, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,8 @@ import (
|
||||||
mapset "github.com/deckarep/golang-set"
|
mapset "github.com/deckarep/golang-set"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/consensus/misc"
|
|
||||||
"github.com/ethereum/go-ethereum/consensus/XDPoS"
|
"github.com/ethereum/go-ethereum/consensus/XDPoS"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus/misc"
|
||||||
"github.com/ethereum/go-ethereum/contracts"
|
"github.com/ethereum/go-ethereum/contracts"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
|
@ -374,13 +374,8 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
|
||||||
case <-timer.C:
|
case <-timer.C:
|
||||||
// If mining is running resubmit a new work cycle periodically to pull in
|
// If mining is running resubmit a new work cycle periodically to pull in
|
||||||
// higher priced transactions. Disable this overhead for pending blocks.
|
// higher priced transactions. Disable this overhead for pending blocks.
|
||||||
if w.isRunning() && (w.config.Clique == nil || w.config.Clique.Period > 0) {
|
if w.isRunning() && (w.config.XDPoS == nil || w.config.XDPoS.Period > 0) {
|
||||||
// Short circuit if no new transaction arrives.
|
commit(false, commitInterruptResubmit)
|
||||||
if atomic.LoadInt32(&w.newTxs) == 0 {
|
|
||||||
timer.Reset(recommit)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
commit(true, commitInterruptResubmit)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case interval := <-w.resubmitIntervalCh:
|
case interval := <-w.resubmitIntervalCh:
|
||||||
|
|
@ -984,7 +979,7 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Info("Not my turn to commit block. Waiting...")
|
log.Info("Not my turn to commit block. Waiting...", "coinbase", w.coinbase, "parent", parent.Header().Number)
|
||||||
// in case some nodes are down
|
// in case some nodes are down
|
||||||
if preIndex == -1 {
|
if preIndex == -1 {
|
||||||
// first block
|
// first block
|
||||||
|
|
@ -1150,6 +1145,7 @@ func (w *worker) commit(uncles []*types.Header, interval func(), update bool, st
|
||||||
receipts[i] = new(types.Receipt)
|
receipts[i] = new(types.Receipt)
|
||||||
*receipts[i] = *l
|
*receipts[i] = *l
|
||||||
}
|
}
|
||||||
|
log.Info("commit", "root", w.current.state.IntermediateRoot(true).String())
|
||||||
s := w.current.state.Copy()
|
s := w.current.state.Copy()
|
||||||
block, err := w.engine.Finalize(w.chain, w.current.header, s, w.current.txs, uncles, w.current.receipts)
|
block, err := w.engine.Finalize(w.chain, w.current.header, s, w.current.txs, uncles, w.current.receipts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue