Commit 69e7b23f authored by caopingcp's avatar caopingcp

improve tendermint stability

parent 8f8ae28f
...@@ -312,6 +312,10 @@ func (cs *ConsensusState) updateToState(state State) { ...@@ -312,6 +312,10 @@ func (cs *ConsensusState) updateToState(state State) {
tendermintlog.Info("Ignoring updateToState()", "newHeight", state.LastBlockHeight+1, "oldHeight", cs.state.LastBlockHeight+1) tendermintlog.Info("Ignoring updateToState()", "newHeight", state.LastBlockHeight+1, "oldHeight", cs.state.LastBlockHeight+1)
return return
} }
// disable gossip votes
if useAggSig && gossipVotes.Load().(bool) {
gossipVotes.Store(false)
}
// Reset fields based on state. // Reset fields based on state.
validators := state.Validators validators := state.Validators
...@@ -361,7 +365,7 @@ func (cs *ConsensusState) updateToState(state State) { ...@@ -361,7 +365,7 @@ func (cs *ConsensusState) updateToState(state State) {
func (cs *ConsensusState) newStep() { func (cs *ConsensusState) newStep() {
if cs.broadcastChannel != nil { if cs.broadcastChannel != nil {
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.NewRoundStepID, Msg: cs.RoundStateMessage(), PeerID: cs.ourID, PeerIP: ""} cs.broadcastChannel <- MsgInfo{TypeID: ttypes.NewRoundStepID, Msg: cs.RoundStateMessage(), PeerID: "", PeerIP: ""}
} }
cs.nSteps++ cs.nSteps++
} }
...@@ -489,6 +493,10 @@ func (cs *ConsensusState) handleTimeout(ti timeoutInfo, rs ttypes.RoundState) { ...@@ -489,6 +493,10 @@ func (cs *ConsensusState) handleTimeout(ti timeoutInfo, rs ttypes.RoundState) {
case ttypes.RoundStepPrecommitWait: case ttypes.RoundStepPrecommitWait:
cs.enterPrecommit(ti.Height, ti.Round) cs.enterPrecommit(ti.Height, ti.Round)
cs.enterNewRound(ti.Height, ti.Round+1) cs.enterNewRound(ti.Height, ti.Round+1)
case ttypes.RoundStepAggPrevoteWait:
cs.enterAggPrevoteWait(ti.Height, ti.Round)
case ttypes.RoundStepAggPrecommitWait:
cs.enterAggPrecommitWait(ti.Height, ti.Round)
default: default:
panic(fmt.Sprintf("Invalid timeout step: %v", ti.Step)) panic(fmt.Sprintf("Invalid timeout step: %v", ti.Step))
} }
...@@ -505,10 +513,6 @@ func (cs *ConsensusState) checkTxsAvailable() { ...@@ -505,10 +513,6 @@ func (cs *ConsensusState) checkTxsAvailable() {
tendermintlog.Info(fmt.Sprintf("blockchain(H: %v) and consensus(H: %v) are not sync", height, rs.Height)) tendermintlog.Info(fmt.Sprintf("blockchain(H: %v) and consensus(H: %v) are not sync", height, rs.Height))
break break
} }
if cs.checkProposalComplete() {
tendermintlog.Debug("already has proposal")
break
}
cs.txsAvailable <- height cs.txsAvailable <- height
case <-cs.client.StopC(): case <-cs.client.StopC():
tendermintlog.Info("checkTxsAvailable quit") tendermintlog.Info("checkTxsAvailable quit")
...@@ -529,7 +533,18 @@ func (cs *ConsensusState) handleTxsAvailable(height int64) { ...@@ -529,7 +533,18 @@ func (cs *ConsensusState) handleTxsAvailable(height int64) {
defer cs.mtx.Unlock() defer cs.mtx.Unlock()
// we only need to do this for round 0 // we only need to do this for round 0
cs.enterPropose(height, 0) if cs.Round != 0 {
return
}
switch cs.Step {
case ttypes.RoundStepNewHeight: // timeoutCommit phase
// +1ms to ensure RoundStepNewRound timeout always happens after RoundStepNewHeight
timeoutCommit := cs.StartTime.Sub(time.Now()) + 1*time.Millisecond
cs.scheduleTimeout(timeoutCommit, height, 0, ttypes.RoundStepNewRound)
case ttypes.RoundStepNewRound: // after timeoutCommit
cs.enterPropose(height, 0)
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -554,6 +569,10 @@ func (cs *ConsensusState) enterNewRound(height int64, round int) { ...@@ -554,6 +569,10 @@ func (cs *ConsensusState) enterNewRound(height int64, round int) {
tendermintlog.Info(fmt.Sprintf("enterNewRound(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) tendermintlog.Info(fmt.Sprintf("enterNewRound(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step))
// disable gossip votes
if useAggSig && gossipVotes.Load().(bool) {
gossipVotes.Store(false)
}
// Increment validators if necessary // Increment validators if necessary
validators := cs.Validators validators := cs.Validators
if cs.Round < round { if cs.Round < round {
...@@ -580,7 +599,7 @@ func (cs *ConsensusState) enterNewRound(height int64, round int) { ...@@ -580,7 +599,7 @@ func (cs *ConsensusState) enterNewRound(height int64, round int) {
cs.Votes.SetRound(round + 1) // also track next round (round+1) to allow round-skipping cs.Votes.SetRound(round + 1) // also track next round (round+1) to allow round-skipping
//cs.eventBus.PublishEventNewRound(cs.RoundStateEvent()) //cs.eventBus.PublishEventNewRound(cs.RoundStateEvent())
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.NewRoundStepID, Msg: cs.RoundStateMessage(), PeerID: cs.ourID, PeerIP: ""} cs.broadcastChannel <- MsgInfo{TypeID: ttypes.NewRoundStepID, Msg: cs.RoundStateMessage(), PeerID: "", PeerIP: ""}
// Wait for txs to be available in the mempool // Wait for txs to be available in the mempool
// before we enterPropose in round 0. // before we enterPropose in round 0.
...@@ -619,8 +638,8 @@ func (cs *ConsensusState) proposalHeartbeat(height int64, round int) { ...@@ -619,8 +638,8 @@ func (cs *ConsensusState) proposalHeartbeat(height int64, round int) {
tendermintlog.Error("SignHeartbeat failed", "err", err) tendermintlog.Error("SignHeartbeat failed", "err", err)
continue continue
} }
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.ProposalHeartbeatID, Msg: heartbeat, PeerID: cs.ourID, PeerIP: ""} cs.broadcastChannel <- MsgInfo{TypeID: ttypes.ProposalHeartbeatID, Msg: heartbeat, PeerID: "", PeerIP: ""}
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.NewRoundStepID, Msg: rs.RoundStateMessage(), PeerID: cs.ourID, PeerIP: ""} cs.broadcastChannel <- MsgInfo{TypeID: ttypes.NewRoundStepID, Msg: rs.RoundStateMessage(), PeerID: "", PeerIP: ""}
counter++ counter++
time.Sleep(proposalHeartbeatIntervalSeconds * time.Second) time.Sleep(proposalHeartbeatIntervalSeconds * time.Second)
} }
...@@ -842,11 +861,6 @@ func (cs *ConsensusState) enterPrevote(height int64, round int) { ...@@ -842,11 +861,6 @@ func (cs *ConsensusState) enterPrevote(height int64, round int) {
cs.newStep() cs.newStep()
}() }()
if useAggSig {
// Wait for some more prevotes; enterPrecommit
cs.scheduleTimeout(cs.Prevote(round)*2, height, round, ttypes.RoundStepPrevoteWait)
}
tendermintlog.Info(fmt.Sprintf("enterPrevote(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step), "cost", types.Since(cs.begCons)) tendermintlog.Info(fmt.Sprintf("enterPrevote(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step), "cost", types.Since(cs.begCons))
// Sign and broadcast vote as necessary // Sign and broadcast vote as necessary
...@@ -904,6 +918,18 @@ func (cs *ConsensusState) defaultDoPrevote(height int64, round int) { ...@@ -904,6 +918,18 @@ func (cs *ConsensusState) defaultDoPrevote(height int64, round int) {
cs.signAddVote(ttypes.VoteTypePrevote, cs.ProposalBlock.Hash()) cs.signAddVote(ttypes.VoteTypePrevote, cs.ProposalBlock.Hash())
} }
// Enter: send prevote for aggregate at next round.
func (cs *ConsensusState) enterAggPrevoteWait(height int64, round int) {
if cs.Height != height || round < cs.Round || (cs.Round == round && ttypes.RoundStepAggPrevoteWait <= cs.Step) {
tendermintlog.Debug(fmt.Sprintf("enterAggPrevoteWait(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step))
return
}
tendermintlog.Info(fmt.Sprintf("enterAggPrevoteWait(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step))
// enable gossip votes when timeout waiting for aggregate prevote
gossipVotes.Store(true)
}
// Enter: any +2/3 prevotes at next round. // Enter: any +2/3 prevotes at next round.
func (cs *ConsensusState) enterPrevoteWait(height int64, round int) { func (cs *ConsensusState) enterPrevoteWait(height int64, round int) {
if cs.Height != height || round < cs.Round || (cs.Round == round && ttypes.RoundStepPrevoteWait <= cs.Step) { if cs.Height != height || round < cs.Round || (cs.Round == round && ttypes.RoundStepPrevoteWait <= cs.Step) {
...@@ -921,6 +947,11 @@ func (cs *ConsensusState) enterPrevoteWait(height int64, round int) { ...@@ -921,6 +947,11 @@ func (cs *ConsensusState) enterPrevoteWait(height int64, round int) {
cs.newStep() cs.newStep()
}() }()
// enable gossip votes in case other validators enterAggPrevoteWait
if useAggSig && !cs.isProposer() && cs.Votes.Prevotes(round).GetAggVote() == nil {
gossipVotes.Store(true)
}
// Wait for some more prevotes; enterPrecommit // Wait for some more prevotes; enterPrecommit
cs.scheduleTimeout(cs.Prevote(round), height, round, ttypes.RoundStepPrevoteWait) cs.scheduleTimeout(cs.Prevote(round), height, round, ttypes.RoundStepPrevoteWait)
} }
...@@ -945,11 +976,6 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) { ...@@ -945,11 +976,6 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) {
cs.newStep() cs.newStep()
}() }()
if useAggSig {
// Wait for some more precommits; enterNewRound
cs.scheduleTimeout(cs.Precommit(round)*2, height, round, ttypes.RoundStepPrecommitWait)
}
blockID, ok := cs.Votes.Prevotes(round).TwoThirdsMajority() blockID, ok := cs.Votes.Prevotes(round).TwoThirdsMajority()
// If we don't have a polka, we must precommit nil // If we don't have a polka, we must precommit nil
...@@ -957,7 +983,7 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) { ...@@ -957,7 +983,7 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) {
if cs.LockedBlock != nil { if cs.LockedBlock != nil {
tendermintlog.Info("enterPrecommit: No +2/3 prevotes during enterPrecommit while we're locked. Precommitting nil") tendermintlog.Info("enterPrecommit: No +2/3 prevotes during enterPrecommit while we're locked. Precommitting nil")
} else { } else {
tendermintlog.Info("enterPrecommit: No +2/3 prevotes during enterPrecommit. Precommitting nil.") tendermintlog.Info("enterPrecommit: No +2/3 prevotes during enterPrecommit. Precommitting nil")
} }
cs.signAddVote(ttypes.VoteTypePrecommit, nil) cs.signAddVote(ttypes.VoteTypePrecommit, nil)
return return
...@@ -1009,6 +1035,7 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) { ...@@ -1009,6 +1035,7 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) {
// Fetch that block, unlock, and precommit nil. // Fetch that block, unlock, and precommit nil.
// The +2/3 prevotes for this round is the POL for our unlock. // The +2/3 prevotes for this round is the POL for our unlock.
// TODO: In the future save the POL prevotes for justification. // TODO: In the future save the POL prevotes for justification.
tendermintlog.Info("enterPrecommit: +2/3 prevotes for a block we do not have. Precommitting nil", "hash", fmt.Sprintf("%X", blockID.Hash))
cs.LockedRound = -1 cs.LockedRound = -1
cs.LockedBlock = nil cs.LockedBlock = nil
if !bytes.Equal(cs.ProposalBlockHash, blockID.Hash) { if !bytes.Equal(cs.ProposalBlockHash, blockID.Hash) {
...@@ -1018,6 +1045,22 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) { ...@@ -1018,6 +1045,22 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) {
cs.signAddVote(ttypes.VoteTypePrecommit, nil) cs.signAddVote(ttypes.VoteTypePrecommit, nil)
} }
// Enter: send precommit for aggregate at next round.
func (cs *ConsensusState) enterAggPrecommitWait(height int64, round int) {
if cs.Height != height || round < cs.Round || (cs.Round == round && ttypes.RoundStepAggPrecommitWait < cs.Step) {
tendermintlog.Debug(fmt.Sprintf("enterAggPrecommitWait(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step))
return
}
tendermintlog.Info(fmt.Sprintf("enterAggPrecommitWait(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step))
// enable gossip votes when timeout waiting for aggregate precommit
gossipVotes.Store(true)
//addr := cs.privValidator.GetAddress()
//vote := cs.Votes.Precommits(round).GetByAddress(addr)
//cs.broadcastChannel <- MsgInfo{TypeID: ttypes.VoteID, Msg: vote.Vote, PeerID: cs.ourID, PeerIP: ""}
}
// Enter: any +2/3 precommits for next round. // Enter: any +2/3 precommits for next round.
func (cs *ConsensusState) enterPrecommitWait(height int64, round int) { func (cs *ConsensusState) enterPrecommitWait(height int64, round int) {
if cs.Height != height || round < cs.Round || (cs.Round == round && ttypes.RoundStepPrecommitWait <= cs.Step) { if cs.Height != height || round < cs.Round || (cs.Round == round && ttypes.RoundStepPrecommitWait <= cs.Step) {
...@@ -1035,9 +1078,13 @@ func (cs *ConsensusState) enterPrecommitWait(height int64, round int) { ...@@ -1035,9 +1078,13 @@ func (cs *ConsensusState) enterPrecommitWait(height int64, round int) {
cs.newStep() cs.newStep()
}() }()
// enable gossip votes in case other validators enterAggPrecommitWait
if useAggSig && !cs.isProposer() && cs.Votes.Precommits(round).GetAggVote() == nil {
gossipVotes.Store(true)
}
// Wait for some more precommits; enterNewRound // Wait for some more precommits; enterNewRound
cs.scheduleTimeout(cs.Precommit(round), height, round, ttypes.RoundStepPrecommitWait) cs.scheduleTimeout(cs.Precommit(round), height, round, ttypes.RoundStepPrecommitWait)
} }
// Enter: +2/3 precommits for block // Enter: +2/3 precommits for block
...@@ -1076,22 +1123,22 @@ func (cs *ConsensusState) enterCommit(height int64, commitRound int) { ...@@ -1076,22 +1123,22 @@ func (cs *ConsensusState) enterCommit(height int64, commitRound int) {
// If we don't have the block being committed, set up to get it. // If we don't have the block being committed, set up to get it.
if !cs.ProposalBlock.HashesTo(blockID.Hash) { if !cs.ProposalBlock.HashesTo(blockID.Hash) {
if !bytes.Equal(cs.ProposalBlockHash, blockID.Hash) { tendermintlog.Info("Commit is for a block we don't know about. Set ProposalBlock=nil",
tendermintlog.Info("Commit is for a block we don't know about. Set ProposalBlock=nil", "ProposalBlock-hash", fmt.Sprintf("%X", cs.ProposalBlock.Hash()), "proposal", fmt.Sprintf("%X", cs.ProposalBlock.Hash()),
"CommitBlock-hash", fmt.Sprintf("%X", blockID.Hash)) "ProposalBlockHash", fmt.Sprintf("%X", cs.ProposalBlockHash),
// We're getting the wrong block. "commit", fmt.Sprintf("%X", blockID.Hash))
// Set up ProposalBlockHash and keep waiting. // We're getting the wrong block.
cs.ProposalBlock = nil // Set up ProposalBlockHash and keep waiting.
cs.ProposalBlockHash = blockID.Hash cs.ProposalBlock = nil
cs.ProposalBlockHash = blockID.Hash
validBlockMsg := &tmtypes.ValidBlockMsg{
Height: cs.Height, validBlockMsg := &tmtypes.ValidBlockMsg{
Round: int32(cs.Round), Height: cs.Height,
Blockhash: cs.ProposalBlockHash, Round: int32(cs.Round),
IsCommit: false, Blockhash: cs.ProposalBlockHash,
} IsCommit: true,
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.ValidBlockID, Msg: validBlockMsg, PeerID: cs.ourID, PeerIP: ""}
} }
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.ValidBlockID, Msg: validBlockMsg, PeerID: "", PeerIP: ""}
//else { //else {
// We just need to keep waiting. // We just need to keep waiting.
//} //}
...@@ -1398,7 +1445,7 @@ func (cs *ConsensusState) tryAddAggVote(aggVoteRaw *tmtypes.AggVote, peerID stri ...@@ -1398,7 +1445,7 @@ func (cs *ConsensusState) tryAddAggVote(aggVoteRaw *tmtypes.AggVote, peerID stri
Blockhash: cs.ProposalBlockHash, Blockhash: cs.ProposalBlockHash,
IsCommit: false, IsCommit: false,
} }
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.ValidBlockID, Msg: validBlockMsg, PeerID: cs.ourID, PeerIP: ""} cs.broadcastChannel <- MsgInfo{TypeID: ttypes.ValidBlockID, Msg: validBlockMsg, PeerID: "", PeerIP: ""}
} }
} }
...@@ -1500,7 +1547,7 @@ func (cs *ConsensusState) addVote(vote *ttypes.Vote, peerID string, peerIP strin ...@@ -1500,7 +1547,7 @@ func (cs *ConsensusState) addVote(vote *ttypes.Vote, peerID string, peerIP strin
Type: int32(vote.Type), Type: int32(vote.Type),
Index: vote.ValidatorIndex, Index: vote.ValidatorIndex,
} }
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.HasVoteID, Msg: hasVoteMsg, PeerID: cs.ourID, PeerIP: ""} cs.broadcastChannel <- MsgInfo{TypeID: ttypes.HasVoteID, Msg: hasVoteMsg, PeerID: "", PeerIP: ""}
// if we can skip timeoutCommit and have all the votes now, // if we can skip timeoutCommit and have all the votes now,
if skipTimeoutCommit && cs.LastCommit.HasAll() { if skipTimeoutCommit && cs.LastCommit.HasAll() {
...@@ -1536,7 +1583,7 @@ func (cs *ConsensusState) addVote(vote *ttypes.Vote, peerID string, peerIP strin ...@@ -1536,7 +1583,7 @@ func (cs *ConsensusState) addVote(vote *ttypes.Vote, peerID string, peerIP strin
Type: int32(vote.Type), Type: int32(vote.Type),
Index: vote.ValidatorIndex, Index: vote.ValidatorIndex,
} }
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.HasVoteID, Msg: hasVoteMsg, PeerID: cs.ourID, PeerIP: ""} cs.broadcastChannel <- MsgInfo{TypeID: ttypes.HasVoteID, Msg: hasVoteMsg, PeerID: "", PeerIP: ""}
switch vote.Type { switch vote.Type {
case uint32(ttypes.VoteTypePrevote): case uint32(ttypes.VoteTypePrevote):
...@@ -1585,7 +1632,7 @@ func (cs *ConsensusState) addVote(vote *ttypes.Vote, peerID string, peerIP strin ...@@ -1585,7 +1632,7 @@ func (cs *ConsensusState) addVote(vote *ttypes.Vote, peerID string, peerIP strin
Blockhash: cs.ProposalBlockHash, Blockhash: cs.ProposalBlockHash,
IsCommit: false, IsCommit: false,
} }
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.ValidBlockID, Msg: validBlockMsg, PeerID: cs.ourID, PeerIP: ""} cs.broadcastChannel <- MsgInfo{TypeID: ttypes.ValidBlockID, Msg: validBlockMsg, PeerID: "", PeerIP: ""}
} }
} }
...@@ -1597,14 +1644,14 @@ func (cs *ConsensusState) addVote(vote *ttypes.Vote, peerID string, peerIP strin ...@@ -1597,14 +1644,14 @@ func (cs *ConsensusState) addVote(vote *ttypes.Vote, peerID string, peerIP strin
case cs.Round == int(vote.Round) && ttypes.RoundStepPrevote <= cs.Step: // current round case cs.Round == int(vote.Round) && ttypes.RoundStepPrevote <= cs.Step: // current round
blockID, ok := prevotes.TwoThirdsMajority() blockID, ok := prevotes.TwoThirdsMajority()
if ok && (cs.isProposalComplete() || len(blockID.Hash) == 0) { if ok && (cs.isProposalComplete() || len(blockID.Hash) == 0) {
if useAggSig && prevotes.GetAggVote() == nil { if useAggSig && cs.isProposer() && prevotes.GetAggVote() == nil {
err := prevotes.SetAggVote() err := prevotes.SetAggVote()
if err != nil { if err != nil {
tendermintlog.Error("prevotes SetAggVote fail", "err", err) tendermintlog.Error("prevotes SetAggVote fail", "err", err)
break break
} }
aggVoteMsg := prevotes.GetAggVote().AggVote aggVoteMsg := prevotes.GetAggVote().AggVote
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.AggVoteID, Msg: aggVoteMsg, PeerID: cs.ourID, PeerIP: ""} cs.broadcastChannel <- MsgInfo{TypeID: ttypes.AggVoteID, Msg: aggVoteMsg, PeerID: "", PeerIP: ""}
tendermintlog.Info("Send aggregate prevote", "aggVote", prevotes.GetAggVote()) tendermintlog.Info("Send aggregate prevote", "aggVote", prevotes.GetAggVote())
} }
cs.enterPrecommit(height, int(vote.Round)) cs.enterPrecommit(height, int(vote.Round))
...@@ -1628,14 +1675,14 @@ func (cs *ConsensusState) addVote(vote *ttypes.Vote, peerID string, peerIP strin ...@@ -1628,14 +1675,14 @@ func (cs *ConsensusState) addVote(vote *ttypes.Vote, peerID string, peerIP strin
cs.enterNewRound(height, int(vote.Round)) cs.enterNewRound(height, int(vote.Round))
cs.enterPrecommit(height, int(vote.Round)) cs.enterPrecommit(height, int(vote.Round))
if len(blockID.Hash) != 0 { if len(blockID.Hash) != 0 {
if useAggSig && precommits.GetAggVote() == nil { if useAggSig && cs.isProposer() && precommits.GetAggVote() == nil {
err := precommits.SetAggVote() err := precommits.SetAggVote()
if err != nil { if err != nil {
tendermintlog.Error("precommits SetAggVote fail", "err", err) tendermintlog.Error("precommits SetAggVote fail", "err", err)
break break
} }
aggVoteMsg := precommits.GetAggVote().AggVote aggVoteMsg := precommits.GetAggVote().AggVote
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.AggVoteID, Msg: aggVoteMsg, PeerID: cs.ourID, PeerIP: ""} cs.broadcastChannel <- MsgInfo{TypeID: ttypes.AggVoteID, Msg: aggVoteMsg, PeerID: "", PeerIP: ""}
tendermintlog.Info("Send aggregate precommit", "aggVote", precommits.GetAggVote()) tendermintlog.Info("Send aggregate precommit", "aggVote", precommits.GetAggVote())
} }
cs.enterCommit(height, int(vote.Round)) cs.enterCommit(height, int(vote.Round))
...@@ -1692,6 +1739,12 @@ func (cs *ConsensusState) signAddVote(voteType byte, hash []byte) *ttypes.Vote { ...@@ -1692,6 +1739,12 @@ func (cs *ConsensusState) signAddVote(voteType byte, hash []byte) *ttypes.Vote {
if useAggSig { if useAggSig {
// send to proposer // send to proposer
cs.unicastChannel <- MsgInfo{TypeID: ttypes.VoteID, Msg: vote.Vote, PeerID: cs.getProposerID(), PeerIP: ""} cs.unicastChannel <- MsgInfo{TypeID: ttypes.VoteID, Msg: vote.Vote, PeerID: cs.getProposerID(), PeerIP: ""}
// wait for aggregate vote
if voteType == ttypes.VoteTypePrevote {
cs.scheduleTimeout(cs.Prevote(cs.Round), cs.Height, cs.Round, ttypes.RoundStepAggPrevoteWait)
} else if voteType == ttypes.VoteTypePrecommit {
cs.scheduleTimeout(cs.Precommit(cs.Round), cs.Height, cs.Round, ttypes.RoundStepAggPrecommitWait)
}
} }
tendermintlog.Info("Sign and send vote", "height", cs.Height, "round", cs.Round, "vote", vote) tendermintlog.Info("Sign and send vote", "height", cs.Height, "round", cs.Round, "vote", vote)
return vote return vote
......
...@@ -200,7 +200,7 @@ func (node *Node) Start() { ...@@ -200,7 +200,7 @@ func (node *Node) Start() {
ip, _ := splitHostPort(addr) ip, _ := splitHostPort(addr)
_, ok := node.localIPs[ip] _, ok := node.localIPs[ip]
if ok { if ok {
tendermintlog.Info("find our ip ", "ourip", ip) tendermintlog.Info("find our ip ", "ourIP", ip)
node.IP = ip node.IP = ip
return return
} }
...@@ -325,6 +325,8 @@ func (node *Node) UnicastRoutine() { ...@@ -325,6 +325,8 @@ func (node *Node) UnicastRoutine() {
} }
for _, peer := range node.peerSet.List() { for _, peer := range node.peerSet.List() {
if peer.ID() == msg.PeerID { if peer.ID() == msg.PeerID {
peerIP, _ := peer.RemoteIP()
msg.PeerIP = peerIP.String()
success := peer.Send(msg) success := peer.Send(msg)
if !success { if !success {
tendermintlog.Error("send failure in UnicastRoutine") tendermintlog.Error("send failure in UnicastRoutine")
...@@ -400,6 +402,7 @@ func (node *Node) addPeer(pc *peerConn) error { ...@@ -400,6 +402,7 @@ func (node *Node) addPeer(pc *peerConn) error {
ID: node.ID, ID: node.ID,
Network: node.Network, Network: node.Network,
Version: node.Version, Version: node.Version,
IP: node.IP,
} }
// Exchange NodeInfo on the conn // Exchange NodeInfo on the conn
peerNodeInfo, err := pc.HandshakeTimeout(nodeinfo, handshakeTimeout*time.Second) peerNodeInfo, err := pc.HandshakeTimeout(nodeinfo, handshakeTimeout*time.Second)
...@@ -460,6 +463,9 @@ func (node *Node) addPeer(pc *peerConn) error { ...@@ -460,6 +463,9 @@ func (node *Node) addPeer(pc *peerConn) error {
} }
tendermintlog.Info("Added peer", "peer", pc.ip) tendermintlog.Info("Added peer", "peer", pc.ip)
stateMsg := MsgInfo{TypeID: ttypes.NewRoundStepID, Msg: node.state.RoundStateMessage(), PeerID: pc.id, PeerIP: pc.ip.String()}
pc.Send(stateMsg)
tendermintlog.Info("Send state msg", "msg", stateMsg, "ourIP", node.IP, "ourID", node.ID)
return nil return nil
} }
...@@ -472,6 +478,9 @@ func (node *Node) Broadcast(msg MsgInfo) chan bool { ...@@ -472,6 +478,9 @@ func (node *Node) Broadcast(msg MsgInfo) chan bool {
wg.Add(1) wg.Add(1)
go func(peer Peer) { go func(peer Peer) {
defer wg.Done() defer wg.Done()
msg.PeerID = peer.ID()
peerIP, _ := peer.RemoteIP()
msg.PeerIP = peerIP.String()
success := peer.Send(msg) success := peer.Send(msg)
successChan <- success successChan <- success
}(peer) }(peer)
......
...@@ -165,6 +165,20 @@ func (ps *PeerSet) hasIP(peerIP net.IP) bool { ...@@ -165,6 +165,20 @@ func (ps *PeerSet) hasIP(peerIP net.IP) bool {
return false return false
} }
//
func (ps *PeerSet) GetIP(peerKey ID) net.IP {
ps.mtx.Lock()
ps.mtx.Unlock()
if item, ok := ps.lookup[peerKey]; ok {
ip, err := item.peer.RemoteIP()
if err == nil {
return ip
}
}
return nil
}
// Size of list // Size of list
func (ps *PeerSet) Size() int { func (ps *PeerSet) Size() int {
ps.mtx.Lock() ps.mtx.Lock()
...@@ -356,6 +370,14 @@ func (pc *peerConn) Send(msg MsgInfo) bool { ...@@ -356,6 +370,14 @@ func (pc *peerConn) Send(msg MsgInfo) bool {
atomic.AddInt32(&pc.sendQueueSize, 1) atomic.AddInt32(&pc.sendQueueSize, 1)
return true return true
case <-time.After(defaultSendTimeout): case <-time.After(defaultSendTimeout):
if msg.TypeID == ttypes.ProposalBlockID {
if propBlock, ok := msg.Msg.(*tmtypes.TendermintBlock); ok {
msg.Msg = &tmtypes.TendermintBlock{
Header: propBlock.Header,
LastCommit: propBlock.LastCommit,
}
}
}
tendermintlog.Error("send msg timeout", "peerip", msg.PeerIP, "msg", msg) tendermintlog.Error("send msg timeout", "peerip", msg.PeerIP, "msg", msg)
return false return false
} }
...@@ -378,29 +400,35 @@ func (pc *peerConn) TrySend(msg MsgInfo) bool { ...@@ -378,29 +400,35 @@ func (pc *peerConn) TrySend(msg MsgInfo) bool {
// Returns true if vote was sent. // Returns true if vote was sent.
func (pc *peerConn) PickSendVote(votes ttypes.VoteSetReader) bool { func (pc *peerConn) PickSendVote(votes ttypes.VoteSetReader) bool {
if useAggSig { if useAggSig {
if pc.state.AggPrecommit {
time.Sleep(pc.myState.PeerGossipSleep())
return false
}
aggVote := votes.GetAggVote() aggVote := votes.GetAggVote()
if aggVote != nil { if aggVote != nil {
if votes.IsCommit() {
pc.state.ensureCatchupCommitRound(votes.Height(), votes.Round(), votes.Size())
}
if pc.state.Height != aggVote.Height ||
(pc.state.Round != int(aggVote.Round) && pc.state.CatchupCommitRound != int(aggVote.Round)) {
return false
}
if (aggVote.Type == uint32(ttypes.VoteTypePrevote) && pc.state.AggPrevote) ||
(aggVote.Type == uint32(ttypes.VoteTypePrecommit) && pc.state.AggPrecommit) {
return false
}
msg := MsgInfo{TypeID: ttypes.AggVoteID, Msg: aggVote.AggVote, PeerID: pc.id, PeerIP: pc.ip.String()} msg := MsgInfo{TypeID: ttypes.AggVoteID, Msg: aggVote.AggVote, PeerID: pc.id, PeerIP: pc.ip.String()}
tendermintlog.Debug("Sending aggregate vote message", "msg", msg) tendermintlog.Debug("Sending aggregate vote message", "msg", msg)
if pc.Send(msg) { if pc.Send(msg) {
pc.state.SetHasAggPrecommit(aggVote) pc.state.SetHasAggVote(aggVote)
time.Sleep(pc.myState.PeerGossipSleep())
return true return true
} }
return false
} }
return false }
} else if vote, ok := pc.state.PickVoteToSend(votes); ok { if vote, ok := pc.state.PickVoteToSend(votes); ok {
msg := MsgInfo{TypeID: ttypes.VoteID, Msg: vote.Vote, PeerID: pc.id, PeerIP: pc.ip.String()} msg := MsgInfo{TypeID: ttypes.VoteID, Msg: vote.Vote, PeerID: pc.id, PeerIP: pc.ip.String()}
tendermintlog.Debug("Sending vote message", "msg", msg) tendermintlog.Debug("Sending vote message", "msg", msg)
if pc.Send(msg) { if pc.Send(msg) {
pc.state.SetHasVote(vote) pc.state.SetHasVote(vote)
return true return true
} }
return false
} }
return false return false
} }
...@@ -666,7 +694,7 @@ FOR_LOOP: ...@@ -666,7 +694,7 @@ FOR_LOOP:
if ok { if ok {
tendermintlog.Debug("Received proposal heartbeat message", tendermintlog.Debug("Received proposal heartbeat message",
"height", msg.Height, "round", msg.Round, "sequence", msg.Sequence, "height", msg.Height, "round", msg.Round, "sequence", msg.Sequence,
"valIdx", msg.ValidatorIndex, "valAddr", msg.ValidatorAddress) "valIdx", msg.ValidatorIndex, "valAddr", fmt.Sprintf("%X", msg.ValidatorAddress))
} }
} }
} }
...@@ -688,25 +716,30 @@ OUTER_LOOP: ...@@ -688,25 +716,30 @@ OUTER_LOOP:
// If the peer is on a previous height, help catch up. // If the peer is on a previous height, help catch up.
if (0 < prs.Height) && (prs.Height < rs.Height) { if (0 < prs.Height) && (prs.Height < rs.Height) {
time.Sleep(2 * pc.myState.PeerGossipSleep()) if prs.ProposalBlockHash != nil && !prs.ProposalBlock {
if prs.Height >= rs.Height { proposalBlock := pc.myState.client.LoadProposalBlock(prs.Height)
continue OUTER_LOOP if proposalBlock == nil {
} tendermintlog.Error("load proposal block fail", "selfHeight", rs.Height,
proposalBlock := pc.myState.client.LoadProposalBlock(prs.Height) "blockHeight", pc.myState.client.GetCurrentHeight())
if proposalBlock == nil { time.Sleep(pc.myState.PeerGossipSleep())
tendermintlog.Error("load proposal block fail", "selfHeight", rs.Height, continue OUTER_LOOP
"blockHeight", pc.myState.client.GetCurrentHeight()) }
newBlock := &ttypes.TendermintBlock{TendermintBlock: proposalBlock}
if !newBlock.HashesTo(prs.ProposalBlockHash) {
tendermintlog.Error(fmt.Sprintf("Wrong proposal block hash. Expected %X, got %X", prs.ProposalBlockHash,
newBlock.Hash()), "height", prs.Height)
time.Sleep(pc.myState.PeerGossipSleep())
continue OUTER_LOOP
}
msg := MsgInfo{TypeID: ttypes.ProposalBlockID, Msg: proposalBlock, PeerID: pc.id, PeerIP: pc.ip.String()}
tendermintlog.Info("Sending block for catchup", "peerIP", pc.ip.String(),
"selfHeight", rs.Height, "peer(H/R/S)", fmt.Sprintf("%v/%v/%v", prs.Height, prs.Round, prs.Step),
"block(H/R/hash)", fmt.Sprintf("%v/%v/%X", proposalBlock.Header.Height, proposalBlock.Header.Round, newBlock.Hash()))
if pc.Send(msg) {
prs.SetHasProposalBlock(newBlock)
}
continue OUTER_LOOP continue OUTER_LOOP
} }
newBlock := &ttypes.TendermintBlock{TendermintBlock: proposalBlock}
msg := MsgInfo{TypeID: ttypes.ProposalBlockID, Msg: proposalBlock, PeerID: pc.id, PeerIP: pc.ip.String()}
tendermintlog.Info("Sending block for catchup", "peerip", pc.ip.String(),
"selfHeight", rs.Height, "peerHeight", prs.Height, "block(H/R/hash)",
fmt.Sprintf("%v/%v/%X", proposalBlock.Header.Height, proposalBlock.Header.Round, newBlock.Hash()))
if !pc.Send(msg) {
tendermintlog.Error("send catchup block fail")
}
continue OUTER_LOOP
} }
// If height and round don't match, sleep. // If height and round don't match, sleep.
...@@ -790,8 +823,10 @@ OUTER_LOOP: ...@@ -790,8 +823,10 @@ OUTER_LOOP:
// If height matches, then send LastCommit, Prevotes, Precommits. // If height matches, then send LastCommit, Prevotes, Precommits.
if rs.Height == prs.Height { if rs.Height == prs.Height {
if !useAggSig && pc.gossipVotesForHeight(rs, &prs.PeerRoundState) { if !useAggSig || gossipVotes.Load().(bool) {
continue OUTER_LOOP if pc.gossipVotesForHeight(rs, &prs.PeerRoundState) {
continue OUTER_LOOP
}
} }
} }
...@@ -815,7 +850,7 @@ OUTER_LOOP: ...@@ -815,7 +850,7 @@ OUTER_LOOP:
tendermintlog.Info("Picked Catchup commit to send", tendermintlog.Info("Picked Catchup commit to send",
"commit(H/R)", fmt.Sprintf("%v/%v", commitObj.Height(), commitObj.Round()), "commit(H/R)", fmt.Sprintf("%v/%v", commitObj.Height(), commitObj.Round()),
"BitArray", commitObj.BitArray().String(), "BitArray", commitObj.BitArray().String(),
"peerip", pc.ip.String(), "height", prs.Height) "peerip", pc.ip.String(), "peer(H/R/S)", fmt.Sprintf("%v/%v/%v", prs.Height, prs.Round, prs.Step))
continue OUTER_LOOP continue OUTER_LOOP
} }
} }
...@@ -1030,33 +1065,40 @@ func (ps *PeerConnState) SetHasProposalBlock(block *ttypes.TendermintBlock) { ...@@ -1030,33 +1065,40 @@ func (ps *PeerConnState) SetHasProposalBlock(block *ttypes.TendermintBlock) {
ps.mtx.Lock() ps.mtx.Lock()
defer ps.mtx.Unlock() defer ps.mtx.Unlock()
if ps.Height != block.Header.Height || ps.Round != int(block.Header.Round) { if ps.Height != block.Header.Height ||
(ps.Round != int(block.Header.Round) && ps.CatchupCommitRound != int(block.Header.Round)) {
return return
} }
if ps.ProposalBlock { if ps.ProposalBlock {
return return
} }
tendermintlog.Debug("Peer set proposal block", "peerip", ps.ip.String(), tendermintlog.Debug("Peer set proposal block", "peerIP", ps.ip.String(),
"peer-state", fmt.Sprintf("%v/%v/%v", ps.Height, ps.Round, ps.Step), "peer-state", fmt.Sprintf("%v/%v(%v)/%v", ps.Height, ps.Round, ps.CatchupCommitRound, ps.Step),
"block(H/R)", fmt.Sprintf("%v/%v", block.Header.Height, block.Header.Round)) "block(H/R)", fmt.Sprintf("%v/%v", block.Header.Height, block.Header.Round))
ps.ProposalBlock = true ps.ProposalBlock = true
} }
// SetHasAggPrecommit sets the given aggregate precommit as known for the peer. // SetHasAggVote sets the given aggregate precommit as known for the peer.
func (ps *PeerConnState) SetHasAggPrecommit(aggVote *ttypes.AggVote) { func (ps *PeerConnState) SetHasAggVote(aggVote *ttypes.AggVote) {
ps.mtx.Lock() ps.mtx.Lock()
defer ps.mtx.Unlock() defer ps.mtx.Unlock()
if ps.Height != aggVote.Height || ps.Round != int(aggVote.Round) { if ps.Height != aggVote.Height ||
(ps.Round != int(aggVote.Round) && ps.CatchupCommitRound != int(aggVote.Round)) {
return return
} }
if ps.AggPrecommit { if (aggVote.Type == uint32(ttypes.VoteTypePrevote) && ps.AggPrevote) ||
(aggVote.Type == uint32(ttypes.VoteTypePrecommit) && ps.AggPrecommit) {
return return
} }
tendermintlog.Debug("Peer set aggregate precommit", "peerip", ps.ip.String(), tendermintlog.Debug("Peer set aggregate vote", "peerIP", ps.ip.String(),
"peer-state", fmt.Sprintf("%v/%v/%v", ps.Height, ps.Round, ps.Step), "peer-state", fmt.Sprintf("%v/%v(%v)/%v", ps.Height, ps.Round, ps.CatchupCommitRound, ps.Step),
"aggVote(H/R)", fmt.Sprintf("%v/%v", aggVote.Height, aggVote.Round)) "aggVote(H/R/T)", fmt.Sprintf("%v/%v/%v", aggVote.Height, aggVote.Round, aggVote.Type))
ps.AggPrecommit = true if aggVote.Type == uint32(ttypes.VoteTypePrevote) {
ps.AggPrevote = true
} else if aggVote.Type == uint32(ttypes.VoteTypePrecommit) {
ps.AggPrecommit = true
}
} }
// PickVoteToSend picks a vote to send to the peer. // PickVoteToSend picks a vote to send to the peer.
...@@ -1086,7 +1128,7 @@ func (ps *PeerConnState) PickVoteToSend(votes ttypes.VoteSetReader) (vote *ttype ...@@ -1086,7 +1128,7 @@ func (ps *PeerConnState) PickVoteToSend(votes ttypes.VoteSetReader) (vote *ttype
if index, ok := votes.BitArray().Sub(psVotes).PickRandom(); ok { if index, ok := votes.BitArray().Sub(psVotes).PickRandom(); ok {
tendermintlog.Debug("PickVoteToSend", "peer(H/R)", fmt.Sprintf("%v/%v", ps.Height, ps.Round), tendermintlog.Debug("PickVoteToSend", "peer(H/R)", fmt.Sprintf("%v/%v", ps.Height, ps.Round),
"vote(H/R)", fmt.Sprintf("%v/%v", height, round), "type", voteType, "selfVotes", votes.BitArray().String(), "vote(H/R)", fmt.Sprintf("%v/%v", height, round), "type", voteType, "selfVotes", votes.BitArray().String(),
"peerVotes", psVotes.String(), "peerip", ps.ip.String()) "peerVotes", psVotes.String(), "peerIP", ps.ip.String())
return votes.GetByIndex(index), true return votes.GetByIndex(index), true
} }
return nil, false return nil, false
...@@ -1252,6 +1294,7 @@ func (ps *PeerConnState) ApplyNewRoundStepMessage(msg *tmtypes.NewRoundStepMsg) ...@@ -1252,6 +1294,7 @@ func (ps *PeerConnState) ApplyNewRoundStepMessage(msg *tmtypes.NewRoundStepMsg)
// We'll update the BitArray capacity later. // We'll update the BitArray capacity later.
ps.Prevotes = nil ps.Prevotes = nil
ps.Precommits = nil ps.Precommits = nil
ps.AggPrevote = false
ps.AggPrecommit = false ps.AggPrecommit = false
} }
if psHeight == msg.Height && psRound != int(msg.Round) && int(msg.Round) == psCatchupCommitRound { if psHeight == msg.Height && psRound != int(msg.Round) && int(msg.Round) == psCatchupCommitRound {
...@@ -1291,11 +1334,17 @@ func (ps *PeerConnState) ApplyValidBlockMessage(msg *tmtypes.ValidBlockMsg) { ...@@ -1291,11 +1334,17 @@ func (ps *PeerConnState) ApplyValidBlockMessage(msg *tmtypes.ValidBlockMsg) {
if ps.Round != int(msg.Round) && !msg.IsCommit { if ps.Round != int(msg.Round) && !msg.IsCommit {
return return
} }
tendermintlog.Debug("ApplyValidBlockMessage", "peerip", ps.ip.String(), tendermintlog.Debug("ApplyValidBlockMessage", "peerIP", ps.ip.String(),
"peer(H/R)", fmt.Sprintf("%v/%v", ps.Height, ps.Round), "peer(H/R/S)", fmt.Sprintf("%v/%v/%v", ps.Height, ps.Round, ps.Step),
"blockhash", fmt.Sprintf("%X", msg.Blockhash)) "blockhash", fmt.Sprintf("%X", msg.Blockhash))
ps.ProposalBlockHash = msg.Blockhash ps.ProposalBlockHash = msg.Blockhash
if ps.CatchupCommitRound == int(msg.Round) && msg.IsCommit {
tendermintlog.Info("Set ProposalBlockHash for catchup", "peerIP", ps.ip.String(),
"peer(H/R/S)", fmt.Sprintf("%v/%v/%v", ps.Height, ps.Round, ps.Step),
"CommitRound", ps.CatchupCommitRound,
"ProposalBlockHash", fmt.Sprintf("%X", ps.ProposalBlockHash))
}
} }
// ApplyProposalPOLMessage updates the peer state for the new proposal POL. // ApplyProposalPOLMessage updates the peer state for the new proposal POL.
......
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
"fmt" "fmt"
"math/rand" "math/rand"
"os" "os"
"sync/atomic"
"time" "time"
"github.com/33cn/chain33/common/crypto" "github.com/33cn/chain33/common/crypto"
...@@ -47,12 +48,13 @@ var ( ...@@ -47,12 +48,13 @@ var (
preExec = false preExec = false
createEmptyBlocksInterval int32 // second createEmptyBlocksInterval int32 // second
validatorNodes = []string{"127.0.0.1:46656"} validatorNodes = []string{"127.0.0.1:46656"}
peerGossipSleepDuration int32 = 200 peerGossipSleepDuration int32 = 100
peerQueryMaj23SleepDuration int32 = 2000 peerQueryMaj23SleepDuration int32 = 2000
zeroHash [32]byte zeroHash [32]byte
random *rand.Rand random *rand.Rand
signName = "ed25519" signName = "ed25519"
useAggSig = false useAggSig = false
gossipVotes atomic.Value
) )
func init() { func init() {
...@@ -150,6 +152,7 @@ func applyConfig(sub []byte) { ...@@ -150,6 +152,7 @@ func applyConfig(sub []byte) {
signName = subcfg.SignName signName = subcfg.SignName
} }
useAggSig = subcfg.UseAggregateSignature useAggSig = subcfg.UseAggregateSignature
gossipVotes.Store(true)
} }
// DefaultDBProvider returns a database using the DBBackend and DBDir // DefaultDBProvider returns a database using the DBBackend and DBDir
...@@ -306,12 +309,11 @@ OuterLoop: ...@@ -306,12 +309,11 @@ OuterLoop:
} }
tendermintlog.Info("Save state from block") tendermintlog.Info("Save state from block")
} }
tendermintlog.Debug("Load state finish", "state", state)
// start // start
tendermintlog.Info("StartConsensus", tendermintlog.Info("StartConsensus",
"privValidator", fmt.Sprintf("%X", ttypes.Fingerprint(client.privValidator.GetAddress())), "privValidator", fmt.Sprintf("%X", ttypes.Fingerprint(client.privValidator.GetAddress())),
"Validators", state.Validators.String()) "state", state)
// Log whether this node is a validator or an observer // Log whether this node is a validator or an observer
if state.Validators.HasAddress(client.privValidator.GetAddress()) { if state.Validators.HasAddress(client.privValidator.GetAddress()) {
tendermintlog.Info("This node is a validator") tendermintlog.Info("This node is a validator")
...@@ -424,7 +426,6 @@ func (client *Client) ProcEvent(msg *queue.Message) bool { ...@@ -424,7 +426,6 @@ func (client *Client) ProcEvent(msg *queue.Message) bool {
// CreateBlock a routine monitor whether some transactions available and tell client by available channel // CreateBlock a routine monitor whether some transactions available and tell client by available channel
func (client *Client) CreateBlock() { func (client *Client) CreateBlock() {
issleep := true
for { for {
if client.IsClosed() { if client.IsClosed() {
tendermintlog.Info("CreateBlock quit") tendermintlog.Info("CreateBlock quit")
...@@ -432,23 +433,18 @@ func (client *Client) CreateBlock() { ...@@ -432,23 +433,18 @@ func (client *Client) CreateBlock() {
} }
if !client.csState.IsRunning() { if !client.csState.IsRunning() {
tendermintlog.Info("consensus not running") tendermintlog.Info("consensus not running")
time.Sleep(time.Second) time.Sleep(500 * time.Millisecond)
continue continue
} }
if issleep {
time.Sleep(time.Second)
}
height, err := client.getLastHeight() height, err := client.getLastHeight()
if err != nil { if err != nil {
issleep = true
continue continue
} }
if !client.CheckTxsAvailable(height) { if !client.CheckTxsAvailable(height) {
issleep = true time.Sleep(500 * time.Millisecond)
continue continue
} }
issleep = false
client.txsAvailable <- height + 1 client.txsAvailable <- height + 1
time.Sleep(time.Duration(timeoutTxAvail) * time.Millisecond) time.Sleep(time.Duration(timeoutTxAvail) * time.Millisecond)
...@@ -590,7 +586,7 @@ func (client *Client) QueryValidatorsByHeight(height int64) (*tmtypes.ValNodes, ...@@ -590,7 +586,7 @@ func (client *Client) QueryValidatorsByHeight(height int64) (*tmtypes.ValNodes,
if height < 1 { if height < 1 {
return nil, ttypes.ErrHeightLessThanOne return nil, ttypes.ErrHeightLessThanOne
} }
req := &tmtypes.ReqNodeInfo{Height: height} req := &tmtypes.ReqValNodes{Height: height}
param, err := proto.Marshal(req) param, err := proto.Marshal(req)
if err != nil { if err != nil {
tendermintlog.Error("QueryValidatorsByHeight marshal", "err", err) tendermintlog.Error("QueryValidatorsByHeight marshal", "err", err)
...@@ -670,22 +666,43 @@ func (client *Client) Query_IsHealthy(req *types.ReqNil) (types.Message, error) ...@@ -670,22 +666,43 @@ func (client *Client) Query_IsHealthy(req *types.ReqNil) (types.Message, error)
// Query_NodeInfo query validator node info // Query_NodeInfo query validator node info
func (client *Client) Query_NodeInfo(req *types.ReqNil) (types.Message, error) { func (client *Client) Query_NodeInfo(req *types.ReqNil) (types.Message, error) {
nodes := client.csState.GetRoundState().Validators.Validators vals := client.csState.GetRoundState().Validators.Validators
validators := make([]*tmtypes.Validator, 0) nodes := make([]*tmtypes.ValNodeInfo, 0)
for _, node := range nodes { for _, val := range vals {
if node == nil { if val == nil {
validators = append(validators, &tmtypes.Validator{}) nodes = append(nodes, &tmtypes.ValNodeInfo{})
} else { } else {
item := &tmtypes.Validator{ ipstr, idstr := "UNKOWN", "UNKOWN"
Address: node.Address, pub, err := ttypes.ConsensusCrypto.PubKeyFromBytes(val.PubKey)
PubKey: node.PubKey, if err != nil {
VotingPower: node.VotingPower, tendermintlog.Error("Query_NodeInfo invalid pubkey", "err", err)
Accum: node.Accum, } else {
id := GenIDByPubKey(pub)
idstr = string(id)
if id == client.node.ID {
ipstr = client.node.IP
} else {
ip := client.node.peerSet.GetIP(id)
if ip == nil {
tendermintlog.Error("Query_NodeInfo nil ip", "id", idstr)
} else {
ipstr = ip.String()
}
}
}
item := &tmtypes.ValNodeInfo{
NodeIP: ipstr,
NodeID: idstr,
Address: fmt.Sprintf("%X", val.Address),
PubKey: fmt.Sprintf("%X", val.PubKey),
VotingPower: val.VotingPower,
Accum: val.Accum,
} }
validators = append(validators, item) nodes = append(nodes, item)
} }
} }
return &tmtypes.ValidatorSet{Validators: validators, Proposer: &tmtypes.Validator{}}, nil return &tmtypes.ValNodeInfoSet{Nodes: nodes}, nil
} }
// CmpBestBlock 比较newBlock是不是最优区块 // CmpBestBlock 比较newBlock是不是最优区块
......
...@@ -272,7 +272,7 @@ func CheckState(t *testing.T, client *Client) { ...@@ -272,7 +272,7 @@ func CheckState(t *testing.T, client *Client) {
assert.Equal(t, client.csState.Prevote(0), 1000*time.Millisecond) assert.Equal(t, client.csState.Prevote(0), 1000*time.Millisecond)
assert.Equal(t, client.csState.Precommit(0), 1000*time.Millisecond) assert.Equal(t, client.csState.Precommit(0), 1000*time.Millisecond)
assert.Equal(t, client.csState.PeerGossipSleep(), 200*time.Millisecond) assert.Equal(t, client.csState.PeerGossipSleep(), 100*time.Millisecond)
assert.Equal(t, client.csState.PeerQueryMaj23Sleep(), 2000*time.Millisecond) assert.Equal(t, client.csState.PeerQueryMaj23Sleep(), 2000*time.Millisecond)
assert.Equal(t, client.csState.IsProposer(), true) assert.Equal(t, client.csState.IsProposer(), true)
assert.Nil(t, client.csState.GetPrevotesState(state.LastBlockHeight, 0, nil)) assert.Nil(t, client.csState.GetPrevotesState(state.LastBlockHeight, 0, nil))
...@@ -286,7 +286,7 @@ func CheckState(t *testing.T, client *Client) { ...@@ -286,7 +286,7 @@ func CheckState(t *testing.T, client *Client) {
msg2, err := client.Query_NodeInfo(&types.ReqNil{}) msg2, err := client.Query_NodeInfo(&types.ReqNil{})
assert.Nil(t, err) assert.Nil(t, err)
tvals := msg2.(*vty.ValidatorSet).Validators tvals := msg2.(*vty.ValNodeInfoSet).Nodes
assert.Len(t, tvals, 1) assert.Len(t, tvals, 1)
err = client.CommitBlock(client.GetCurrentBlock()) err = client.CommitBlock(client.GetCurrentBlock())
......
...@@ -201,7 +201,7 @@ func (h *Header) StringIndented(indent string) string { ...@@ -201,7 +201,7 @@ func (h *Header) StringIndented(indent string) string {
%s LastCommit: %v %s LastCommit: %v
%s Validators: %v %s Validators: %v
%s App: %v %s App: %v
%s Conensus: %v %s Consensus: %v
%s Results: %v %s Results: %v
%s}#%v`, %s}#%v`,
indent, h.ChainID, indent, h.ChainID,
...@@ -304,7 +304,7 @@ func (commit *Commit) IsCommit() bool { ...@@ -304,7 +304,7 @@ func (commit *Commit) IsCommit() bool {
// GetAggVote ... // GetAggVote ...
func (commit *Commit) GetAggVote() *AggVote { func (commit *Commit) GetAggVote() *AggVote {
if commit == nil { if commit == nil || commit.AggVote == nil {
return nil return nil
} }
aggVote := &AggVote{commit.AggVote} aggVote := &AggVote{commit.AggVote}
......
...@@ -22,14 +22,16 @@ var ( ...@@ -22,14 +22,16 @@ var (
// step and message id define // step and message id define
const ( const (
RoundStepNewHeight = RoundStepType(0x01) // Wait til CommitTime + timeoutCommit RoundStepNewHeight = RoundStepType(0x01) // Wait til CommitTime + timeoutCommit
RoundStepNewRound = RoundStepType(0x02) // Setup new round and go to RoundStepPropose RoundStepNewRound = RoundStepType(0x02) // Setup new round and go to RoundStepPropose
RoundStepPropose = RoundStepType(0x03) // Did propose, gossip proposal RoundStepPropose = RoundStepType(0x03) // Did propose, gossip proposal
RoundStepPrevote = RoundStepType(0x04) // Did prevote, gossip prevotes RoundStepPrevote = RoundStepType(0x04) // Did prevote, gossip prevotes
RoundStepPrevoteWait = RoundStepType(0x05) // Did receive any +2/3 prevotes, start timeout RoundStepAggPrevoteWait = RoundStepType(0x05) // Did send prevote for aggregate, start timeout
RoundStepPrecommit = RoundStepType(0x06) // Did precommit, gossip precommits RoundStepPrevoteWait = RoundStepType(0x06) // Did receive any +2/3 prevotes, start timeout
RoundStepPrecommitWait = RoundStepType(0x07) // Did receive any +2/3 precommits, start timeout RoundStepPrecommit = RoundStepType(0x07) // Did precommit, gossip precommits
RoundStepCommit = RoundStepType(0x08) // Entered commit state machine RoundStepAggPrecommitWait = RoundStepType(0x08) // Did send precommit for aggregate, start timeout
RoundStepPrecommitWait = RoundStepType(0x09) // Did receive any +2/3 precommits, start timeout
RoundStepCommit = RoundStepType(0x10) // Entered commit state machine
// NOTE: RoundStepNewHeight acts as RoundStepCommitWait. // NOTE: RoundStepNewHeight acts as RoundStepCommitWait.
NewRoundStepID = byte(0x01) NewRoundStepID = byte(0x01)
...@@ -84,6 +86,10 @@ func (rs RoundStepType) String() string { ...@@ -84,6 +86,10 @@ func (rs RoundStepType) String() string {
return "RoundStepPrecommitWait" return "RoundStepPrecommitWait"
case RoundStepCommit: case RoundStepCommit:
return "RoundStepCommit" return "RoundStepCommit"
case RoundStepAggPrevoteWait:
return "RoundStepAggPrevoteWait"
case RoundStepAggPrecommitWait:
return "RoundStepAggPrecommitWait"
default: default:
return "RoundStepUnknown" // Cannot panic. return "RoundStepUnknown" // Cannot panic.
} }
...@@ -188,6 +194,7 @@ type PeerRoundState struct { ...@@ -188,6 +194,7 @@ type PeerRoundState struct {
LastCommit *BitArray // All commit precommits of commit for last height. LastCommit *BitArray // All commit precommits of commit for last height.
CatchupCommitRound int // Round that we have commit for. Not necessarily unique. -1 if none. CatchupCommitRound int // Round that we have commit for. Not necessarily unique. -1 if none.
CatchupCommit *BitArray // All commit precommits peer has for this height & CatchupCommitRound CatchupCommit *BitArray // All commit precommits peer has for this height & CatchupCommitRound
AggPrevote bool // True if peer has aggregate prevote for this round
AggPrecommit bool // True if peer has aggregate precommit for this round AggPrecommit bool // True if peer has aggregate precommit for this round
} }
...@@ -208,6 +215,7 @@ func (prs PeerRoundState) StringIndented(indent string) string { ...@@ -208,6 +215,7 @@ func (prs PeerRoundState) StringIndented(indent string) string {
%s Precommits %v %s Precommits %v
%s LastCommit %v (round %v) %s LastCommit %v (round %v)
%s CatchupCommit %v (round %v) %s CatchupCommit %v (round %v)
%s AggPrevote %v
%s AggPrecommit %v %s AggPrecommit %v
%s}`, %s}`,
indent, prs.Height, prs.Round, prs.Step, prs.StartTime, indent, prs.Height, prs.Round, prs.Step, prs.StartTime,
...@@ -219,6 +227,7 @@ func (prs PeerRoundState) StringIndented(indent string) string { ...@@ -219,6 +227,7 @@ func (prs PeerRoundState) StringIndented(indent string) string {
indent, prs.Precommits, indent, prs.Precommits,
indent, prs.LastCommit, prs.LastCommitRound, indent, prs.LastCommit, prs.LastCommitRound,
indent, prs.CatchupCommit, prs.CatchupCommitRound, indent, prs.CatchupCommit, prs.CatchupCommitRound,
indent, prs.AggPrevote,
indent, prs.AggPrecommit, indent, prs.AggPrecommit,
indent) indent)
} }
......
...@@ -40,6 +40,7 @@ func ValCmd() *cobra.Command { ...@@ -40,6 +40,7 @@ func ValCmd() *cobra.Command {
IsSyncCmd(), IsSyncCmd(),
GetBlockInfoCmd(), GetBlockInfoCmd(),
GetNodeInfoCmd(), GetNodeInfoCmd(),
GetPerfStatCmd(),
AddNodeCmd(), AddNodeCmd(),
CreateCmd(), CreateCmd(),
) )
...@@ -75,7 +76,7 @@ func GetNodeInfoCmd() *cobra.Command { ...@@ -75,7 +76,7 @@ func GetNodeInfoCmd() *cobra.Command {
func getNodeInfo(cmd *cobra.Command, args []string) { func getNodeInfo(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
var res []*vt.Validator var res *vt.ValNodeInfoSet
ctx := jsonclient.NewRPCCtx(rpcLaddr, "valnode.GetNodeInfo", nil, &res) ctx := jsonclient.NewRPCCtx(rpcLaddr, "valnode.GetNodeInfo", nil, &res)
ctx.Run() ctx.Run()
} }
...@@ -113,6 +114,41 @@ func getBlockInfo(cmd *cobra.Command, args []string) { ...@@ -113,6 +114,41 @@ func getBlockInfo(cmd *cobra.Command, args []string) {
ctx.Run() ctx.Run()
} }
// GetPerfStatCmd get block info
func GetPerfStatCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "stat",
Short: "Get tendermint performance statistics",
Run: getPerfStat,
}
addGetPerfStatFlags(cmd)
return cmd
}
func addGetPerfStatFlags(cmd *cobra.Command) {
cmd.Flags().Int64P("start", "s", 0, "start block height")
cmd.Flags().Int64P("end", "e", 0, "end block height")
}
func getPerfStat(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
start, _ := cmd.Flags().GetInt64("start")
end, _ := cmd.Flags().GetInt64("end")
req := &vt.ReqPerfStat{
Start: start,
End: end,
}
params := rpctypes.Query4Jrpc{
Execer: vt.ValNodeX,
FuncName: "GetPerfState",
Payload: types.MustPBToJSON(req),
}
var res vt.PerfStat
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
}
// AddNodeCmd add validator node // AddNodeCmd add validator node
func AddNodeCmd() *cobra.Command { func AddNodeCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
......
...@@ -10,7 +10,7 @@ import ( ...@@ -10,7 +10,7 @@ import (
) )
// Query_GetValNodeByHeight method // Query_GetValNodeByHeight method
func (val *ValNode) Query_GetValNodeByHeight(in *pty.ReqNodeInfo) (types.Message, error) { func (val *ValNode) Query_GetValNodeByHeight(in *pty.ReqValNodes) (types.Message, error) {
height := in.GetHeight() height := in.GetHeight()
if height <= 0 { if height <= 0 {
...@@ -60,3 +60,60 @@ func (val *ValNode) Query_GetBlockInfoByHeight(in *pty.ReqBlockInfo) (types.Mess ...@@ -60,3 +60,60 @@ func (val *ValNode) Query_GetBlockInfoByHeight(in *pty.ReqBlockInfo) (types.Mess
} }
return reply, nil return reply, nil
} }
// Query_GetPerfState method
func (val *ValNode) Query_GetPerfState(in *pty.ReqPerfStat) (types.Message, error) {
start := in.GetStart()
end := in.GetEnd()
if start < 0 || end < 0 || start > end || end > val.GetHeight() {
return nil, types.ErrInvalidParam
}
if start == 0 {
start = 1
}
if end == 0 {
end = val.GetHeight()
}
startKey := CalcValNodeBlockInfoHeightKey(start)
startValue, err := val.GetLocalDB().Get(startKey)
if err != nil {
return nil, err
}
if len(startValue) == 0 {
return nil, types.ErrNotFound
}
startInfo := &pty.TendermintBlockInfo{}
err = types.Decode(startValue, startInfo)
if err != nil {
return nil, err
}
endKey := CalcValNodeBlockInfoHeightKey(end)
endValue, err := val.GetLocalDB().Get(endKey)
if err != nil {
return nil, err
}
if len(endValue) == 0 {
return nil, types.ErrNotFound
}
endInfo := &pty.TendermintBlockInfo{}
err = types.Decode(endValue, endInfo)
if err != nil {
return nil, err
}
startHeader := startInfo.Block.Header
endHeader := endInfo.Block.Header
totalTx := endHeader.TotalTxs - startHeader.TotalTxs
totalBlock := endHeader.Height - startHeader.Height + 1
totalSecond := endHeader.Time - startHeader.Time + 1
return &pty.PerfStat{
TotalTx: totalTx,
TotalBlock: totalBlock,
TxPerBlock: totalTx / totalBlock,
TotalSecond: totalSecond,
TxPerSecond: totalTx / totalSecond,
}, nil
}
...@@ -21,7 +21,7 @@ message ValNodeAction { ...@@ -21,7 +21,7 @@ message ValNodeAction {
int32 Ty = 3; int32 Ty = 3;
} }
message ReqNodeInfo { message ReqValNodes {
int64 height = 1; int64 height = 1;
} }
...@@ -29,7 +29,33 @@ message ReqBlockInfo { ...@@ -29,7 +29,33 @@ message ReqBlockInfo {
int64 height = 1; int64 height = 1;
} }
message ValNodeInfo {
string nodeIP = 1;
string nodeID = 2;
string address = 3;
string pubKey = 4;
int64 votingPower = 5;
int64 accum = 6;
}
message ValNodeInfoSet {
repeated ValNodeInfo nodes = 1;
}
message PerfStat {
int64 totalTx = 1;
int64 totalBlock = 2;
int64 txPerBlock = 3;
int64 totalSecond = 4;
int64 txPerSecond = 5;
}
message ReqPerfStat {
int64 start = 1;
int64 end = 2;
}
service valnode { service valnode {
rpc IsSync(ReqNil) returns (IsHealthy) {} rpc IsSync(ReqNil) returns (IsHealthy) {}
rpc GetNodeInfo(ReqNil) returns (ValidatorSet) {} rpc GetNodeInfo(ReqNil) returns (ValNodeInfoSet) {}
} }
\ No newline at end of file
...@@ -34,12 +34,12 @@ func (c *Jrpc) IsSync(req *types.ReqNil, result *interface{}) error { ...@@ -34,12 +34,12 @@ func (c *Jrpc) IsSync(req *types.ReqNil, result *interface{}) error {
} }
// GetNodeInfo query node info // GetNodeInfo query node info
func (c *channelClient) GetNodeInfo(ctx context.Context, req *types.ReqNil) (*vt.ValidatorSet, error) { func (c *channelClient) GetNodeInfo(ctx context.Context, req *types.ReqNil) (*vt.ValNodeInfoSet, error) {
data, err := c.QueryConsensusFunc("tendermint", "NodeInfo", &types.ReqNil{}) data, err := c.QueryConsensusFunc("tendermint", "NodeInfo", &types.ReqNil{})
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resp, ok := data.(*vt.ValidatorSet); ok { if resp, ok := data.(*vt.ValNodeInfoSet); ok {
return resp, nil return resp, nil
} }
return nil, types.ErrDecode return nil, types.ErrDecode
...@@ -51,6 +51,6 @@ func (c *Jrpc) GetNodeInfo(req *types.ReqNil, result *interface{}) error { ...@@ -51,6 +51,6 @@ func (c *Jrpc) GetNodeInfo(req *types.ReqNil, result *interface{}) error {
if err != nil { if err != nil {
return err return err
} }
*result = data.Validators *result = data
return nil return nil
} }
...@@ -63,15 +63,16 @@ func TestChannelClient_GetNodeInfo(t *testing.T) { ...@@ -63,15 +63,16 @@ func TestChannelClient_GetNodeInfo(t *testing.T) {
client := newGrpc(api) client := newGrpc(api)
client.Init("valnode", nil, nil, nil) client.Init("valnode", nil, nil, nil)
req := &types.ReqNil{} req := &types.ReqNil{}
node := &vt.Validator{ node := &vt.ValNodeInfo{
Address: []byte("aaa"), NodeIP: "127.0.0.1",
PubKey: []byte("bbb"), NodeID: "001",
Address: "aaa",
PubKey: "bbb",
VotingPower: 10, VotingPower: 10,
Accum: -1, Accum: -1,
} }
set := &vt.ValidatorSet{ set := &vt.ValNodeInfoSet{
Validators: []*vt.Validator{node}, Nodes: []*vt.ValNodeInfo{node},
Proposer: node,
} }
api.On("QueryConsensusFunc", "tendermint", "NodeInfo", req).Return(set, nil) api.On("QueryConsensusFunc", "tendermint", "NodeInfo", req).Return(set, nil)
result, err := client.GetNodeInfo(context.Background(), req) result, err := client.GetNodeInfo(context.Background(), req)
...@@ -84,18 +85,19 @@ func TestJrpc_GetNodeInfo(t *testing.T) { ...@@ -84,18 +85,19 @@ func TestJrpc_GetNodeInfo(t *testing.T) {
J := newJrpc(api) J := newJrpc(api)
req := &types.ReqNil{} req := &types.ReqNil{}
var result interface{} var result interface{}
node := &vt.Validator{ node := &vt.ValNodeInfo{
Address: []byte("aaa"), NodeIP: "127.0.0.1",
PubKey: []byte("bbb"), NodeID: "001",
Address: "aaa",
PubKey: "bbb",
VotingPower: 10, VotingPower: 10,
Accum: -1, Accum: -1,
} }
set := &vt.ValidatorSet{ set := &vt.ValNodeInfoSet{
Validators: []*vt.Validator{node}, Nodes: []*vt.ValNodeInfo{node},
Proposer: node,
} }
api.On("QueryConsensusFunc", "tendermint", "NodeInfo", req).Return(set, nil) api.On("QueryConsensusFunc", "tendermint", "NodeInfo", req).Return(set, nil)
err := J.GetNodeInfo(req, &result) err := J.GetNodeInfo(req, &result)
assert.Nil(t, err) assert.Nil(t, err)
assert.EqualValues(t, set.Validators, result) assert.EqualValues(t, set, result)
} }
...@@ -200,39 +200,39 @@ func (*ValNodeAction) XXX_OneofWrappers() []interface{} { ...@@ -200,39 +200,39 @@ func (*ValNodeAction) XXX_OneofWrappers() []interface{} {
} }
} }
type ReqNodeInfo struct { type ReqValNodes struct {
Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
} }
func (m *ReqNodeInfo) Reset() { *m = ReqNodeInfo{} } func (m *ReqValNodes) Reset() { *m = ReqValNodes{} }
func (m *ReqNodeInfo) String() string { return proto.CompactTextString(m) } func (m *ReqValNodes) String() string { return proto.CompactTextString(m) }
func (*ReqNodeInfo) ProtoMessage() {} func (*ReqValNodes) ProtoMessage() {}
func (*ReqNodeInfo) Descriptor() ([]byte, []int) { func (*ReqValNodes) Descriptor() ([]byte, []int) {
return fileDescriptor_38e9a3523ca7e0ea, []int{3} return fileDescriptor_38e9a3523ca7e0ea, []int{3}
} }
func (m *ReqNodeInfo) XXX_Unmarshal(b []byte) error { func (m *ReqValNodes) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReqNodeInfo.Unmarshal(m, b) return xxx_messageInfo_ReqValNodes.Unmarshal(m, b)
} }
func (m *ReqNodeInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { func (m *ReqValNodes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReqNodeInfo.Marshal(b, m, deterministic) return xxx_messageInfo_ReqValNodes.Marshal(b, m, deterministic)
} }
func (m *ReqNodeInfo) XXX_Merge(src proto.Message) { func (m *ReqValNodes) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReqNodeInfo.Merge(m, src) xxx_messageInfo_ReqValNodes.Merge(m, src)
} }
func (m *ReqNodeInfo) XXX_Size() int { func (m *ReqValNodes) XXX_Size() int {
return xxx_messageInfo_ReqNodeInfo.Size(m) return xxx_messageInfo_ReqValNodes.Size(m)
} }
func (m *ReqNodeInfo) XXX_DiscardUnknown() { func (m *ReqValNodes) XXX_DiscardUnknown() {
xxx_messageInfo_ReqNodeInfo.DiscardUnknown(m) xxx_messageInfo_ReqValNodes.DiscardUnknown(m)
} }
var xxx_messageInfo_ReqNodeInfo proto.InternalMessageInfo var xxx_messageInfo_ReqValNodes proto.InternalMessageInfo
func (m *ReqNodeInfo) GetHeight() int64 { func (m *ReqValNodes) GetHeight() int64 {
if m != nil { if m != nil {
return m.Height return m.Height
} }
...@@ -278,12 +278,252 @@ func (m *ReqBlockInfo) GetHeight() int64 { ...@@ -278,12 +278,252 @@ func (m *ReqBlockInfo) GetHeight() int64 {
return 0 return 0
} }
type ValNodeInfo struct {
NodeIP string `protobuf:"bytes,1,opt,name=nodeIP,proto3" json:"nodeIP,omitempty"`
NodeID string `protobuf:"bytes,2,opt,name=nodeID,proto3" json:"nodeID,omitempty"`
Address string `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"`
PubKey string `protobuf:"bytes,4,opt,name=pubKey,proto3" json:"pubKey,omitempty"`
VotingPower int64 `protobuf:"varint,5,opt,name=votingPower,proto3" json:"votingPower,omitempty"`
Accum int64 `protobuf:"varint,6,opt,name=accum,proto3" json:"accum,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ValNodeInfo) Reset() { *m = ValNodeInfo{} }
func (m *ValNodeInfo) String() string { return proto.CompactTextString(m) }
func (*ValNodeInfo) ProtoMessage() {}
func (*ValNodeInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_38e9a3523ca7e0ea, []int{5}
}
func (m *ValNodeInfo) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ValNodeInfo.Unmarshal(m, b)
}
func (m *ValNodeInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ValNodeInfo.Marshal(b, m, deterministic)
}
func (m *ValNodeInfo) XXX_Merge(src proto.Message) {
xxx_messageInfo_ValNodeInfo.Merge(m, src)
}
func (m *ValNodeInfo) XXX_Size() int {
return xxx_messageInfo_ValNodeInfo.Size(m)
}
func (m *ValNodeInfo) XXX_DiscardUnknown() {
xxx_messageInfo_ValNodeInfo.DiscardUnknown(m)
}
var xxx_messageInfo_ValNodeInfo proto.InternalMessageInfo
func (m *ValNodeInfo) GetNodeIP() string {
if m != nil {
return m.NodeIP
}
return ""
}
func (m *ValNodeInfo) GetNodeID() string {
if m != nil {
return m.NodeID
}
return ""
}
func (m *ValNodeInfo) GetAddress() string {
if m != nil {
return m.Address
}
return ""
}
func (m *ValNodeInfo) GetPubKey() string {
if m != nil {
return m.PubKey
}
return ""
}
func (m *ValNodeInfo) GetVotingPower() int64 {
if m != nil {
return m.VotingPower
}
return 0
}
func (m *ValNodeInfo) GetAccum() int64 {
if m != nil {
return m.Accum
}
return 0
}
type ValNodeInfoSet struct {
Nodes []*ValNodeInfo `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ValNodeInfoSet) Reset() { *m = ValNodeInfoSet{} }
func (m *ValNodeInfoSet) String() string { return proto.CompactTextString(m) }
func (*ValNodeInfoSet) ProtoMessage() {}
func (*ValNodeInfoSet) Descriptor() ([]byte, []int) {
return fileDescriptor_38e9a3523ca7e0ea, []int{6}
}
func (m *ValNodeInfoSet) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ValNodeInfoSet.Unmarshal(m, b)
}
func (m *ValNodeInfoSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ValNodeInfoSet.Marshal(b, m, deterministic)
}
func (m *ValNodeInfoSet) XXX_Merge(src proto.Message) {
xxx_messageInfo_ValNodeInfoSet.Merge(m, src)
}
func (m *ValNodeInfoSet) XXX_Size() int {
return xxx_messageInfo_ValNodeInfoSet.Size(m)
}
func (m *ValNodeInfoSet) XXX_DiscardUnknown() {
xxx_messageInfo_ValNodeInfoSet.DiscardUnknown(m)
}
var xxx_messageInfo_ValNodeInfoSet proto.InternalMessageInfo
func (m *ValNodeInfoSet) GetNodes() []*ValNodeInfo {
if m != nil {
return m.Nodes
}
return nil
}
type PerfStat struct {
TotalTx int64 `protobuf:"varint,1,opt,name=totalTx,proto3" json:"totalTx,omitempty"`
TotalBlock int64 `protobuf:"varint,2,opt,name=totalBlock,proto3" json:"totalBlock,omitempty"`
TxPerBlock int64 `protobuf:"varint,3,opt,name=txPerBlock,proto3" json:"txPerBlock,omitempty"`
TotalSecond int64 `protobuf:"varint,4,opt,name=totalSecond,proto3" json:"totalSecond,omitempty"`
TxPerSecond int64 `protobuf:"varint,5,opt,name=txPerSecond,proto3" json:"txPerSecond,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *PerfStat) Reset() { *m = PerfStat{} }
func (m *PerfStat) String() string { return proto.CompactTextString(m) }
func (*PerfStat) ProtoMessage() {}
func (*PerfStat) Descriptor() ([]byte, []int) {
return fileDescriptor_38e9a3523ca7e0ea, []int{7}
}
func (m *PerfStat) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PerfStat.Unmarshal(m, b)
}
func (m *PerfStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_PerfStat.Marshal(b, m, deterministic)
}
func (m *PerfStat) XXX_Merge(src proto.Message) {
xxx_messageInfo_PerfStat.Merge(m, src)
}
func (m *PerfStat) XXX_Size() int {
return xxx_messageInfo_PerfStat.Size(m)
}
func (m *PerfStat) XXX_DiscardUnknown() {
xxx_messageInfo_PerfStat.DiscardUnknown(m)
}
var xxx_messageInfo_PerfStat proto.InternalMessageInfo
func (m *PerfStat) GetTotalTx() int64 {
if m != nil {
return m.TotalTx
}
return 0
}
func (m *PerfStat) GetTotalBlock() int64 {
if m != nil {
return m.TotalBlock
}
return 0
}
func (m *PerfStat) GetTxPerBlock() int64 {
if m != nil {
return m.TxPerBlock
}
return 0
}
func (m *PerfStat) GetTotalSecond() int64 {
if m != nil {
return m.TotalSecond
}
return 0
}
func (m *PerfStat) GetTxPerSecond() int64 {
if m != nil {
return m.TxPerSecond
}
return 0
}
type ReqPerfStat struct {
Start int64 `protobuf:"varint,1,opt,name=start,proto3" json:"start,omitempty"`
End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ReqPerfStat) Reset() { *m = ReqPerfStat{} }
func (m *ReqPerfStat) String() string { return proto.CompactTextString(m) }
func (*ReqPerfStat) ProtoMessage() {}
func (*ReqPerfStat) Descriptor() ([]byte, []int) {
return fileDescriptor_38e9a3523ca7e0ea, []int{8}
}
func (m *ReqPerfStat) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReqPerfStat.Unmarshal(m, b)
}
func (m *ReqPerfStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReqPerfStat.Marshal(b, m, deterministic)
}
func (m *ReqPerfStat) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReqPerfStat.Merge(m, src)
}
func (m *ReqPerfStat) XXX_Size() int {
return xxx_messageInfo_ReqPerfStat.Size(m)
}
func (m *ReqPerfStat) XXX_DiscardUnknown() {
xxx_messageInfo_ReqPerfStat.DiscardUnknown(m)
}
var xxx_messageInfo_ReqPerfStat proto.InternalMessageInfo
func (m *ReqPerfStat) GetStart() int64 {
if m != nil {
return m.Start
}
return 0
}
func (m *ReqPerfStat) GetEnd() int64 {
if m != nil {
return m.End
}
return 0
}
func init() { func init() {
proto.RegisterType((*ValNode)(nil), "types.ValNode") proto.RegisterType((*ValNode)(nil), "types.ValNode")
proto.RegisterType((*ValNodes)(nil), "types.ValNodes") proto.RegisterType((*ValNodes)(nil), "types.ValNodes")
proto.RegisterType((*ValNodeAction)(nil), "types.ValNodeAction") proto.RegisterType((*ValNodeAction)(nil), "types.ValNodeAction")
proto.RegisterType((*ReqNodeInfo)(nil), "types.ReqNodeInfo") proto.RegisterType((*ReqValNodes)(nil), "types.ReqValNodes")
proto.RegisterType((*ReqBlockInfo)(nil), "types.ReqBlockInfo") proto.RegisterType((*ReqBlockInfo)(nil), "types.ReqBlockInfo")
proto.RegisterType((*ValNodeInfo)(nil), "types.ValNodeInfo")
proto.RegisterType((*ValNodeInfoSet)(nil), "types.ValNodeInfoSet")
proto.RegisterType((*PerfStat)(nil), "types.PerfStat")
proto.RegisterType((*ReqPerfStat)(nil), "types.ReqPerfStat")
} }
func init() { func init() {
...@@ -291,28 +531,38 @@ func init() { ...@@ -291,28 +531,38 @@ func init() {
} }
var fileDescriptor_38e9a3523ca7e0ea = []byte{ var fileDescriptor_38e9a3523ca7e0ea = []byte{
// 322 bytes of a gzipped FileDescriptorProto // 496 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x51, 0xcd, 0x6a, 0xf2, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x53, 0xd1, 0x6a, 0xdb, 0x40,
0x14, 0x4d, 0xcc, 0x97, 0xf8, 0xf5, 0x46, 0x45, 0xa6, 0x45, 0x42, 0x56, 0x61, 0xb0, 0x25, 0x50, 0x10, 0xb4, 0xac, 0xc8, 0x8e, 0x57, 0xb6, 0x31, 0x47, 0x1a, 0x84, 0x1f, 0x8a, 0x11, 0x69, 0x11,
0x90, 0xa2, 0x8b, 0x42, 0x77, 0x75, 0x53, 0xa5, 0xd0, 0xc5, 0x28, 0xdd, 0xc7, 0xe4, 0xb6, 0x06, 0x14, 0x4c, 0x71, 0x09, 0x85, 0xbc, 0x35, 0x04, 0x6a, 0x53, 0x08, 0xe6, 0x64, 0xfa, 0x2e, 0x4b,
0xe3, 0x4c, 0x4c, 0x46, 0x4b, 0x5e, 0xa1, 0x4f, 0x5d, 0x32, 0x99, 0x46, 0x68, 0xe9, 0xf2, 0xfc, 0x9b, 0x58, 0x54, 0xba, 0xb3, 0xa5, 0xb3, 0x1b, 0xfd, 0x42, 0x7f, 0xa4, 0xfd, 0xcc, 0xa2, 0xd5,
0xe5, 0x9c, 0xdc, 0x81, 0xfe, 0x29, 0xca, 0xb8, 0x48, 0x70, 0x92, 0x17, 0x42, 0x0a, 0x62, 0xcb, 0x49, 0x55, 0x1a, 0xf2, 0xa6, 0x99, 0x9d, 0xbd, 0x9b, 0xdd, 0xd1, 0xc1, 0xe8, 0x14, 0x24, 0x42,
0x2a, 0xc7, 0xd2, 0xef, 0xc5, 0x62, 0xbf, 0x17, 0xbc, 0x21, 0xfd, 0xa1, 0x44, 0x9e, 0x60, 0xb1, 0x46, 0x38, 0xdf, 0x67, 0x52, 0x49, 0x66, 0xa9, 0x62, 0x8f, 0xf9, 0x74, 0x18, 0xca, 0x34, 0x95,
0x4f, 0xb9, 0x6c, 0x18, 0x7a, 0x0f, 0xdd, 0xd7, 0x28, 0x7b, 0x11, 0x09, 0x92, 0x11, 0x38, 0xf9, 0xa2, 0x22, 0xa7, 0x13, 0x85, 0x22, 0xc2, 0x2c, 0x8d, 0x85, 0xaa, 0x18, 0xf7, 0x33, 0xf4, 0xbf,
0x71, 0xf3, 0x8c, 0x95, 0x67, 0x06, 0x66, 0xd8, 0x63, 0x1a, 0x91, 0x2b, 0xb0, 0x73, 0xf1, 0x81, 0x07, 0xc9, 0xbd, 0x8c, 0x90, 0x5d, 0x42, 0x6f, 0x7f, 0xdc, 0x7e, 0xc3, 0xc2, 0x31, 0x66, 0x86,
0x85, 0xd7, 0x09, 0xcc, 0xd0, 0x62, 0x0d, 0xa0, 0x77, 0xf0, 0x5f, 0x07, 0x4b, 0x32, 0x06, 0xbb, 0x37, 0xe4, 0x1a, 0xb1, 0x0b, 0xb0, 0xf6, 0xf2, 0x27, 0x66, 0x4e, 0x77, 0x66, 0x78, 0x26, 0xaf,
0x6e, 0x2e, 0x3d, 0x33, 0xb0, 0x42, 0x77, 0x3a, 0x98, 0xa8, 0xee, 0x89, 0xd6, 0x59, 0x23, 0xd2, 0x80, 0xfb, 0x11, 0xce, 0x75, 0x63, 0xce, 0xae, 0xc0, 0x2a, 0x6f, 0xce, 0x1d, 0x63, 0x66, 0x7a,
0x4f, 0x13, 0xfa, 0x9a, 0x7a, 0x8c, 0x65, 0x2a, 0x38, 0x19, 0xc3, 0xbf, 0x5a, 0x52, 0x7d, 0xbf, 0xf6, 0x62, 0x3c, 0xa7, 0xbb, 0xe7, 0xba, 0xce, 0xab, 0xa2, 0xfb, 0xcb, 0x80, 0x91, 0xa6, 0xbe,
0x62, 0x0b, 0x83, 0x29, 0x95, 0x3c, 0xc0, 0xc5, 0x26, 0x13, 0xf1, 0x6e, 0xc9, 0xdf, 0x84, 0xda, 0x84, 0x2a, 0x96, 0x82, 0x5d, 0xc1, 0x59, 0x59, 0xa2, 0xfb, 0x5e, 0xb4, 0x2d, 0x3b, 0x9c, 0xaa,
0xe0, 0x4e, 0x7d, 0x6d, 0x5d, 0xb7, 0xbf, 0x33, 0xff, 0x76, 0x2c, 0x0c, 0x76, 0xb6, 0x93, 0x01, 0xec, 0x06, 0x06, 0xdb, 0x44, 0x86, 0x3f, 0x56, 0xe2, 0x41, 0x92, 0x07, 0x7b, 0x31, 0xd5, 0xd2,
0x74, 0xd6, 0x95, 0x67, 0x05, 0x66, 0x68, 0xb3, 0xce, 0xba, 0x9a, 0x77, 0xc1, 0x3e, 0x45, 0xd9, 0x4d, 0x33, 0xce, 0x6d, 0xad, 0x58, 0x76, 0xf8, 0x3f, 0x39, 0x1b, 0x43, 0x77, 0x53, 0x38, 0xe6,
0x11, 0xe9, 0x35, 0xb8, 0x0c, 0x0f, 0x75, 0x8f, 0xf2, 0x8d, 0xc0, 0xd9, 0x62, 0xfa, 0xbe, 0x95, 0xcc, 0xf0, 0x2c, 0xde, 0xdd, 0x14, 0xb7, 0x7d, 0xb0, 0x4e, 0x41, 0x72, 0x44, 0xf7, 0x1d, 0xd8,
0x6a, 0x8b, 0xc5, 0x34, 0xa2, 0x37, 0xd0, 0x63, 0x78, 0x68, 0x3f, 0xfe, 0x97, 0x6f, 0xba, 0x83, 0x1c, 0x0f, 0xcd, 0x04, 0x97, 0xd0, 0xdb, 0x61, 0xfc, 0xb8, 0x53, 0xe4, 0xc5, 0xe4, 0x1a, 0xb9,
0xae, 0x3e, 0x3f, 0xb9, 0x05, 0x67, 0x59, 0xae, 0x2a, 0x1e, 0x93, 0xbe, 0x5e, 0x59, 0x17, 0xa5, 0xef, 0x61, 0xc8, 0xf1, 0xd0, 0x1c, 0xfe, 0xaa, 0xee, 0xb7, 0x01, 0xb6, 0x3e, 0xac, 0xd6, 0x95,
0x99, 0x3f, 0xd4, 0x70, 0x59, 0x2e, 0x30, 0xca, 0xe4, 0xb6, 0xa2, 0x06, 0x99, 0x81, 0xfb, 0x84, 0xde, 0x57, 0x6b, 0xd2, 0x0d, 0xb8, 0x46, 0x0d, 0x7f, 0x47, 0x83, 0xd4, 0xfc, 0x1d, 0x73, 0xa0,
0xb2, 0x9d, 0xf1, 0x23, 0x71, 0x79, 0xbe, 0x48, 0x9a, 0x44, 0x52, 0x14, 0x2b, 0x94, 0xd4, 0xd8, 0x1f, 0x44, 0x51, 0x86, 0x79, 0x4e, 0x66, 0x07, 0xbc, 0x86, 0xad, 0x54, 0xce, 0xaa, 0x0e, 0x9d,
0x38, 0xea, 0xe9, 0x66, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xce, 0xc8, 0x21, 0x55, 0xf2, 0x01, 0xca, 0x0c, 0xec, 0x93, 0x54, 0xb1, 0x78, 0x5c, 0x53, 0x36, 0x16, 0xd9, 0x69, 0x53, 0x65, 0x6e,
0x00, 0x00, 0x41, 0x18, 0x1e, 0x53, 0xa7, 0x57, 0xe5, 0x46, 0xc0, 0xbd, 0x81, 0x71, 0xcb, 0xa8, 0x8f, 0x8a,
0x79, 0xcf, 0xd3, 0x63, 0xcf, 0x63, 0x28, 0x55, 0x75, 0x82, 0x7f, 0x0c, 0x38, 0x5f, 0x63, 0xf6,
0xe0, 0xab, 0x40, 0x95, 0x96, 0x95, 0x54, 0x41, 0xb2, 0x79, 0xd2, 0xbb, 0xa8, 0x21, 0x7b, 0x0b,
0x40, 0x9f, 0xb4, 0x36, 0xfd, 0xd7, 0xb4, 0x18, 0xaa, 0x3f, 0xad, 0x31, 0xab, 0xea, 0xa6, 0xae,
0x37, 0x4c, 0x39, 0x1a, 0xa9, 0x7d, 0x0c, 0xa5, 0x88, 0x68, 0x6e, 0x93, 0xb7, 0x29, 0x52, 0x94,
0x7a, 0xad, 0xd0, 0xc3, 0xb7, 0x28, 0xf7, 0x9a, 0xf2, 0x6d, 0xcc, 0x5e, 0x80, 0x95, 0xab, 0x20,
0xab, 0x63, 0xab, 0x00, 0x9b, 0x80, 0x89, 0x22, 0xd2, 0x0e, 0xcb, 0xcf, 0x45, 0x0a, 0x7d, 0xfd,
0x8c, 0xd8, 0x07, 0xe8, 0xad, 0x72, 0xbf, 0x10, 0x21, 0x1b, 0xe9, 0x8d, 0x70, 0x3c, 0xdc, 0xc7,
0xc9, 0x74, 0xa2, 0xe1, 0x2a, 0x5f, 0x62, 0x90, 0xa8, 0x5d, 0xe1, 0x76, 0xd8, 0x35, 0xd8, 0x5f,
0x51, 0x35, 0xf1, 0xff, 0xd7, 0xf1, 0xe6, 0xe5, 0x4a, 0x7d, 0x54, 0x6e, 0x67, 0xdb, 0xa3, 0x47,
0xf8, 0xe9, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbe, 0x95, 0xc7, 0x52, 0xbc, 0x03, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
...@@ -328,7 +578,7 @@ const _ = grpc.SupportPackageIsVersion6 ...@@ -328,7 +578,7 @@ const _ = grpc.SupportPackageIsVersion6
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type ValnodeClient interface { type ValnodeClient interface {
IsSync(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*IsHealthy, error) IsSync(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*IsHealthy, error)
GetNodeInfo(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*ValidatorSet, error) GetNodeInfo(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*ValNodeInfoSet, error)
} }
type valnodeClient struct { type valnodeClient struct {
...@@ -348,8 +598,8 @@ func (c *valnodeClient) IsSync(ctx context.Context, in *types.ReqNil, opts ...gr ...@@ -348,8 +598,8 @@ func (c *valnodeClient) IsSync(ctx context.Context, in *types.ReqNil, opts ...gr
return out, nil return out, nil
} }
func (c *valnodeClient) GetNodeInfo(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*ValidatorSet, error) { func (c *valnodeClient) GetNodeInfo(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*ValNodeInfoSet, error) {
out := new(ValidatorSet) out := new(ValNodeInfoSet)
err := c.cc.Invoke(ctx, "/types.valnode/GetNodeInfo", in, out, opts...) err := c.cc.Invoke(ctx, "/types.valnode/GetNodeInfo", in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -360,7 +610,7 @@ func (c *valnodeClient) GetNodeInfo(ctx context.Context, in *types.ReqNil, opts ...@@ -360,7 +610,7 @@ func (c *valnodeClient) GetNodeInfo(ctx context.Context, in *types.ReqNil, opts
// ValnodeServer is the server API for Valnode service. // ValnodeServer is the server API for Valnode service.
type ValnodeServer interface { type ValnodeServer interface {
IsSync(context.Context, *types.ReqNil) (*IsHealthy, error) IsSync(context.Context, *types.ReqNil) (*IsHealthy, error)
GetNodeInfo(context.Context, *types.ReqNil) (*ValidatorSet, error) GetNodeInfo(context.Context, *types.ReqNil) (*ValNodeInfoSet, error)
} }
// UnimplementedValnodeServer can be embedded to have forward compatible implementations. // UnimplementedValnodeServer can be embedded to have forward compatible implementations.
...@@ -370,7 +620,7 @@ type UnimplementedValnodeServer struct { ...@@ -370,7 +620,7 @@ type UnimplementedValnodeServer struct {
func (*UnimplementedValnodeServer) IsSync(ctx context.Context, req *types.ReqNil) (*IsHealthy, error) { func (*UnimplementedValnodeServer) IsSync(ctx context.Context, req *types.ReqNil) (*IsHealthy, error) {
return nil, status.Errorf(codes.Unimplemented, "method IsSync not implemented") return nil, status.Errorf(codes.Unimplemented, "method IsSync not implemented")
} }
func (*UnimplementedValnodeServer) GetNodeInfo(ctx context.Context, req *types.ReqNil) (*ValidatorSet, error) { func (*UnimplementedValnodeServer) GetNodeInfo(ctx context.Context, req *types.ReqNil) (*ValNodeInfoSet, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetNodeInfo not implemented") return nil, status.Errorf(codes.Unimplemented, "method GetNodeInfo not implemented")
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment