Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: election of ValidatorSet based on VRF #74

Merged
merged 20 commits into from
May 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,672 changes: 2,105 additions & 2,567 deletions abci/types/types.pb.go

Large diffs are not rendered by default.

34 changes: 16 additions & 18 deletions abci/types/typespb_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion blockchain/v0/reactor.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ FOR_LOOP:
// NOTE: we can probably make this more efficient, but note that calling
// first.Hash() doesn't verify the tx contents, so MakePartSet() is
// currently necessary.
err := state.Validators.VerifyCommit(
err := state.Voters.VerifyCommit(
chainID, firstID, first.Height, second.LastCommit)
if err != nil {
bcR.Logger.Error("Error in validation", "err", err)
Expand Down
2 changes: 1 addition & 1 deletion blockchain/v0/reactor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ func makeBlock(privVal types.PrivValidator, height int64, state sm.State, lastCo
message := state.MakeHashMessage(0)
proof, _ := privVal.GenerateVRFProof(message)
block, _ := state.MakeBlock(height, makeTxs(height), lastCommit, nil,
types.SelectProposer(state.Validators, state.LastProofHash, height, 0).Address, 0, proof)
state.Validators.SelectProposer(state.LastProofHash, height, 0).Address, 0, proof)
return block
}

Expand Down
2 changes: 1 addition & 1 deletion blockchain/v1/reactor.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ func (bcR *BlockchainReactor) processBlock() error {
// NOTE: we can probably make this more efficient, but note that calling
// first.Hash() doesn't verify the tx contents, so MakePartSet() is
// currently necessary.
err = bcR.state.Validators.VerifyCommit(chainID, firstID, first.Height, second.LastCommit)
err = bcR.state.Voters.VerifyCommit(chainID, firstID, first.Height, second.LastCommit)
if err != nil {
bcR.Logger.Error("error during commit verification", "err", err,
"first", first.Height, "second", second.Height)
Expand Down
2 changes: 1 addition & 1 deletion blockchain/v1/reactor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ func makeBlock(privVal types.PrivValidator, height int64, state sm.State, lastCo
message := state.MakeHashMessage(0)
proof, _ := privVal.GenerateVRFProof(message)
block, _ := state.MakeBlock(height, makeTxs(height), lastCommit, nil,
types.SelectProposer(state.Validators, state.LastProofHash, height, 0).Address, 0, proof)
state.Validators.SelectProposer(state.LastProofHash, height, 0).Address, 0, proof)
return block
}

Expand Down
2 changes: 1 addition & 1 deletion blockchain/v2/processor_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (pc pContext) tmState() state.State {
}

func (pc pContext) verifyCommit(chainID string, blockID types.BlockID, height int64, commit *types.Commit) error {
return pc.state.Validators.VerifyCommit(chainID, blockID, height, commit)
return pc.state.Voters.VerifyCommit(chainID, blockID, height, commit)
}

func (pc *pContext) saveBlock(block *types.Block, blockParts *types.PartSet, seenCommit *types.Commit) {
Expand Down
2 changes: 1 addition & 1 deletion blockchain/v2/reactor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ func makeTxs(height int64) (txs []types.Tx) {
func makeBlock(privVal types.PrivValidator, height int64, state sm.State, lastCommit *types.Commit) *types.Block {
message := state.MakeHashMessage(0)
proof, _ := privVal.GenerateVRFProof(message)
proposerAddr := types.SelectProposer(state.Validators, state.LastProofHash, height, 0).Address
proposerAddr := state.Validators.SelectProposer(state.LastProofHash, height, 0).Address
block, _ := state.MakeBlock(height, makeTxs(height), lastCommit, nil, proposerAddr, 0, proof)
return block
}
Expand Down
4 changes: 2 additions & 2 deletions consensus/byzantine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ func TestByzantine(t *testing.T) {

// find proposer of current height and round from State
func findProposer(state *State) (int, *types.Validator) {
proposer := types.SelectProposer(state.Validators, state.state.LastProofHash, state.Height, state.Round)
return state.Validators.GetByAddress(proposer.PubKey.Address())
proposer := state.Validators.SelectProposer(state.state.LastProofHash, state.Height, state.Round)
return state.Voters.GetByAddress(proposer.PubKey.Address())
}

//-------------------------------
Expand Down
2 changes: 1 addition & 1 deletion consensus/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ func forceProposer(cs *State, vals []*validatorStub, index []int, height []int64
curVal = vals[theOthers(index[j])]
mustBe = false
}
if curVal.GetPubKey().Equals(types.SelectProposer(cs.Validators, currentHash, height[j], round[j]).PubKey) !=
if curVal.GetPubKey().Equals(cs.Validators.SelectProposer(currentHash, height[j], round[j]).PubKey) !=
mustBe {
allMatch = false
break
Expand Down
109 changes: 55 additions & 54 deletions consensus/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,29 @@ type Metrics struct {
// Height of the chain.
Height metrics.Gauge

// ValidatorLastSignedHeight of a validator.
ValidatorLastSignedHeight metrics.Gauge
// VoterLastSignedHeight of a voter.
VoterLastSignedHeight metrics.Gauge

// Number of rounds.
Rounds metrics.Gauge

// Number of validators.
Validators metrics.Gauge
// Total power of all validators.
ValidatorsPower metrics.Gauge
// Power of a validator.
ValidatorPower metrics.Gauge
// Amount of blocks missed by a validator.
ValidatorMissedBlocks metrics.Gauge
// Number of validators who did not sign.
MissingValidators metrics.Gauge
// Total power of the missing validators.
MissingValidatorsPower metrics.Gauge
// Number of validators who tried to double sign.
ByzantineValidators metrics.Gauge
// Total power of the byzantine validators.
ByzantineValidatorsPower metrics.Gauge
// ValidatorOrVoter: voter
// Number of voters.
Voters metrics.Gauge
// Total power of all voters.
VotersPower metrics.Gauge
// Power of a voter.
VoterPower metrics.Gauge
// Amount of blocks missed by a voter.
VoterMissedBlocks metrics.Gauge
// Number of voters who did not sign.
MissingVoters metrics.Gauge
// Total power of the missing voters.
MissingVotersPower metrics.Gauge
// Number of voters who tried to double sign.
ByzantineVoters metrics.Gauge
// Total power of the byzantine voters.
ByzantineVotersPower metrics.Gauge

// Time between this and the last block.
BlockIntervalSeconds metrics.Gauge
Expand Down Expand Up @@ -82,59 +83,59 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics {
Help: "Number of rounds.",
}, labels).With(labelsAndValues...),

Validators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Voters: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "validators",
Help: "Number of validators.",
Name: "voters",
Help: "Number of voters.",
}, labels).With(labelsAndValues...),
ValidatorLastSignedHeight: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
VoterLastSignedHeight: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "validator_last_signed_height",
Help: "Last signed height for a validator",
Name: "voter_last_signed_height",
Help: "Last signed height for a voter",
}, append(labels, "validator_address")).With(labelsAndValues...),
ValidatorMissedBlocks: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
VoterMissedBlocks: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "validator_missed_blocks",
Help: "Total missed blocks for a validator",
Name: "voter_missed_blocks",
Help: "Total missed blocks for a voter",
}, append(labels, "validator_address")).With(labelsAndValues...),
ValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
VotersPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "validators_power",
Help: "Total power of all validators.",
Name: "voters_power",
Help: "Total power of all voters.",
}, labels).With(labelsAndValues...),
ValidatorPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
VoterPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "validator_power",
Help: "Power of a validator",
Name: "voter_power",
Help: "Power of a voter",
}, append(labels, "validator_address")).With(labelsAndValues...),
MissingValidators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
MissingVoters: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "missing_validators",
Help: "Number of validators who did not sign.",
Name: "missing_voters",
Help: "Number of voters who did not sign.",
}, labels).With(labelsAndValues...),
MissingValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
MissingVotersPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "missing_validators_power",
Help: "Total power of the missing validators.",
Name: "missing_voters_power",
Help: "Total power of the missing voters.",
}, labels).With(labelsAndValues...),
ByzantineValidators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
ByzantineVoters: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "byzantine_validators",
Help: "Number of validators who tried to double sign.",
Name: "byzantine_voters",
Help: "Number of voters who tried to double sign.",
}, labels).With(labelsAndValues...),
ByzantineValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
ByzantineVotersPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "byzantine_validators_power",
Help: "Total power of the byzantine validators.",
Name: "byzantine_voters_power",
Help: "Total power of the byzantine voters.",
}, labels).With(labelsAndValues...),

BlockIntervalSeconds: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Expand Down Expand Up @@ -188,18 +189,18 @@ func NopMetrics() *Metrics {
return &Metrics{
Height: discard.NewGauge(),

ValidatorLastSignedHeight: discard.NewGauge(),
VoterLastSignedHeight: discard.NewGauge(),

Rounds: discard.NewGauge(),

Validators: discard.NewGauge(),
ValidatorsPower: discard.NewGauge(),
ValidatorPower: discard.NewGauge(),
ValidatorMissedBlocks: discard.NewGauge(),
MissingValidators: discard.NewGauge(),
MissingValidatorsPower: discard.NewGauge(),
ByzantineValidators: discard.NewGauge(),
ByzantineValidatorsPower: discard.NewGauge(),
Voters: discard.NewGauge(),
VotersPower: discard.NewGauge(),
VoterPower: discard.NewGauge(),
VoterMissedBlocks: discard.NewGauge(),
MissingVoters: discard.NewGauge(),
MissingVotersPower: discard.NewGauge(),
ByzantineVoters: discard.NewGauge(),
ByzantineVotersPower: discard.NewGauge(),

BlockIntervalSeconds: discard.NewGauge(),

Expand Down
28 changes: 14 additions & 14 deletions consensus/reactor.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,9 @@ func (conR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
case *VoteMessage:
cs := conR.conS
cs.mtx.RLock()
height, valSize, lastCommitSize := cs.Height, cs.Validators.Size(), cs.LastCommit.Size()
height, voterSize, lastCommitSize := cs.Height, cs.Voters.Size(), cs.LastCommit.Size()
cs.mtx.RUnlock()
ps.EnsureVoteBitArrays(height, valSize)
ps.EnsureVoteBitArrays(height, voterSize)
ps.EnsureVoteBitArrays(height-1, lastCommitSize)
ps.SetHasVote(msg.Vote)

Expand Down Expand Up @@ -1119,7 +1119,7 @@ func (ps *PeerState) getVoteBitArray(height int64, round int, votesType types.Si
}

// 'round': A round for which we have a +2/3 commit.
func (ps *PeerState) ensureCatchupCommitRound(height int64, round int, numValidators int) {
func (ps *PeerState) ensureCatchupCommitRound(height int64, round int, numVoters int) {
if ps.PRS.Height != height {
return
}
Expand All @@ -1143,37 +1143,37 @@ func (ps *PeerState) ensureCatchupCommitRound(height int64, round int, numValida
if round == ps.PRS.Round {
ps.PRS.CatchupCommit = ps.PRS.Precommits
} else {
ps.PRS.CatchupCommit = bits.NewBitArray(numValidators)
ps.PRS.CatchupCommit = bits.NewBitArray(numVoters)
}
}

// EnsureVoteBitArrays ensures the bit-arrays have been allocated for tracking
// what votes this peer has received.
// NOTE: It's important to make sure that numValidators actually matches
// what the node sees as the number of validators for height.
func (ps *PeerState) EnsureVoteBitArrays(height int64, numValidators int) {
// NOTE: It's important to make sure that numVoters actually matches
// what the node sees as the number of voters for height.
func (ps *PeerState) EnsureVoteBitArrays(height int64, numVoters int) {
ps.mtx.Lock()
defer ps.mtx.Unlock()
ps.ensureVoteBitArrays(height, numValidators)
ps.ensureVoteBitArrays(height, numVoters)
}

func (ps *PeerState) ensureVoteBitArrays(height int64, numValidators int) {
func (ps *PeerState) ensureVoteBitArrays(height int64, numVoters int) {
if ps.PRS.Height == height {
if ps.PRS.Prevotes == nil {
ps.PRS.Prevotes = bits.NewBitArray(numValidators)
ps.PRS.Prevotes = bits.NewBitArray(numVoters)
}
if ps.PRS.Precommits == nil {
ps.PRS.Precommits = bits.NewBitArray(numValidators)
ps.PRS.Precommits = bits.NewBitArray(numVoters)
}
if ps.PRS.CatchupCommit == nil {
ps.PRS.CatchupCommit = bits.NewBitArray(numValidators)
ps.PRS.CatchupCommit = bits.NewBitArray(numVoters)
}
if ps.PRS.ProposalPOL == nil {
ps.PRS.ProposalPOL = bits.NewBitArray(numValidators)
ps.PRS.ProposalPOL = bits.NewBitArray(numVoters)
}
} else if ps.PRS.Height == height+1 {
if ps.PRS.LastCommit == nil {
ps.PRS.LastCommit = bits.NewBitArray(numValidators)
ps.PRS.LastCommit = bits.NewBitArray(numVoters)
}
}
}
Expand Down
Loading