parlia: fix verifyVoteAttestation when verify a batch of headers (#2121)
This commit is contained in:
parent
124939aaa4
commit
de1a126ec5
@ -150,7 +150,7 @@ type PoSA interface {
|
|||||||
IsSystemContract(to *common.Address) bool
|
IsSystemContract(to *common.Address) bool
|
||||||
EnoughDistance(chain ChainReader, header *types.Header) bool
|
EnoughDistance(chain ChainReader, header *types.Header) bool
|
||||||
IsLocalBlock(header *types.Header) bool
|
IsLocalBlock(header *types.Header) bool
|
||||||
GetJustifiedNumberAndHash(chain ChainHeaderReader, header *types.Header) (uint64, common.Hash, error)
|
GetJustifiedNumberAndHash(chain ChainHeaderReader, headers []*types.Header) (uint64, common.Hash, error)
|
||||||
GetFinalizedHeader(chain ChainHeaderReader, header *types.Header) *types.Header
|
GetFinalizedHeader(chain ChainHeaderReader, header *types.Header) *types.Header
|
||||||
VerifyVote(chain ChainHeaderReader, vote *types.VoteEnvelope) error
|
VerifyVote(chain ChainHeaderReader, vote *types.VoteEnvelope) error
|
||||||
IsActiveValidatorAt(chain ChainHeaderReader, header *types.Header, checkVoteKeyFn func(bLSPublicKey *types.BLSPublicKey) bool) bool
|
IsActiveValidatorAt(chain ChainHeaderReader, header *types.Header, checkVoteKeyFn func(bLSPublicKey *types.BLSPublicKey) bool) bool
|
||||||
|
@ -447,7 +447,11 @@ func (p *Parlia) verifyVoteAttestation(chain consensus.ChainHeaderReader, header
|
|||||||
// The source block should be the highest justified block.
|
// The source block should be the highest justified block.
|
||||||
sourceNumber := attestation.Data.SourceNumber
|
sourceNumber := attestation.Data.SourceNumber
|
||||||
sourceHash := attestation.Data.SourceHash
|
sourceHash := attestation.Data.SourceHash
|
||||||
justifiedBlockNumber, justifiedBlockHash, err := p.GetJustifiedNumberAndHash(chain, parent)
|
headers := []*types.Header{parent}
|
||||||
|
if len(parents) > 0 {
|
||||||
|
headers = parents
|
||||||
|
}
|
||||||
|
justifiedBlockNumber, justifiedBlockHash, err := p.GetJustifiedNumberAndHash(chain, headers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unexpected error when getting the highest justified number and hash")
|
return fmt.Errorf("unexpected error when getting the highest justified number and hash")
|
||||||
}
|
}
|
||||||
@ -871,7 +875,7 @@ func (p *Parlia) assembleVoteAttestation(chain consensus.ChainHeaderReader, head
|
|||||||
|
|
||||||
// Prepare vote attestation
|
// Prepare vote attestation
|
||||||
// Prepare vote data
|
// Prepare vote data
|
||||||
justifiedBlockNumber, justifiedBlockHash, err := p.GetJustifiedNumberAndHash(chain, parent)
|
justifiedBlockNumber, justifiedBlockHash, err := p.GetJustifiedNumberAndHash(chain, []*types.Header{parent})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unexpected error when getting the highest justified number and hash")
|
return fmt.Errorf("unexpected error when getting the highest justified number and hash")
|
||||||
}
|
}
|
||||||
@ -1266,7 +1270,7 @@ func (p *Parlia) VerifyVote(chain consensus.ChainHeaderReader, vote *types.VoteE
|
|||||||
return fmt.Errorf("target number mismatch")
|
return fmt.Errorf("target number mismatch")
|
||||||
}
|
}
|
||||||
|
|
||||||
justifiedBlockNumber, justifiedBlockHash, err := p.GetJustifiedNumberAndHash(chain, header)
|
justifiedBlockNumber, justifiedBlockHash, err := p.GetJustifiedNumberAndHash(chain, []*types.Header{header})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to get the highest justified number and hash", "headerNumber", header.Number, "headerHash", header.Hash())
|
log.Error("failed to get the highest justified number and hash", "headerNumber", header.Number, "headerHash", header.Hash())
|
||||||
return fmt.Errorf("unexpected error when getting the highest justified number and hash")
|
return fmt.Errorf("unexpected error when getting the highest justified number and hash")
|
||||||
@ -1751,20 +1755,22 @@ func (p *Parlia) applyTransaction(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetJustifiedNumberAndHash returns the highest justified block's number and hash on the branch including and before `header`
|
// GetJustifiedNumberAndHash retrieves the number and hash of the highest justified block
|
||||||
func (p *Parlia) GetJustifiedNumberAndHash(chain consensus.ChainHeaderReader, header *types.Header) (uint64, common.Hash, error) {
|
// within the branch including `headers` and utilizing the latest element as the head.
|
||||||
if chain == nil || header == nil {
|
func (p *Parlia) GetJustifiedNumberAndHash(chain consensus.ChainHeaderReader, headers []*types.Header) (uint64, common.Hash, error) {
|
||||||
|
if chain == nil || len(headers) == 0 || headers[len(headers)-1] == nil {
|
||||||
return 0, common.Hash{}, fmt.Errorf("illegal chain or header")
|
return 0, common.Hash{}, fmt.Errorf("illegal chain or header")
|
||||||
}
|
}
|
||||||
snap, err := p.snapshot(chain, header.Number.Uint64(), header.Hash(), nil)
|
head := headers[len(headers)-1]
|
||||||
|
snap, err := p.snapshot(chain, head.Number.Uint64(), head.Hash(), headers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unexpected error when getting snapshot",
|
log.Error("Unexpected error when getting snapshot",
|
||||||
"error", err, "blockNumber", header.Number.Uint64(), "blockHash", header.Hash())
|
"error", err, "blockNumber", head.Number.Uint64(), "blockHash", head.Hash())
|
||||||
return 0, common.Hash{}, err
|
return 0, common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if snap.Attestation == nil {
|
if snap.Attestation == nil {
|
||||||
if p.chainConfig.IsLuban(header.Number) {
|
if p.chainConfig.IsLuban(head.Number) {
|
||||||
log.Debug("once one attestation generated, attestation of snap would not be nil forever basically")
|
log.Debug("once one attestation generated, attestation of snap would not be nil forever basically")
|
||||||
}
|
}
|
||||||
return 0, chain.GetHeaderByNumber(0).Hash(), nil
|
return 0, chain.GetHeaderByNumber(0).Hash(), nil
|
||||||
|
@ -637,7 +637,7 @@ func (bc *BlockChain) empty() bool {
|
|||||||
// GetJustifiedNumber returns the highest justified blockNumber on the branch including and before `header`.
|
// GetJustifiedNumber returns the highest justified blockNumber on the branch including and before `header`.
|
||||||
func (bc *BlockChain) GetJustifiedNumber(header *types.Header) uint64 {
|
func (bc *BlockChain) GetJustifiedNumber(header *types.Header) uint64 {
|
||||||
if p, ok := bc.engine.(consensus.PoSA); ok {
|
if p, ok := bc.engine.(consensus.PoSA); ok {
|
||||||
justifiedBlockNumber, _, err := p.GetJustifiedNumberAndHash(bc, header)
|
justifiedBlockNumber, _, err := p.GetJustifiedNumberAndHash(bc, []*types.Header{header})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return justifiedBlockNumber
|
return justifiedBlockNumber
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ func (bc *BlockChain) CurrentSafeBlock() *types.Header {
|
|||||||
if currentHeader == nil {
|
if currentHeader == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
_, justifiedBlockHash, err := p.GetJustifiedNumberAndHash(bc, currentHeader)
|
_, justifiedBlockHash, err := p.GetJustifiedNumberAndHash(bc, []*types.Header{currentHeader})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return bc.GetHeaderByHash(justifiedBlockHash)
|
return bc.GetHeaderByHash(justifiedBlockHash)
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine c
|
|||||||
// GetJustifiedNumber returns the highest justified blockNumber on the branch including and before `header`.
|
// GetJustifiedNumber returns the highest justified blockNumber on the branch including and before `header`.
|
||||||
func (hc *HeaderChain) GetJustifiedNumber(header *types.Header) uint64 {
|
func (hc *HeaderChain) GetJustifiedNumber(header *types.Header) uint64 {
|
||||||
if p, ok := hc.engine.(consensus.PoSA); ok {
|
if p, ok := hc.engine.(consensus.PoSA); ok {
|
||||||
justifiedBlockNumber, _, err := p.GetJustifiedNumberAndHash(hc, header)
|
justifiedBlockNumber, _, err := p.GetJustifiedNumberAndHash(hc, []*types.Header{header})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return justifiedBlockNumber
|
return justifiedBlockNumber
|
||||||
}
|
}
|
||||||
|
@ -218,7 +218,7 @@ func (voteManager *VoteManager) loop() {
|
|||||||
// A validator must not vote within the span of its other votes . (Rule 2)
|
// A validator must not vote within the span of its other votes . (Rule 2)
|
||||||
// Validators always vote for their canonical chain’s latest block. (Rule 3)
|
// Validators always vote for their canonical chain’s latest block. (Rule 3)
|
||||||
func (voteManager *VoteManager) UnderRules(header *types.Header) (bool, uint64, common.Hash) {
|
func (voteManager *VoteManager) UnderRules(header *types.Header) (bool, uint64, common.Hash) {
|
||||||
sourceNumber, sourceHash, err := voteManager.engine.GetJustifiedNumberAndHash(voteManager.chain, header)
|
sourceNumber, sourceHash, err := voteManager.engine.GetJustifiedNumberAndHash(voteManager.chain, []*types.Header{header})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to get the highest justified number and hash at cur header", "curHeader's BlockNumber", header.Number, "curHeader's BlockHash", header.Hash())
|
log.Error("failed to get the highest justified number and hash at cur header", "curHeader's BlockNumber", header.Number, "curHeader's BlockHash", header.Hash())
|
||||||
return false, 0, common.Hash{}
|
return false, 0, common.Hash{}
|
||||||
|
@ -78,15 +78,15 @@ func newTestBackend() *testBackend {
|
|||||||
func (b *testBackend) IsMining() bool { return true }
|
func (b *testBackend) IsMining() bool { return true }
|
||||||
func (b *testBackend) EventMux() *event.TypeMux { return b.eventMux }
|
func (b *testBackend) EventMux() *event.TypeMux { return b.eventMux }
|
||||||
|
|
||||||
func (p *mockPOSA) GetJustifiedNumberAndHash(chain consensus.ChainHeaderReader, header *types.Header) (uint64, common.Hash, error) {
|
func (p *mockPOSA) GetJustifiedNumberAndHash(chain consensus.ChainHeaderReader, headers []*types.Header) (uint64, common.Hash, error) {
|
||||||
parentHeader := chain.GetHeaderByHash(header.ParentHash)
|
parentHeader := chain.GetHeaderByHash(headers[len(headers)-1].ParentHash)
|
||||||
if parentHeader == nil {
|
if parentHeader == nil {
|
||||||
return 0, common.Hash{}, fmt.Errorf("unexpected error")
|
return 0, common.Hash{}, fmt.Errorf("unexpected error")
|
||||||
}
|
}
|
||||||
return parentHeader.Number.Uint64(), parentHeader.Hash(), nil
|
return parentHeader.Number.Uint64(), parentHeader.Hash(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *mockInvalidPOSA) GetJustifiedNumberAndHash(chain consensus.ChainHeaderReader, header *types.Header) (uint64, common.Hash, error) {
|
func (p *mockInvalidPOSA) GetJustifiedNumberAndHash(chain consensus.ChainHeaderReader, headers []*types.Header) (uint64, common.Hash, error) {
|
||||||
return 0, common.Hash{}, fmt.Errorf("not supported")
|
return 0, common.Hash{}, fmt.Errorf("not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,7 +436,7 @@ func (lc *LightChain) CurrentHeader() *types.Header {
|
|||||||
// GetJustifiedNumber returns the highest justified blockNumber on the branch including and before `header`
|
// GetJustifiedNumber returns the highest justified blockNumber on the branch including and before `header`
|
||||||
func (lc *LightChain) GetJustifiedNumber(header *types.Header) uint64 {
|
func (lc *LightChain) GetJustifiedNumber(header *types.Header) uint64 {
|
||||||
if p, ok := lc.engine.(consensus.PoSA); ok {
|
if p, ok := lc.engine.(consensus.PoSA); ok {
|
||||||
justifiedBlockNumber, _, err := p.GetJustifiedNumberAndHash(lc.hc, header)
|
justifiedBlockNumber, _, err := p.GetJustifiedNumberAndHash(lc.hc, []*types.Header{header})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return justifiedBlockNumber
|
return justifiedBlockNumber
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user