mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 14:52:17 +00:00
fixes from review
This commit is contained in:
parent
a41f0d3891
commit
e9804d76cf
@ -174,6 +174,26 @@ func (hvs *HeightVoteSet) getVoteSet(round int, type_ byte) *types.VoteSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a peer claims that it has 2/3 majority for given blockKey, call this.
|
||||||
|
// NOTE: if there are too many peers, or too much peer churn,
|
||||||
|
// this can cause memory issues.
|
||||||
|
// TODO: implement ability to remove peers too
|
||||||
|
func (hvs *HeightVoteSet) SetPeerMaj23(round int, type_ byte, peerID p2p.ID, blockID types.BlockID) error {
|
||||||
|
hvs.mtx.Lock()
|
||||||
|
defer hvs.mtx.Unlock()
|
||||||
|
if !types.IsVoteTypeValid(type_) {
|
||||||
|
return fmt.Errorf("SetPeerMaj23: Invalid vote type %v", type_)
|
||||||
|
}
|
||||||
|
voteSet := hvs.getVoteSet(round, type_)
|
||||||
|
if voteSet == nil {
|
||||||
|
return nil // something we don't know about yet
|
||||||
|
}
|
||||||
|
return voteSet.SetPeerMaj23(types.P2PID(peerID), blockID)
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------
|
||||||
|
// string and json
|
||||||
|
|
||||||
func (hvs *HeightVoteSet) String() string {
|
func (hvs *HeightVoteSet) String() string {
|
||||||
return hvs.StringIndented("")
|
return hvs.StringIndented("")
|
||||||
}
|
}
|
||||||
@ -207,29 +227,20 @@ func (hvs *HeightVoteSet) StringIndented(indent string) string {
|
|||||||
indent)
|
indent)
|
||||||
}
|
}
|
||||||
|
|
||||||
// `"__xx_xx____x:46/100:0.46"`
|
|
||||||
type roundVotes struct {
|
|
||||||
Round int `json:"round"`
|
|
||||||
Prevotes []string `json:"prevotes"`
|
|
||||||
PrevotesBitArray string `json:"prevotes_bit_array"`
|
|
||||||
Precommits []string `json:"precommits"`
|
|
||||||
PrecommitsBitArray string `json:"precommits_bit_array"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (hvs *HeightVoteSet) MarshalJSON() ([]byte, error) {
|
func (hvs *HeightVoteSet) MarshalJSON() ([]byte, error) {
|
||||||
hvs.mtx.Lock()
|
hvs.mtx.Lock()
|
||||||
defer hvs.mtx.Unlock()
|
defer hvs.mtx.Unlock()
|
||||||
|
|
||||||
roundsVotes := hvs.toRoundVotes()
|
allVotes := hvs.toAllRoundVotes()
|
||||||
return cdc.MarshalJSON(roundsVotes)
|
return cdc.MarshalJSON(allVotes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hvs *HeightVoteSet) toRoundVotes() []roundVotes {
|
func (hvs *HeightVoteSet) toAllRoundVotes() []roundVotes {
|
||||||
totalRounds := hvs.round + 1
|
totalRounds := hvs.round + 1
|
||||||
roundsVotes := make([]roundVotes, totalRounds)
|
allVotes := make([]roundVotes, totalRounds)
|
||||||
// rounds 0 ~ hvs.round inclusive
|
// rounds 0 ~ hvs.round inclusive
|
||||||
for round := 0; round < totalRounds; round++ {
|
for round := 0; round < totalRounds; round++ {
|
||||||
roundsVotes[round] = roundVotes{
|
allVotes[round] = roundVotes{
|
||||||
Round: round,
|
Round: round,
|
||||||
Prevotes: hvs.roundVoteSets[round].Prevotes.VoteStrings(),
|
Prevotes: hvs.roundVoteSets[round].Prevotes.VoteStrings(),
|
||||||
PrevotesBitArray: hvs.roundVoteSets[round].Prevotes.BitArrayString(),
|
PrevotesBitArray: hvs.roundVoteSets[round].Prevotes.BitArrayString(),
|
||||||
@ -238,22 +249,13 @@ func (hvs *HeightVoteSet) toRoundVotes() []roundVotes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: all other peer catchup rounds
|
// TODO: all other peer catchup rounds
|
||||||
return roundsVotes
|
return allVotes
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a peer claims that it has 2/3 majority for given blockKey, call this.
|
type roundVotes struct {
|
||||||
// NOTE: if there are too many peers, or too much peer churn,
|
Round int `json:"round"`
|
||||||
// this can cause memory issues.
|
Prevotes []string `json:"prevotes"`
|
||||||
// TODO: implement ability to remove peers too
|
PrevotesBitArray string `json:"prevotes_bit_array"`
|
||||||
func (hvs *HeightVoteSet) SetPeerMaj23(round int, type_ byte, peerID p2p.ID, blockID types.BlockID) error {
|
Precommits []string `json:"precommits"`
|
||||||
hvs.mtx.Lock()
|
PrecommitsBitArray string `json:"precommits_bit_array"`
|
||||||
defer hvs.mtx.Unlock()
|
|
||||||
if !types.IsVoteTypeValid(type_) {
|
|
||||||
return fmt.Errorf("SetPeerMaj23: Invalid vote type %v", type_)
|
|
||||||
}
|
|
||||||
voteSet := hvs.getVoteSet(round, type_)
|
|
||||||
if voteSet == nil {
|
|
||||||
return nil // something we don't know about yet
|
|
||||||
}
|
|
||||||
return voteSet.SetPeerMaj23(types.P2PID(peerID), blockID)
|
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,7 @@ type RoundState struct {
|
|||||||
LastValidators *types.ValidatorSet `json:"last_validators"`
|
LastValidators *types.ValidatorSet `json:"last_validators"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compressed version of the RoundState for use in RPC
|
||||||
type RoundStateSimple struct {
|
type RoundStateSimple struct {
|
||||||
HeightRoundStep string `json:"height/round/step"`
|
HeightRoundStep string `json:"height/round/step"`
|
||||||
StartTime time.Time `json:"start_time"`
|
StartTime time.Time `json:"start_time"`
|
||||||
@ -88,8 +89,12 @@ type RoundStateSimple struct {
|
|||||||
Votes json.RawMessage `json:"height_vote_set"`
|
Votes json.RawMessage `json:"height_vote_set"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compress the RoundState to RoundStateSimple
|
||||||
func (rs *RoundState) RoundStateSimple() RoundStateSimple {
|
func (rs *RoundState) RoundStateSimple() RoundStateSimple {
|
||||||
votesJSON, _ := rs.Votes.MarshalJSON() // TODO err
|
votesJSON, err := rs.Votes.MarshalJSON()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
return RoundStateSimple{
|
return RoundStateSimple{
|
||||||
HeightRoundStep: fmt.Sprintf("%d/%d/%d", rs.Height, rs.Round, rs.Step),
|
HeightRoundStep: fmt.Sprintf("%d/%d/%d", rs.Height, rs.Round, rs.Step),
|
||||||
StartTime: rs.StartTime,
|
StartTime: rs.StartTime,
|
||||||
|
@ -126,6 +126,15 @@ func (c *HTTP) DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *HTTP) ConsensusState() (*ctypes.ResultConsensusState, error) {
|
||||||
|
result := new(ctypes.ResultConsensusState)
|
||||||
|
_, err := c.rpc.Call("consensus_state", map[string]interface{}{}, result)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "ConsensusState")
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *HTTP) Health() (*ctypes.ResultHealth, error) {
|
func (c *HTTP) Health() (*ctypes.ResultHealth, error) {
|
||||||
result := new(ctypes.ResultHealth)
|
result := new(ctypes.ResultHealth)
|
||||||
_, err := c.rpc.Call("health", map[string]interface{}{}, result)
|
_, err := c.rpc.Call("health", map[string]interface{}{}, result)
|
||||||
|
@ -84,6 +84,7 @@ type Client interface {
|
|||||||
type NetworkClient interface {
|
type NetworkClient interface {
|
||||||
NetInfo() (*ctypes.ResultNetInfo, error)
|
NetInfo() (*ctypes.ResultNetInfo, error)
|
||||||
DumpConsensusState() (*ctypes.ResultDumpConsensusState, error)
|
DumpConsensusState() (*ctypes.ResultDumpConsensusState, error)
|
||||||
|
ConsensusState() (*ctypes.ResultConsensusState, error)
|
||||||
Health() (*ctypes.ResultHealth, error)
|
Health() (*ctypes.ResultHealth, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +84,10 @@ func (Local) DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
|
|||||||
return core.DumpConsensusState()
|
return core.DumpConsensusState()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (Local) ConsensusState() (*ctypes.ResultConsensusState, error) {
|
||||||
|
return core.ConsensusState()
|
||||||
|
}
|
||||||
|
|
||||||
func (Local) Health() (*ctypes.ResultHealth, error) {
|
func (Local) Health() (*ctypes.ResultHealth, error) {
|
||||||
return core.Health()
|
return core.Health()
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,17 @@ func TestDumpConsensusState(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConsensusState(t *testing.T) {
|
||||||
|
for i, c := range GetClients() {
|
||||||
|
// FIXME: fix server so it doesn't panic on invalid input
|
||||||
|
nc, ok := c.(client.NetworkClient)
|
||||||
|
require.True(t, ok, "%d", i)
|
||||||
|
cons, err := nc.ConsensusState()
|
||||||
|
require.Nil(t, err, "%d: %+v", i, err)
|
||||||
|
assert.NotEmpty(t, cons.RoundState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestHealth(t *testing.T) {
|
func TestHealth(t *testing.T) {
|
||||||
for i, c := range GetClients() {
|
for i, c := range GetClients() {
|
||||||
nc, ok := c.(client.NetworkClient)
|
nc, ok := c.(client.NetworkClient)
|
||||||
|
@ -212,7 +212,48 @@ func DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
|
|||||||
return &ctypes.ResultDumpConsensusState{roundState, peerStates}, nil
|
return &ctypes.ResultDumpConsensusState{roundState, peerStates}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConsensusState returns a concise summary of the consensus state.
|
||||||
// UNSTABLE
|
// UNSTABLE
|
||||||
|
//
|
||||||
|
// ```shell
|
||||||
|
// curl 'localhost:46657/consensus_state'
|
||||||
|
// ```
|
||||||
|
//
|
||||||
|
// ```go
|
||||||
|
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
|
||||||
|
// state, err := client.ConsensusState()
|
||||||
|
// ```
|
||||||
|
//
|
||||||
|
// The above command returns JSON structured like this:
|
||||||
|
//
|
||||||
|
// ```json
|
||||||
|
//{
|
||||||
|
// "jsonrpc": "2.0",
|
||||||
|
// "id": "",
|
||||||
|
// "result": {
|
||||||
|
// "round_state": {
|
||||||
|
// "height/round/step": "9336/0/1",
|
||||||
|
// "start_time": "2018-05-14T10:25:45.72595357-04:00",
|
||||||
|
// "proposal_block_hash": "",
|
||||||
|
// "locked_block_hash": "",
|
||||||
|
// "valid_block_hash": "",
|
||||||
|
// "height_vote_set": [
|
||||||
|
// {
|
||||||
|
// "round": 0,
|
||||||
|
// "prevotes": [
|
||||||
|
// "nil-Vote"
|
||||||
|
// ],
|
||||||
|
// "prevotes_bit_array": "BA{1:_} 0/10 = 0.00",
|
||||||
|
// "precommits": [
|
||||||
|
// "nil-Vote"
|
||||||
|
// ],
|
||||||
|
// "precommits_bit_array": "BA{1:_} 0/10 = 0.00"
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//```
|
||||||
func ConsensusState() (*ctypes.ResultConsensusState, error) {
|
func ConsensusState() (*ctypes.ResultConsensusState, error) {
|
||||||
// Get self round state.
|
// Get self round state.
|
||||||
bz, err := consensusState.GetRoundStateSimpleJSON()
|
bz, err := consensusState.GetRoundStateSimpleJSON()
|
||||||
|
@ -418,6 +418,9 @@ func (voteSet *VoteSet) TwoThirdsMajority() (blockID BlockID, ok bool) {
|
|||||||
return BlockID{}, false
|
return BlockID{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
// Strings and JSON
|
||||||
|
|
||||||
func (voteSet *VoteSet) String() string {
|
func (voteSet *VoteSet) String() string {
|
||||||
if voteSet == nil {
|
if voteSet == nil {
|
||||||
return "nil-VoteSet"
|
return "nil-VoteSet"
|
||||||
@ -470,8 +473,9 @@ type VoteSetJSON struct {
|
|||||||
PeerMaj23s map[P2PID]BlockID `json:"peer_maj_23s"`
|
PeerMaj23s map[P2PID]BlockID `json:"peer_maj_23s"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the bit-array of votes including the fraction of power
|
// Return the bit-array of votes including
|
||||||
// that has voted eg. "__x_xxx_:6/20 = 0.3".
|
// the fraction of power that has voted like:
|
||||||
|
// "BA{29:xx__x__x_x___x__x_______xxx__} 856/1304 = 0.66"
|
||||||
func (voteSet *VoteSet) BitArrayString() string {
|
func (voteSet *VoteSet) BitArrayString() string {
|
||||||
voteSet.mtx.Lock()
|
voteSet.mtx.Lock()
|
||||||
defer voteSet.mtx.Unlock()
|
defer voteSet.mtx.Unlock()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user