mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
fix error double validation
This commit is contained in:
parent
7c561e5117
commit
3fa13073fd
3 changed files with 28 additions and 34 deletions
|
|
@ -34,4 +34,6 @@ var (
|
||||||
// ErrInvalidNumber is returned if a block's number doesn't equal it's parent's
|
// ErrInvalidNumber is returned if a block's number doesn't equal it's parent's
|
||||||
// plus one.
|
// plus one.
|
||||||
ErrInvalidNumber = errors.New("invalid block number")
|
ErrInvalidNumber = errors.New("invalid block number")
|
||||||
|
|
||||||
|
ErrMissingValidatorSignature = errors.New("missing validator in header")
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -214,10 +214,10 @@ type Posv struct {
|
||||||
config *params.PosvConfig // Consensus engine configuration parameters
|
config *params.PosvConfig // Consensus engine configuration parameters
|
||||||
db ethdb.Database // Database to store and retrieve snapshot checkpoints
|
db ethdb.Database // Database to store and retrieve snapshot checkpoints
|
||||||
|
|
||||||
recents *lru.ARCCache // Snapshots for recent block to speed up reorgs
|
recents *lru.ARCCache // Snapshots for recent block to speed up reorgs
|
||||||
signatures *lru.ARCCache // Signatures of recent blocks to speed up mining
|
signatures *lru.ARCCache // Signatures of recent blocks to speed up mining
|
||||||
|
validatorSignatures *lru.ARCCache // Signatures of recent blocks to speed up mining
|
||||||
proposals map[common.Address]bool // Current list of proposals we are pushing
|
proposals map[common.Address]bool // Current list of proposals we are pushing
|
||||||
|
|
||||||
signer common.Address // Ethereum address of the signing key
|
signer common.Address // Ethereum address of the signing key
|
||||||
signFn clique.SignerFn // Signer function to authorize hashes with
|
signFn clique.SignerFn // Signer function to authorize hashes with
|
||||||
|
|
@ -240,13 +240,14 @@ func New(config *params.PosvConfig, db ethdb.Database) *Posv {
|
||||||
// Allocate the snapshot caches and create the engine
|
// Allocate the snapshot caches and create the engine
|
||||||
recents, _ := lru.NewARC(inmemorySnapshots)
|
recents, _ := lru.NewARC(inmemorySnapshots)
|
||||||
signatures, _ := lru.NewARC(inmemorySignatures)
|
signatures, _ := lru.NewARC(inmemorySignatures)
|
||||||
|
validatorSignatures, _ := lru.NewARC(inmemorySignatures)
|
||||||
return &Posv{
|
return &Posv{
|
||||||
config: &conf,
|
config: &conf,
|
||||||
db: db,
|
db: db,
|
||||||
recents: recents,
|
recents: recents,
|
||||||
signatures: signatures,
|
signatures: signatures,
|
||||||
proposals: make(map[common.Address]bool),
|
validatorSignatures: validatorSignatures,
|
||||||
|
proposals: make(map[common.Address]bool),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -956,12 +957,12 @@ func (c *Posv) RecoverSigner(header *types.Header) (common.Address, error) {
|
||||||
func (c *Posv) RecoverValidator(header *types.Header) (common.Address, error) {
|
func (c *Posv) RecoverValidator(header *types.Header) (common.Address, error) {
|
||||||
// If the signature's already cached, return that
|
// If the signature's already cached, return that
|
||||||
hash := header.Hash()
|
hash := header.Hash()
|
||||||
if address, known := c.signatures.Get(hash); known {
|
if address, known := c.validatorSignatures.Get(hash); known {
|
||||||
return address.(common.Address), nil
|
return address.(common.Address), nil
|
||||||
}
|
}
|
||||||
// Retrieve the signature from the header extra-data
|
// Retrieve the signature from the header extra-data
|
||||||
if len(header.Validator) < extraSeal {
|
if len(header.Validator) < extraSeal {
|
||||||
return common.Address{}, errMissingSignature
|
return common.Address{}, consensus.ErrMissingValidatorSignature
|
||||||
}
|
}
|
||||||
signature := header.Validator[len(header.Validator)-extraSeal:]
|
signature := header.Validator[len(header.Validator)-extraSeal:]
|
||||||
|
|
||||||
|
|
@ -973,7 +974,7 @@ func (c *Posv) RecoverValidator(header *types.Header) (common.Address, error) {
|
||||||
var signer common.Address
|
var signer common.Address
|
||||||
copy(signer[:], crypto.Keccak256(pubkey[1:])[12:])
|
copy(signer[:], crypto.Keccak256(pubkey[1:])[12:])
|
||||||
|
|
||||||
c.signatures.Add(hash, signer)
|
c.validatorSignatures.Add(hash, signer)
|
||||||
return signer, nil
|
return signer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,6 @@ type Fetcher struct {
|
||||||
queueChangeHook func(common.Hash, bool) // Method to call upon adding or deleting a block from the import queue
|
queueChangeHook func(common.Hash, bool) // Method to call upon adding or deleting a block from the import queue
|
||||||
fetchingHook func([]common.Hash) // Method to call upon starting a block (eth/61) or header (eth/62) fetch
|
fetchingHook func([]common.Hash) // Method to call upon starting a block (eth/61) or header (eth/62) fetch
|
||||||
completingHook func([]common.Hash) // Method to call upon starting a block body fetch (eth/62)
|
completingHook func([]common.Hash) // Method to call upon starting a block body fetch (eth/62)
|
||||||
doubleValidateHook func(*types.Block) error
|
|
||||||
signHook func(*types.Block) error
|
signHook func(*types.Block) error
|
||||||
appendM2HeaderHook func(*types.Block) (*types.Block, error)
|
appendM2HeaderHook func(*types.Block) (*types.Block, error)
|
||||||
}
|
}
|
||||||
|
|
@ -654,33 +653,30 @@ func (f *Fetcher) insert(peer string, block *types.Block) {
|
||||||
// Quickly validate the header and propagate the block if it passes
|
// Quickly validate the header and propagate the block if it passes
|
||||||
switch err := f.verifyHeader(block.Header()); err {
|
switch err := f.verifyHeader(block.Header()); err {
|
||||||
case nil:
|
case nil:
|
||||||
|
// All ok, quickly propagate to our peers
|
||||||
|
propBroadcastOutTimer.UpdateSince(block.ReceivedAt)
|
||||||
|
go f.broadcastBlock(block, true)
|
||||||
|
case consensus.ErrFutureBlock:
|
||||||
|
case consensus.ErrMissingValidatorSignature:
|
||||||
|
newBlock := block
|
||||||
if f.appendM2HeaderHook != nil {
|
if f.appendM2HeaderHook != nil {
|
||||||
if block, err = f.appendM2HeaderHook(block); err != nil {
|
if newBlock, err = f.appendM2HeaderHook(block); err != nil {
|
||||||
log.Error("Append m2 to block header fail", "err", err)
|
log.Error("Append m2 to block header fail", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// All ok, quickly propagate to our peers
|
|
||||||
propBroadcastOutTimer.UpdateSince(block.ReceivedAt)
|
|
||||||
go f.broadcastBlock(block, true)
|
go f.broadcastBlock(block, true)
|
||||||
|
if newBlock.Hash() == block.Hash() {
|
||||||
case consensus.ErrFutureBlock:
|
return
|
||||||
// Weird future block, don't fail, but neither propagate
|
}
|
||||||
|
block = newBlock
|
||||||
|
propBroadcastOutTimer.UpdateSince(block.ReceivedAt)
|
||||||
default:
|
default:
|
||||||
// Something went very wrong, drop the peer
|
// Something went very wrong, drop the peer
|
||||||
log.Debug("Propagated block verification failed", "peer", peer, "number", block.Number(), "hash", hash, "err", err)
|
log.Debug("Propagated block verification failed", "peer", peer, "number", block.Number(), "hash", hash, "err", err)
|
||||||
f.dropPeer(peer)
|
f.dropPeer(peer)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Invoke the dv hook to run double validation layer
|
|
||||||
if f.doubleValidateHook != nil {
|
|
||||||
if err := f.doubleValidateHook(block); err != nil {
|
|
||||||
log.Error("Double validation failed", "err", err, "Discard this block!")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the actual import and log any issues
|
// Run the actual import and log any issues
|
||||||
if _, err := f.insertChain(types.Blocks{block}); err != nil {
|
if _, err := f.insertChain(types.Blocks{block}); err != nil {
|
||||||
|
|
@ -756,11 +752,6 @@ func (f *Fetcher) forgetBlock(hash common.Hash) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind double validate hook before block imported into chain.
|
|
||||||
func (f *Fetcher) SetDoubleValidateHook(doubleValidateHook func(*types.Block) error) {
|
|
||||||
f.doubleValidateHook = doubleValidateHook
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind double validate hook before block imported into chain.
|
// Bind double validate hook before block imported into chain.
|
||||||
func (f *Fetcher) SetSignHook(signHook func(*types.Block) error) {
|
func (f *Fetcher) SetSignHook(signHook func(*types.Block) error) {
|
||||||
f.signHook = signHook
|
f.signHook = signHook
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue