mirror of
https://github.com/fluencelabs/tendermint
synced 2025-07-31 04:01:55 +00:00
lint markdown docs using a stop-words and write-good linters (#2195)
* lint docs with write-good, stop-words * remove package-lock.json * update changelog * fix wrong paragraph formatting * fix some docs formatting * fix docs format * fix abci spec format
This commit is contained in:
committed by
Anton Kaliaev
parent
8a84593c02
commit
20e35654c6
@@ -1,49 +1,48 @@
|
||||
# Consensus Reactor
|
||||
|
||||
Consensus Reactor defines a reactor for the consensus service. It contains the ConsensusState service that
|
||||
manages the state of the Tendermint consensus internal state machine.
|
||||
When Consensus Reactor is started, it starts Broadcast Routine which starts ConsensusState service.
|
||||
Furthermore, for each peer that is added to the Consensus Reactor, it creates (and manages) the known peer state
|
||||
(that is used extensively in gossip routines) and starts the following three routines for the peer p:
|
||||
Gossip Data Routine, Gossip Votes Routine and QueryMaj23Routine. Finally, Consensus Reactor is responsible
|
||||
Consensus Reactor defines a reactor for the consensus service. It contains the ConsensusState service that
|
||||
manages the state of the Tendermint consensus internal state machine.
|
||||
When Consensus Reactor is started, it starts Broadcast Routine which starts ConsensusState service.
|
||||
Furthermore, for each peer that is added to the Consensus Reactor, it creates (and manages) the known peer state
|
||||
(that is used extensively in gossip routines) and starts the following three routines for the peer p:
|
||||
Gossip Data Routine, Gossip Votes Routine and QueryMaj23Routine. Finally, Consensus Reactor is responsible
|
||||
for decoding messages received from a peer and for adequate processing of the message depending on its type and content.
|
||||
The processing normally consists of updating the known peer state and for some messages
|
||||
(`ProposalMessage`, `BlockPartMessage` and `VoteMessage`) also forwarding message to ConsensusState module
|
||||
for further processing. In the following text we specify the core functionality of those separate unit of executions
|
||||
that are part of the Consensus Reactor.
|
||||
The processing normally consists of updating the known peer state and for some messages
|
||||
(`ProposalMessage`, `BlockPartMessage` and `VoteMessage`) also forwarding message to ConsensusState module
|
||||
for further processing. In the following text we specify the core functionality of those separate unit of executions
|
||||
that are part of the Consensus Reactor.
|
||||
|
||||
## ConsensusState service
|
||||
|
||||
Consensus State handles execution of the Tendermint BFT consensus algorithm. It processes votes and proposals,
|
||||
Consensus State handles execution of the Tendermint BFT consensus algorithm. It processes votes and proposals,
|
||||
and upon reaching agreement, commits blocks to the chain and executes them against the application.
|
||||
The internal state machine receives input from peers, the internal validator and from a timer.
|
||||
|
||||
Inside Consensus State we have the following units of execution: Timeout Ticker and Receive Routine.
|
||||
Timeout Ticker is a timer that schedules timeouts conditional on the height/round/step that are processed
|
||||
by the Receive Routine.
|
||||
|
||||
Timeout Ticker is a timer that schedules timeouts conditional on the height/round/step that are processed
|
||||
by the Receive Routine.
|
||||
|
||||
### Receive Routine of the ConsensusState service
|
||||
|
||||
Receive Routine of the ConsensusState handles messages which may cause internal consensus state transitions.
|
||||
It is the only routine that updates RoundState that contains internal consensus state.
|
||||
Updates (state transitions) happen on timeouts, complete proposals, and 2/3 majorities.
|
||||
It receives messages from peers, internal validators and from Timeout Ticker
|
||||
and invokes the corresponding handlers, potentially updating the RoundState.
|
||||
The details of the protocol (together with formal proofs of correctness) implemented by the Receive Routine are
|
||||
It is the only routine that updates RoundState that contains internal consensus state.
|
||||
Updates (state transitions) happen on timeouts, complete proposals, and 2/3 majorities.
|
||||
It receives messages from peers, internal validators and from Timeout Ticker
|
||||
and invokes the corresponding handlers, potentially updating the RoundState.
|
||||
The details of the protocol (together with formal proofs of correctness) implemented by the Receive Routine are
|
||||
discussed in separate document. For understanding of this document
|
||||
it is sufficient to understand that the Receive Routine manages and updates RoundState data structure that is
|
||||
it is sufficient to understand that the Receive Routine manages and updates RoundState data structure that is
|
||||
then extensively used by the gossip routines to determine what information should be sent to peer processes.
|
||||
|
||||
## Round State
|
||||
|
||||
RoundState defines the internal consensus state. It contains height, round, round step, a current validator set,
|
||||
a proposal and proposal block for the current round, locked round and block (if some block is being locked), set of
|
||||
received votes and last commit and last validators set.
|
||||
a proposal and proposal block for the current round, locked round and block (if some block is being locked), set of
|
||||
received votes and last commit and last validators set.
|
||||
|
||||
```golang
|
||||
type RoundState struct {
|
||||
Height int64
|
||||
Height int64
|
||||
Round int
|
||||
Step RoundStepType
|
||||
Validators ValidatorSet
|
||||
@@ -54,10 +53,10 @@ type RoundState struct {
|
||||
LockedBlock Block
|
||||
LockedBlockParts PartSet
|
||||
Votes HeightVoteSet
|
||||
LastCommit VoteSet
|
||||
LastCommit VoteSet
|
||||
LastValidators ValidatorSet
|
||||
}
|
||||
```
|
||||
}
|
||||
```
|
||||
|
||||
Internally, consensus will run as a state machine with the following states:
|
||||
|
||||
@@ -82,8 +81,8 @@ type PeerRoundState struct {
|
||||
Round int // Round peer is at, -1 if unknown.
|
||||
Step RoundStepType // Step peer is at
|
||||
Proposal bool // True if peer has proposal for this round
|
||||
ProposalBlockPartsHeader PartSetHeader
|
||||
ProposalBlockParts BitArray
|
||||
ProposalBlockPartsHeader PartSetHeader
|
||||
ProposalBlockParts BitArray
|
||||
ProposalPOLRound int // Proposal's POL round. -1 if none.
|
||||
ProposalPOL BitArray // nil until ProposalPOLMessage received.
|
||||
Prevotes BitArray // All votes peer has for this round
|
||||
@@ -93,19 +92,19 @@ type PeerRoundState struct {
|
||||
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
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
## Receive method of Consensus reactor
|
||||
|
||||
The entry point of the Consensus reactor is a receive method. When a message is received from a peer p,
|
||||
normally the peer round state is updated correspondingly, and some messages
|
||||
The entry point of the Consensus reactor is a receive method. When a message is received from a peer p,
|
||||
normally the peer round state is updated correspondingly, and some messages
|
||||
are passed for further processing, for example to ConsensusState service. We now specify the processing of messages
|
||||
in the receive method of Consensus reactor for each message type. In the following message handler, `rs` and `prs` denote
|
||||
`RoundState` and `PeerRoundState`, respectively.
|
||||
|
||||
### NewRoundStepMessage handler
|
||||
### NewRoundStepMessage handler
|
||||
|
||||
```
|
||||
```
|
||||
handleMessage(msg):
|
||||
if msg is from smaller height/round/step then return
|
||||
// Just remember these values.
|
||||
@@ -116,10 +115,10 @@ handleMessage(msg):
|
||||
|
||||
Update prs with values from msg
|
||||
if prs.Height or prs.Round has been updated then
|
||||
reset Proposal related fields of the peer state
|
||||
reset Proposal related fields of the peer state
|
||||
if prs.Round has been updated and msg.Round == prsCatchupCommitRound then
|
||||
prs.Precommits = psCatchupCommit
|
||||
if prs.Height has been updated then
|
||||
if prs.Height has been updated then
|
||||
if prsHeight+1 == msg.Height && prsRound == msg.LastCommitRound then
|
||||
prs.LastCommitRound = msg.LastCommitRound
|
||||
prs.LastCommit = prs.Precommits
|
||||
@@ -128,111 +127,111 @@ handleMessage(msg):
|
||||
prs.LastCommit = nil
|
||||
}
|
||||
Reset prs.CatchupCommitRound and prs.CatchupCommit
|
||||
```
|
||||
```
|
||||
|
||||
### CommitStepMessage handler
|
||||
|
||||
```
|
||||
```
|
||||
handleMessage(msg):
|
||||
if prs.Height == msg.Height then
|
||||
if prs.Height == msg.Height then
|
||||
prs.ProposalBlockPartsHeader = msg.BlockPartsHeader
|
||||
prs.ProposalBlockParts = msg.BlockParts
|
||||
```
|
||||
```
|
||||
|
||||
### HasVoteMessage handler
|
||||
|
||||
```
|
||||
```
|
||||
handleMessage(msg):
|
||||
if prs.Height == msg.Height then
|
||||
if prs.Height == msg.Height then
|
||||
prs.setHasVote(msg.Height, msg.Round, msg.Type, msg.Index)
|
||||
```
|
||||
```
|
||||
|
||||
### VoteSetMaj23Message handler
|
||||
|
||||
```
|
||||
```
|
||||
handleMessage(msg):
|
||||
if prs.Height == msg.Height then
|
||||
Record in rs that a peer claim to have ⅔ majority for msg.BlockID
|
||||
Send VoteSetBitsMessage showing votes node has for that BlockId
|
||||
```
|
||||
Send VoteSetBitsMessage showing votes node has for that BlockId
|
||||
```
|
||||
|
||||
### ProposalMessage handler
|
||||
|
||||
```
|
||||
handleMessage(msg):
|
||||
if prs.Height != msg.Height || prs.Round != msg.Round || prs.Proposal then return
|
||||
if prs.Height != msg.Height || prs.Round != msg.Round || prs.Proposal then return
|
||||
prs.Proposal = true
|
||||
prs.ProposalBlockPartsHeader = msg.BlockPartsHeader
|
||||
prs.ProposalBlockParts = empty set
|
||||
prs.ProposalBlockParts = empty set
|
||||
prs.ProposalPOLRound = msg.POLRound
|
||||
prs.ProposalPOL = nil
|
||||
prs.ProposalPOL = nil
|
||||
Send msg through internal peerMsgQueue to ConsensusState service
|
||||
```
|
||||
```
|
||||
|
||||
### ProposalPOLMessage handler
|
||||
|
||||
```
|
||||
```
|
||||
handleMessage(msg):
|
||||
if prs.Height != msg.Height or prs.ProposalPOLRound != msg.ProposalPOLRound then return
|
||||
prs.ProposalPOL = msg.ProposalPOL
|
||||
```
|
||||
```
|
||||
|
||||
### BlockPartMessage handler
|
||||
|
||||
```
|
||||
```
|
||||
handleMessage(msg):
|
||||
if prs.Height != msg.Height || prs.Round != msg.Round then return
|
||||
Record in prs that peer has block part msg.Part.Index
|
||||
Record in prs that peer has block part msg.Part.Index
|
||||
Send msg trough internal peerMsgQueue to ConsensusState service
|
||||
```
|
||||
```
|
||||
|
||||
### VoteMessage handler
|
||||
|
||||
```
|
||||
```
|
||||
handleMessage(msg):
|
||||
Record in prs that a peer knows vote with index msg.vote.ValidatorIndex for particular height and round
|
||||
Send msg trough internal peerMsgQueue to ConsensusState service
|
||||
```
|
||||
```
|
||||
|
||||
### VoteSetBitsMessage handler
|
||||
|
||||
```
|
||||
```
|
||||
handleMessage(msg):
|
||||
Update prs for the bit-array of votes peer claims to have for the msg.BlockID
|
||||
```
|
||||
```
|
||||
|
||||
## Gossip Data Routine
|
||||
|
||||
It is used to send the following messages to the peer: `BlockPartMessage`, `ProposalMessage` and
|
||||
`ProposalPOLMessage` on the DataChannel. The gossip data routine is based on the local RoundState (`rs`)
|
||||
It is used to send the following messages to the peer: `BlockPartMessage`, `ProposalMessage` and
|
||||
`ProposalPOLMessage` on the DataChannel. The gossip data routine is based on the local RoundState (`rs`)
|
||||
and the known PeerRoundState (`prs`). The routine repeats forever the logic shown below:
|
||||
|
||||
```
|
||||
1a) if rs.ProposalBlockPartsHeader == prs.ProposalBlockPartsHeader and the peer does not have all the proposal parts then
|
||||
Part = pick a random proposal block part the peer does not have
|
||||
Send BlockPartMessage(rs.Height, rs.Round, Part) to the peer on the DataChannel
|
||||
Part = pick a random proposal block part the peer does not have
|
||||
Send BlockPartMessage(rs.Height, rs.Round, Part) to the peer on the DataChannel
|
||||
if send returns true, record that the peer knows the corresponding block Part
|
||||
Continue
|
||||
|
||||
Continue
|
||||
|
||||
1b) if (0 < prs.Height) and (prs.Height < rs.Height) then
|
||||
help peer catch up using gossipDataForCatchup function
|
||||
Continue
|
||||
|
||||
1c) if (rs.Height != prs.Height) or (rs.Round != prs.Round) then
|
||||
1c) if (rs.Height != prs.Height) or (rs.Round != prs.Round) then
|
||||
Sleep PeerGossipSleepDuration
|
||||
Continue
|
||||
Continue
|
||||
|
||||
// at this point rs.Height == prs.Height and rs.Round == prs.Round
|
||||
1d) if (rs.Proposal != nil and !prs.Proposal) then
|
||||
1d) if (rs.Proposal != nil and !prs.Proposal) then
|
||||
Send ProposalMessage(rs.Proposal) to the peer
|
||||
if send returns true, record that the peer knows Proposal
|
||||
if 0 <= rs.Proposal.POLRound then
|
||||
polRound = rs.Proposal.POLRound
|
||||
prevotesBitArray = rs.Votes.Prevotes(polRound).BitArray()
|
||||
polRound = rs.Proposal.POLRound
|
||||
prevotesBitArray = rs.Votes.Prevotes(polRound).BitArray()
|
||||
Send ProposalPOLMessage(rs.Height, polRound, prevotesBitArray)
|
||||
Continue
|
||||
Continue
|
||||
|
||||
2) Sleep PeerGossipSleepDuration
|
||||
2) Sleep PeerGossipSleepDuration
|
||||
```
|
||||
|
||||
### Gossip Data For Catchup
|
||||
@@ -240,65 +239,65 @@ and the known PeerRoundState (`prs`). The routine repeats forever the logic show
|
||||
This function is responsible for helping peer catch up if it is at the smaller height (prs.Height < rs.Height).
|
||||
The function executes the following logic:
|
||||
|
||||
if peer does not have all block parts for prs.ProposalBlockPart then
|
||||
if peer does not have all block parts for prs.ProposalBlockPart then
|
||||
blockMeta = Load Block Metadata for height prs.Height from blockStore
|
||||
if (!blockMeta.BlockID.PartsHeader == prs.ProposalBlockPartsHeader) then
|
||||
Sleep PeerGossipSleepDuration
|
||||
return
|
||||
Part = pick a random proposal block part the peer does not have
|
||||
Send BlockPartMessage(prs.Height, prs.Round, Part) to the peer on the DataChannel
|
||||
Part = pick a random proposal block part the peer does not have
|
||||
Send BlockPartMessage(prs.Height, prs.Round, Part) to the peer on the DataChannel
|
||||
if send returns true, record that the peer knows the corresponding block Part
|
||||
return
|
||||
else Sleep PeerGossipSleepDuration
|
||||
|
||||
else Sleep PeerGossipSleepDuration
|
||||
|
||||
## Gossip Votes Routine
|
||||
|
||||
It is used to send the following message: `VoteMessage` on the VoteChannel.
|
||||
The gossip votes routine is based on the local RoundState (`rs`)
|
||||
The gossip votes routine is based on the local RoundState (`rs`)
|
||||
and the known PeerRoundState (`prs`). The routine repeats forever the logic shown below:
|
||||
|
||||
```
|
||||
1a) if rs.Height == prs.Height then
|
||||
if prs.Step == RoundStepNewHeight then
|
||||
vote = random vote from rs.LastCommit the peer does not have
|
||||
Send VoteMessage(vote) to the peer
|
||||
if send returns true, continue
|
||||
|
||||
if prs.Step <= RoundStepPrevote and prs.Round != -1 and prs.Round <= rs.Round then
|
||||
Prevotes = rs.Votes.Prevotes(prs.Round)
|
||||
vote = random vote from Prevotes the peer does not have
|
||||
Send VoteMessage(vote) to the peer
|
||||
if prs.Step == RoundStepNewHeight then
|
||||
vote = random vote from rs.LastCommit the peer does not have
|
||||
Send VoteMessage(vote) to the peer
|
||||
if send returns true, continue
|
||||
|
||||
if prs.Step <= RoundStepPrecommit and prs.Round != -1 and prs.Round <= rs.Round then
|
||||
Precommits = rs.Votes.Precommits(prs.Round)
|
||||
vote = random vote from Precommits the peer does not have
|
||||
Send VoteMessage(vote) to the peer
|
||||
if prs.Step <= RoundStepPrevote and prs.Round != -1 and prs.Round <= rs.Round then
|
||||
Prevotes = rs.Votes.Prevotes(prs.Round)
|
||||
vote = random vote from Prevotes the peer does not have
|
||||
Send VoteMessage(vote) to the peer
|
||||
if send returns true, continue
|
||||
|
||||
if prs.ProposalPOLRound != -1 then
|
||||
|
||||
if prs.Step <= RoundStepPrecommit and prs.Round != -1 and prs.Round <= rs.Round then
|
||||
Precommits = rs.Votes.Precommits(prs.Round)
|
||||
vote = random vote from Precommits the peer does not have
|
||||
Send VoteMessage(vote) to the peer
|
||||
if send returns true, continue
|
||||
|
||||
if prs.ProposalPOLRound != -1 then
|
||||
PolPrevotes = rs.Votes.Prevotes(prs.ProposalPOLRound)
|
||||
vote = random vote from PolPrevotes the peer does not have
|
||||
Send VoteMessage(vote) to the peer
|
||||
if send returns true, continue
|
||||
vote = random vote from PolPrevotes the peer does not have
|
||||
Send VoteMessage(vote) to the peer
|
||||
if send returns true, continue
|
||||
|
||||
1b) if prs.Height != 0 and rs.Height == prs.Height+1 then
|
||||
vote = random vote from rs.LastCommit peer does not have
|
||||
Send VoteMessage(vote) to the peer
|
||||
if send returns true, continue
|
||||
|
||||
1c) if prs.Height != 0 and rs.Height >= prs.Height+2 then
|
||||
Commit = get commit from BlockStore for prs.Height
|
||||
vote = random vote from Commit the peer does not have
|
||||
Send VoteMessage(vote) to the peer
|
||||
vote = random vote from rs.LastCommit peer does not have
|
||||
Send VoteMessage(vote) to the peer
|
||||
if send returns true, continue
|
||||
|
||||
2) Sleep PeerGossipSleepDuration
|
||||
1c) if prs.Height != 0 and rs.Height >= prs.Height+2 then
|
||||
Commit = get commit from BlockStore for prs.Height
|
||||
vote = random vote from Commit the peer does not have
|
||||
Send VoteMessage(vote) to the peer
|
||||
if send returns true, continue
|
||||
|
||||
2) Sleep PeerGossipSleepDuration
|
||||
```
|
||||
|
||||
## QueryMaj23Routine
|
||||
|
||||
It is used to send the following message: `VoteSetMaj23Message`. `VoteSetMaj23Message` is sent to indicate that a given
|
||||
It is used to send the following message: `VoteSetMaj23Message`. `VoteSetMaj23Message` is sent to indicate that a given
|
||||
BlockID has seen +2/3 votes. This routine is based on the local RoundState (`rs`) and the known PeerRoundState
|
||||
(`prs`). The routine repeats forever the logic shown below.
|
||||
|
||||
@@ -324,8 +323,8 @@ BlockID has seen +2/3 votes. This routine is based on the local RoundState (`rs`
|
||||
Send m to peer
|
||||
Sleep PeerQueryMaj23SleepDuration
|
||||
|
||||
1d) if prs.CatchupCommitRound != -1 and 0 < prs.Height and
|
||||
prs.Height <= blockStore.Height() then
|
||||
1d) if prs.CatchupCommitRound != -1 and 0 < prs.Height and
|
||||
prs.Height <= blockStore.Height() then
|
||||
Commit = LoadCommit(prs.Height)
|
||||
m = VoteSetMaj23Message(prs.Height,Commit.Round,Precommit,Commit.blockId)
|
||||
Send m to peer
|
||||
@@ -339,14 +338,14 @@ BlockID has seen +2/3 votes. This routine is based on the local RoundState (`rs`
|
||||
The Broadcast routine subscribes to an internal event bus to receive new round steps, votes messages and proposal
|
||||
heartbeat messages, and broadcasts messages to peers upon receiving those events.
|
||||
It broadcasts `NewRoundStepMessage` or `CommitStepMessage` upon new round state event. Note that
|
||||
broadcasting these messages does not depend on the PeerRoundState; it is sent on the StateChannel.
|
||||
Upon receiving VoteMessage it broadcasts `HasVoteMessage` message to its peers on the StateChannel.
|
||||
broadcasting these messages does not depend on the PeerRoundState; it is sent on the StateChannel.
|
||||
Upon receiving VoteMessage it broadcasts `HasVoteMessage` message to its peers on the StateChannel.
|
||||
`ProposalHeartbeatMessage` is sent the same way on the StateChannel.
|
||||
|
||||
## Channels
|
||||
|
||||
Defines 4 channels: state, data, vote and vote_set_bits. Each channel
|
||||
has `SendQueueCapacity` and `RecvBufferCapacity` and
|
||||
has `SendQueueCapacity` and `RecvBufferCapacity` and
|
||||
`RecvMessageCapacity` set to `maxMsgSize`.
|
||||
|
||||
Sending incorrectly encoded data will result in stopping the peer.
|
||||
|
@@ -23,7 +23,7 @@ processes using `BlockPartMessage`.
|
||||
|
||||
Validators in Tendermint communicate by peer-to-peer gossiping protocol. Each validator is connected
|
||||
only to a subset of processes called peers. By the gossiping protocol, a validator send to its peers
|
||||
all needed information (`ProposalMessage`, `VoteMessage` and `BlockPartMessage`) so they can
|
||||
all needed information (`ProposalMessage`, `VoteMessage` and `BlockPartMessage`) so they can
|
||||
reach agreement on some block, and also obtain the content of the chosen block (block parts). As
|
||||
part of the gossiping protocol, processes also send auxiliary messages that inform peers about the
|
||||
executed steps of the core consensus algorithm (`NewRoundStepMessage` and `CommitStepMessage`), and
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# Proposer selection procedure in Tendermint
|
||||
|
||||
This document specifies the Proposer Selection Procedure that is used in Tendermint to choose a round proposer.
|
||||
This document specifies the Proposer Selection Procedure that is used in Tendermint to choose a round proposer.
|
||||
As Tendermint is “leader-based protocol”, the proposer selection is critical for its correct functioning.
|
||||
Let denote with `proposer_p(h,r)` a process returned by the Proposer Selection Procedure at the process p, at height h
|
||||
and round r. Then the Proposer Selection procedure should fulfill the following properties:
|
||||
@@ -9,13 +9,13 @@ and round r. Then the Proposer Selection procedure should fulfill the following
|
||||
p and q, for each height h, and each round r,
|
||||
proposer_p(h,r) = proposer_q(h,r)
|
||||
|
||||
`Liveness`: In every consecutive sequence of rounds of size K (K is system parameter), at least a
|
||||
single round has an honest proposer.
|
||||
`Liveness`: In every consecutive sequence of rounds of size K (K is system parameter), at least a
|
||||
single round has an honest proposer.
|
||||
|
||||
`Fairness`: The proposer selection is proportional to the validator voting power, i.e., a validator with more
|
||||
voting power is selected more frequently, proportional to its power. More precisely, given a set of processes
|
||||
with the total voting power N, during a sequence of rounds of size N, every process is proposer in a number of rounds
|
||||
equal to its voting power.
|
||||
`Fairness`: The proposer selection is proportional to the validator voting power, i.e., a validator with more
|
||||
voting power is selected more frequently, proportional to its power. More precisely, given a set of processes
|
||||
with the total voting power N, during a sequence of rounds of size N, every process is proposer in a number of rounds
|
||||
equal to its voting power.
|
||||
|
||||
We now look at a few particular cases to understand better how fairness should be implemented.
|
||||
If we have 4 processes with the following voting power distribution (p0,4), (p1, 2), (p2, 2), (p3, 2) at some round r,
|
||||
@@ -27,20 +27,20 @@ Let consider now the following scenario where a total voting power of faulty pro
|
||||
p0: (p0,3), (p1, 1), (p2, 1), (p3, 1), (p4, 1), (p5, 1), (p6, 1), (p7, 1).
|
||||
In this case the sequence of proposer selections looks like this:
|
||||
|
||||
`p0, p1, p2, p3, p0, p4, p5, p6, p7, p0, p0, p1, p2, p3, p0, p4, p5, p6, p7, p0, etc`
|
||||
`p0, p1, p2, p3, p0, p4, p5, p6, p7, p0, p0, p1, p2, p3, p0, p4, p5, p6, p7, p0, etc`
|
||||
|
||||
In this case, we see that a number of rounds coordinated by a faulty process is proportional to its voting power.
|
||||
We consider also the case where we have voting power uniformly distributed among processes, i.e., we have 10 processes
|
||||
each with voting power of 1. And let consider that there are 3 faulty processes with consecutive addresses,
|
||||
We consider also the case where we have voting power uniformly distributed among processes, i.e., we have 10 processes
|
||||
each with voting power of 1. And let consider that there are 3 faulty processes with consecutive addresses,
|
||||
for example the first 3 processes are faulty. Then the sequence looks like this:
|
||||
|
||||
`p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, etc`
|
||||
|
||||
In this case, we have 3 consecutive rounds with a faulty proposer.
|
||||
In this case, we have 3 consecutive rounds with a faulty proposer.
|
||||
One special case we consider is the case where a single honest process p0 has most of the voting power, for example:
|
||||
(p0,100), (p1, 2), (p2, 3), (p3, 4). Then the sequence of proposer selection looks like this:
|
||||
|
||||
p0, p0, p0, p0, p0, p0, p0, p0, p0, p0, p0, p0, p0, p1, p0, p0, p0, p0, p0, etc
|
||||
|
||||
This basically means that almost all rounds have the same proposer. But in this case, the process p0 has anyway enough
|
||||
This basically means that almost all rounds have the same proposer. But in this case, the process p0 has anyway enough
|
||||
voting power to decide whatever he wants, so the fact that he coordinates almost all rounds seems correct.
|
||||
|
Reference in New Issue
Block a user