mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 21:31:37 +00:00
update adaptor for verify headers and fix vote handler to include +1 distance when checking rounds (#48)
This commit is contained in:
parent
328d555b9b
commit
7cc2bef2d3
6 changed files with 60 additions and 15 deletions
|
|
@ -149,8 +149,30 @@ func (x *XDPoS) VerifyHeader(chain consensus.ChainReader, header *types.Header,
|
|||
// method returns a quit channel to abort the operations and a results channel to
|
||||
// retrieve the async verifications (the order is that of the input slice).
|
||||
func (x *XDPoS) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, fullVerifies []bool) (chan<- struct{}, <-chan error) {
|
||||
// TODO: (Hashlab) This funciton is a special case
|
||||
return x.EngineV1.VerifyHeaders(chain, headers, fullVerifies)
|
||||
abort := make(chan struct{})
|
||||
results := make(chan error, len(headers))
|
||||
|
||||
// Split the headers list into v1 and v2 buckets
|
||||
var v1headers []*types.Header
|
||||
var v2headers []*types.Header
|
||||
|
||||
for _, header := range headers {
|
||||
switch x.config.BlockConsensusVersion(header.Number) {
|
||||
case params.ConsensusEngineVersion2:
|
||||
v2headers = append(v2headers, header)
|
||||
default: // Default "v1"
|
||||
v1headers = append(v1headers, header)
|
||||
}
|
||||
}
|
||||
|
||||
if v1headers != nil {
|
||||
x.EngineV1.VerifyHeaders(chain, headers, fullVerifies, abort, results)
|
||||
}
|
||||
if v2headers != nil {
|
||||
x.EngineV2.VerifyHeaders(chain, headers, fullVerifies, abort, results)
|
||||
}
|
||||
|
||||
return abort, results
|
||||
}
|
||||
|
||||
// VerifyUncles implements consensus.Engine, always returning an error for any
|
||||
|
|
|
|||
|
|
@ -116,10 +116,7 @@ func (x *XDPoS_v1) VerifyHeader(chain consensus.ChainReader, header *types.Heade
|
|||
// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The
|
||||
// method returns a quit channel to abort the operations and a results channel to
|
||||
// retrieve the async verifications (the order is that of the input slice).
|
||||
func (x *XDPoS_v1) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, fullVerifies []bool) (chan<- struct{}, <-chan error) {
|
||||
abort := make(chan struct{})
|
||||
results := make(chan error, len(headers))
|
||||
|
||||
func (x *XDPoS_v1) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, fullVerifies []bool, abort <-chan struct{}, results chan<- error) {
|
||||
go func() {
|
||||
for i, header := range headers {
|
||||
err := x.verifyHeaderWithCache(chain, header, headers[:i], fullVerifies[i])
|
||||
|
|
@ -131,7 +128,6 @@ func (x *XDPoS_v1) VerifyHeaders(chain consensus.ChainReader, headers []*types.H
|
|||
}
|
||||
}
|
||||
}()
|
||||
return abort, results
|
||||
}
|
||||
|
||||
func (x *XDPoS_v1) verifyHeaderWithCache(chain consensus.ChainReader, header *types.Header, parents []*types.Header, fullVerify bool) error {
|
||||
|
|
|
|||
|
|
@ -478,6 +478,19 @@ func (x *XDPoS_v2) VerifyHeader(chain consensus.ChainReader, header *types.Heade
|
|||
return nil
|
||||
}
|
||||
|
||||
// TODO: Yet to be implemented XIN-135
|
||||
func (x *XDPoS_v2) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, fullVerifies []bool, abort <-chan struct{}, results chan<- error) {
|
||||
go func() {
|
||||
for range headers {
|
||||
select {
|
||||
case <-abort:
|
||||
return
|
||||
case results <- nil:
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Utils for test to get current Pool size
|
||||
func (x *XDPoS_v2) GetVotePoolSize(vote *utils.Vote) int {
|
||||
return x.votePool.Size(vote)
|
||||
|
|
@ -556,8 +569,8 @@ func (x *XDPoS_v2) VoteHandler(chain consensus.ChainReader, voteMsg *utils.Vote)
|
|||
func (x *XDPoS_v2) voteHandler(chain consensus.ChainReader, voteMsg *utils.Vote) error {
|
||||
|
||||
// 1. checkRoundNumber
|
||||
if voteMsg.ProposedBlockInfo.Round != x.currentRound {
|
||||
return &utils.ErrIncomingMessageRoundNotEqualCurrentRound{
|
||||
if (voteMsg.ProposedBlockInfo.Round != x.currentRound) && (voteMsg.ProposedBlockInfo.Round != x.currentRound+1) {
|
||||
return &utils.ErrIncomingMessageRoundTooFarFromCurrentRound{
|
||||
Type: "vote",
|
||||
IncomingRound: voteMsg.ProposedBlockInfo.Round,
|
||||
CurrentRound: x.currentRound,
|
||||
|
|
|
|||
|
|
@ -88,3 +88,13 @@ type ErrIncomingMessageRoundNotEqualCurrentRound struct {
|
|||
func (e *ErrIncomingMessageRoundNotEqualCurrentRound) Error() string {
|
||||
return fmt.Sprintf("%s message round number: %v does not match currentRound: %v", e.Type, e.IncomingRound, e.CurrentRound)
|
||||
}
|
||||
|
||||
type ErrIncomingMessageRoundTooFarFromCurrentRound struct {
|
||||
Type string
|
||||
IncomingRound Round
|
||||
CurrentRound Round
|
||||
}
|
||||
|
||||
func (e *ErrIncomingMessageRoundTooFarFromCurrentRound) Error() string {
|
||||
return fmt.Sprintf("%s message round number: %v is too far away from currentRound: %v", e.Type, e.IncomingRound, e.CurrentRound)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
|
|||
assert.Equal(t, big.NewInt(13), highestCommitBlock.Number)
|
||||
}
|
||||
|
||||
func TestThrowErrorIfVoteMsgRoundNotEqualToCurrentRound(t *testing.T) {
|
||||
func TestThrowErrorIfVoteMsgRoundIsMoreThanOneRoundAwayFromCurrentRound(t *testing.T) {
|
||||
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 15, params.TestXDPoSMockChainConfigWithV2Engine, 0)
|
||||
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
|
||||
|
||||
|
|
@ -146,14 +146,18 @@ func TestThrowErrorIfVoteMsgRoundNotEqualToCurrentRound(t *testing.T) {
|
|||
// voteRound > currentRound
|
||||
err := engineV2.VoteHandler(blockchain, voteMsg)
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, "vote message round number: 6 does not match currentRound: 7", err.Error())
|
||||
assert.Equal(t, "vote message round number: 6 is too far away from currentRound: 7", err.Error())
|
||||
|
||||
// Set round to 5
|
||||
// Set round to 5, it's 1 round away, should not trigger failure
|
||||
engineV2.SetNewRoundFaker(utils.Round(5), false)
|
||||
err = engineV2.VoteHandler(blockchain, voteMsg)
|
||||
assert.Nil(t, err)
|
||||
|
||||
engineV2.SetNewRoundFaker(utils.Round(4), false)
|
||||
err = engineV2.VoteHandler(blockchain, voteMsg)
|
||||
assert.NotNil(t, err)
|
||||
// voteRound < currentRound
|
||||
assert.Equal(t, "vote message round number: 6 does not match currentRound: 5", err.Error())
|
||||
assert.Equal(t, "vote message round number: 6 is too far away from currentRound: 4", err.Error())
|
||||
|
||||
}
|
||||
|
||||
func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ func (b *Bfter) Vote(vote *utils.Vote) error {
|
|||
|
||||
err = b.consensus.voteHandler(b.blockChainReader, vote)
|
||||
if err != nil {
|
||||
if _, ok := err.(*utils.ErrIncomingMessageRoundNotEqualCurrentRound); ok {
|
||||
if _, ok := err.(*utils.ErrIncomingMessageRoundTooFarFromCurrentRound); ok {
|
||||
log.Warn("vote round not equal", "error", err, "vote", vote.Hash())
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue