diff --git a/client/core/types/vote.go b/client/core/types/vote.go index 01c07a60f..32d2c7577 100644 --- a/client/core/types/vote.go +++ b/client/core/types/vote.go @@ -223,7 +223,6 @@ func (vote *Vote) String() string { type Votes []*Vote var ( - errDuplicate = errors.New("already voted") errNonNilDuplicate = errors.New("duplicate NON-NIL vote") errNilDuplicate = errors.New("duplicate NIL vote") ) @@ -251,14 +250,16 @@ func (v *VotesSet) Add(vote AddressVote) { defer v.l.Unlock() voteData := vote.Vote() + voteAddress := vote.Address() - if _, ok := v.isVoted[vote.Address()]; ok { - log.Warn("already voted", "address", vote.Address(), "vote", vote.Vote().String()) + if _, ok := v.isVoted[voteAddress]; ok { + log.Debug("already voted", "address", voteAddress, "vote", vote.Vote().String()) return - } else { - v.isVoted[vote.Address()] = struct{}{} } + log.Debug("vote was successfully added", "address", voteAddress, "vote", vote.Vote().String()) + v.isVoted[voteAddress] = struct{}{} + if bytes.Equal(voteData.data.BlockHash.Bytes(), common.Hash{}.Bytes()) { v.nilVotes[voteData.Hash()] = voteData } else { @@ -279,7 +280,7 @@ func (v *VotesSet) Contains(vote AddressVote) error { defer v.l.RUnlock() if _, ok := v.isVoted[vote.Address()]; ok { - return errDuplicate + return fmt.Errorf("already voted address %q", vote.Address().Hash().String()) } h := vote.Vote().Hash() @@ -289,11 +290,9 @@ func (v *VotesSet) Contains(vote AddressVote) error { return errNonNilDuplicate } - if !res { - _, res = v.nilVotes[h] - if res { - return errNilDuplicate - } + _, res = v.nilVotes[h] + if res { + return errNilDuplicate } return nil diff --git a/client/core/voting_table.go b/client/core/voting_table.go index 949852ea6..2b64a5cd0 100644 --- a/client/core/voting_table.go +++ b/client/core/voting_table.go @@ -58,8 +58,12 @@ func (table *votingTable) isDuplicate(voteAddressed types.AddressVote) error { err := table.votes.Contains(voteAddressed) if err != nil { vote := voteAddressed.Vote() - log.Debug(fmt.Sprintf("a duplicate vote in voting table %v; blockHash %v; voteHash %v; from validator %v. Error: %s", - table.voteType, vote.BlockHash().String(), vote.Hash().String(), voteAddressed.Address().String(), vote.String())) + log.Debug("a duplicate vote", + "table", table.voteType, + "blockHash", vote.BlockHash().String(), + "voteHash", vote.Hash().String(), + "validator", voteAddressed.Address().Hash().String(), + "err", vote.String()) return err } return nil diff --git a/client/knode/handler.go b/client/knode/handler.go index aba8520d4..12f62adaa 100644 --- a/client/knode/handler.go +++ b/client/knode/handler.go @@ -632,8 +632,6 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { return errResp(ErrDecode, "msg %v: %v", msg, err) } - p.MarkProposal(proposal.Hash()) - log.Info("got a proposal block", "chainID", proposal.ChainID().Int64(), "number", proposal.BlockNumber().Int64(), "round", proposal.Round(), "hash", proposal.Hash().String()) @@ -645,6 +643,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { log.Info("a proposal block added successfully", "chainID", proposal.ChainID().Int64(), "number", proposal.BlockNumber().Int64(), "round", proposal.Round(), "hash", proposal.Hash().String()) + p.MarkProposal(proposal.Hash()) + case msg.Code == VoteMsg: if !pm.validator.Validating() { break @@ -655,12 +655,11 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { return errResp(ErrDecode, "msg %v: %v", msg, err) } - p.MarkVote(vote.Hash()) - if err := pm.validator.AddVote(&vote); err != nil { // ignore break } + p.MarkVote(vote.Hash()) case msg.Code == BlockFragmentMsg: if !pm.validator.Validating() { @@ -673,13 +672,13 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { return errResp(ErrDecode, "msg %v: %v", msg, err) } - p.MarkBlockFragment(request.Data.Proof) if err := pm.validator.AddBlockFragment(request.BlockNumber, request.Hash, request.Round, request.Data); err != nil { log.Debug("error while adding a new block fragment", "err", err, "requestRound", request.Round, "requestBlock", request.BlockNumber, "requestFragment", request.Data) // ignore break } + p.MarkBlockFragment(request.Data.Proof) default: return errResp(ErrInvalidMsgCode, "%v", msg.Code) diff --git a/client/knode/validator/validator.go b/client/knode/validator/validator.go index 57d7c5d9d..9a5f59540 100644 --- a/client/knode/validator/validator.go +++ b/client/knode/validator/validator.go @@ -687,12 +687,14 @@ func (val *validator) preCommit() { val.lockedRound = 0 val.lockedBlock = nil } + case val.lockedBlock != nil && currentLeader == val.lockedBlock.Hash(): log.Debug("Majority of validators pre-voted the locked block", "block", val.lockedBlock.Hash()) // update locked block round val.lockedRound = val.round // vote on the pre-vote election winner vote = currentLeader + case val.block != nil && currentLeader == val.block.Hash(): log.Debug("Majority of validators pre-voted the proposed block", "block", val.block.Hash()) // lock block @@ -701,17 +703,19 @@ func (val *validator) preCommit() { // vote on the pre-vote election winner vote = currentLeader // we don't have the current block (fetch) + default: // fetch block, unlock, precommit // unlock locked block if val.lockedBlock != nil { - log.Warn("preCommit default case. lockedBlock", + log.Warn("lockedBlock.preCommit default case", "equal", val.lockedBlock.Hash() == currentLeader, "currentLeader", currentLeader, "lockedHash", val.lockedBlock.Hash()) } + if val.block != nil { - log.Warn("preCommit default case. block", + log.Warn("block.preCommit default case.", "equal", val.block.Hash() == currentLeader, "currentLeader", currentLeader, "block", val.block.Hash()) @@ -736,6 +740,10 @@ func (val *validator) vote(vote *types.Vote) { log.Crit("Failed to make address Vote", "err", err) } + if val.walletAccount.Account().Address != addressVote.Address() { + panic("!!!!!!!!!!!!!!!!!!!!!!!!") + } + err = val.votingSystem.Add(addressVote) if err != nil { log.Debug("Failed to add own vote to voting table", @@ -752,6 +760,10 @@ func (val *validator) AddBlockFragment(blockNumber *big.Int, blockHash common.Ha return fmt.Errorf("expected block fragments for %d, got %d", val.blockNumber.Int64(), blockNumber.Int64()) } + if val.round != round { + return fmt.Errorf("expected block fragments for round %d, got %d", val.round, round) + } + err, canAssemble := val.addFragment(fragment, blockHash) if err != nil { return err @@ -812,6 +824,7 @@ func (val *validator) addFragment(fragment *types.BlockFragment, blockHash commo func (val *validator) assembleBlock(round uint64, blockNumber *big.Int, blockHash common.Hash) error { val.blockFragmentsLock.Lock() defer val.blockFragmentsLock.Unlock() + blockFragments := val.blockFragments[blockHash] block, err := blockFragments.Assemble() diff --git a/e2e/features/validator.feature b/e2e/features/validator.feature index d395fb122..bf00858ac 100644 --- a/e2e/features/validator.feature +++ b/e2e/features/validator.feature @@ -41,11 +41,11 @@ Feature: Joining network as a validator And I start validator with 5 mTokens deposit And the token balance of A should be 10 mTokens - Scenario: Re-Start mining on miner crush - Given: I wait for my node to be synced - When I start validator with 5 mTokens deposit - And I wait for my node to be synced - And crash my node validator - And I restart the validator - And I wait for my node to be synced - Then My node should be a validator +# Scenario: Re-Start mining on miner crush +# Given: I wait for my node to be synced +# When I start validator with 5 mTokens deposit +# And I wait for my node to be synced +# And crash my node validator +# And I restart the validator +# And I wait for my node to be synced +# Then My node should be a validator