diff --git a/lib/grandpa/grandpa.go b/lib/grandpa/grandpa.go index 058ce2117b..23e7dd5876 100644 --- a/lib/grandpa/grandpa.go +++ b/lib/grandpa/grandpa.go @@ -753,53 +753,6 @@ func (s *Service) determinePreCommit() (*Vote, error) { return &pvb, nil } -// isFinalisable returns true if the round is finalisable, false otherwise. -func (s *Service) isFinalisable(round uint64) (bool, error) { - var pvb Vote - var err error - - if round == 0 { - return true, nil - } - - s.mapLock.Lock() - v, has := s.preVotedBlock[round] - s.mapLock.Unlock() - - if !has { - return false, ErrNoPreVotedBlock - } - pvb = *v - - bfc, err := s.getBestFinalCandidate() - if err != nil { - return false, err - } - - if bfc == nil { - return false, errors.New("cannot find best final candidate for round") - } - - pc, err := s.getTotalVotesForBlock(bfc.Hash, precommit) - if err != nil { - return false, err - } - - s.mapLock.Lock() - prevBfc := s.bestFinalCandidate[s.state.round-1] - s.mapLock.Unlock() - - if prevBfc == nil { - return false, errors.New("cannot find best final candidate for previous round") - } - - if bfc.Number <= pvb.Number && (s.state.round == 0 || prevBfc.Number <= bfc.Number) && pc > s.state.threshold() { - return true, nil - } - - return false, nil -} - // finalise finalises the round by setting the best final candidate for this round func (s *Service) finalise() error { // get best final candidate @@ -983,52 +936,6 @@ func (s *Service) getBestFinalCandidate() (*Vote, error) { return bfc, nil } -// isCompletable returns true if the round is completable, false otherwise -func (s *Service) isCompletable() (bool, error) { - // haven't received enough votes, not completable - if uint64(s.lenVotes(precommit)+len(s.pcEquivocations)) <= s.state.threshold() { - return false, nil - } - - prevoted, err := s.getPreVotedBlock() - if err != nil { - return false, err - } - - votes := s.getVotes(precommit) - - // for each block with at least 1 vote that's a descendant of the prevoted block, - // check that (total precommits - total pc equivocations - precommits for that block) >2/3|V| - // ie. there must not be a descendent of the prevotes block that is preferred - for _, v := range votes { - if prevoted.Hash == v.Hash { - continue - } - - // check if the current block is a descendant of prevoted block - isDescendant, err := s.blockState.IsDescendantOf(prevoted.Hash, v.Hash) - if err != nil { - return false, err - } - - if !isDescendant { - continue - } - - c, err := s.getTotalVotesForBlock(v.Hash, precommit) - if err != nil { - return false, err - } - - if uint64(len(votes)-len(s.pcEquivocations))-c <= s.state.threshold() { - // round isn't completable - return false, nil - } - } - - return true, nil -} - // getPreVotedBlock returns the current pre-voted block B. also known as GRANDPA-GHOST. // the pre-voted block is the block with the highest block number in the set of all the blocks with // total votes >2/3 the total number of voters, where the total votes is determined by getTotalVotesForBlock. diff --git a/lib/grandpa/grandpa_test.go b/lib/grandpa/grandpa_test.go index 6905755406..d7cc15ec71 100644 --- a/lib/grandpa/grandpa_test.go +++ b/lib/grandpa/grandpa_test.go @@ -781,43 +781,6 @@ func TestGetPreVotedBlock_EvenMoreCandidates(t *testing.T) { require.Equal(t, uint32(4), block.Number) } -func TestIsCompletable(t *testing.T) { - gs, st := newTestService(t) - - branches := map[uint]int{6: 1} - state.AddBlocksToStateWithFixedBranches(t, st.Block, 8, branches) - leaves := gs.blockState.Leaves() - - voteA, err := NewVoteFromHash(leaves[0], st.Block) - require.NoError(t, err) - voteB, err := NewVoteFromHash(leaves[1], st.Block) - require.NoError(t, err) - - for i, k := range kr.Keys { - voter := k.Public().(*ed25519.PublicKey).AsBytes() - - if i < 6 { - gs.prevotes.Store(voter, &SignedVote{ - Vote: *voteA, - }) - gs.precommits.Store(voter, &SignedVote{ - Vote: *voteA, - }) - } else { - gs.prevotes.Store(voter, &SignedVote{ - Vote: *voteB, - }) - gs.precommits.Store(voter, &SignedVote{ - Vote: *voteB, - }) - } - } - - completable, err := gs.isCompletable() - require.NoError(t, err) - require.True(t, completable) -} - func TestFindParentWithNumber(t *testing.T) { gs, st := newTestService(t) @@ -1050,88 +1013,6 @@ func TestDeterminePreVote_WithInvalidPrimaryPreVote(t *testing.T) { require.Equal(t, gs.head.Hash(), pv.Hash) } -func TestIsFinalisable_True(t *testing.T) { - gs, st := newTestService(t) - - branches := map[uint]int{6: 1} - state.AddBlocksToStateWithFixedBranches(t, st.Block, 8, branches) - leaves := gs.blockState.Leaves() - - voteA, err := NewVoteFromHash(leaves[0], st.Block) - require.NoError(t, err) - voteB, err := NewVoteFromHash(leaves[1], st.Block) - require.NoError(t, err) - - for i, k := range kr.Keys { - voter := k.Public().(*ed25519.PublicKey).AsBytes() - - if i < 6 { - gs.prevotes.Store(voter, &SignedVote{ - Vote: *voteA, - }) - gs.precommits.Store(voter, &SignedVote{ - Vote: *voteA, - }) - } else { - gs.prevotes.Store(voter, &SignedVote{ - Vote: *voteB, - }) - gs.precommits.Store(voter, &SignedVote{ - Vote: *voteB, - }) - } - } - - finalisable, err := gs.isFinalisable(gs.state.round) - require.NoError(t, err) - require.True(t, finalisable) -} - -func TestIsFinalisable_False(t *testing.T) { - gs, st := newTestService(t) - - branches := map[uint]int{2: 1} - branches[2] = 1 - state.AddBlocksToStateWithFixedBranches(t, st.Block, 3, branches) - leaves := gs.blockState.Leaves() - - voteA, err := NewVoteFromHash(leaves[0], st.Block) - require.NoError(t, err) - voteB, err := NewVoteFromHash(leaves[1], st.Block) - require.NoError(t, err) - - for i, k := range kr.Keys { - voter := k.Public().(*ed25519.PublicKey).AsBytes() - - if i < 6 { - gs.prevotes.Store(voter, &SignedVote{ - Vote: *voteA, - }) - gs.precommits.Store(voter, &SignedVote{ - Vote: *voteA, - }) - } else { - gs.prevotes.Store(voter, &SignedVote{ - Vote: *voteB, - }) - gs.precommits.Store(voter, &SignedVote{ - Vote: *voteB, - }) - } - } - - // previous round has finalised block # higher than current, so round is not finalisable - gs.state.round = 1 - gs.bestFinalCandidate[0] = &Vote{ - Number: 4, - } - gs.preVotedBlock[gs.state.round] = voteA - - finalisable, err := gs.isFinalisable(gs.state.round) - require.NoError(t, err) - require.False(t, finalisable) -} - func TestGetGrandpaGHOST_CommonAncestor(t *testing.T) { gs, st := newTestService(t)