Consensus Protocol
The consensus protocol implements the avalanche consensus algorithm.
Protocol ID
/ilx/<network>/consensus/1.0.0
Where <network>
is either mainnet
, testnet
, or regtest
depending on which
network is being used.
Network Messages
enum ErrorResponse {
None = 0;
NotFound = 1;
BadRequest = 2;
NotCurrent = 3;
}
message MsgConsensusRequest {
oneof msg {
MsgPollRequest poll_request = 1;
GetBlockReq get_block = 2;
}
}
message MsgPollRequest {
uint32 request_ID = 1;
repeated uint32 heights = 2;
}
message MsgPollResponse {
uint32 request_ID = 1;
repeated bytes votes = 2;
}
message GetBlockReq {
bytes block_ID = 1;
}
message MsgBlockResp {
Block block = 1;
ErrorResponse error = 2;
}
Protocol
- When a new block comes off the wire a node checks it against its local policy. If the block passes the local policy
check then it is marked as
Acceptable
, otherwiseUnacceptable
. - If an
Acceptable
block gets passed into the consensus engine it is assigned a preference ofPreferred
if there are no other preferred blocks.Unacceptable
blocks start asNotPreferred
. - If a new block conflicts (same height) with another block that is
Preferred
the new block preference is set toNot Preferred
. - Once per millisecond the consensus engine select a random peer to query from the validator set, weighted by the percentage of
total stake that validator has, and sends a
MsgAvaRequest
to that peer requesting a vote on a block height. The peer responds with the ID of the block it prefers at that height. - We rate limit the number of inflight requests go out at any one time to the number of responses remaining needed to finalize the block. If the next 1 millisecond step occurs before any of the outstanding requests return, the step is skipped.
- When the
MsgAvaResponse
returns the votes are processed.- We record a
Yes
vote for the block ID in the response and aNo
vote for all other block IDs. - If
>12
out of the last16
recorded votes for a block areYes
then we consider the vote conclusive. - If
>12
out of the last16
recorded votes for a block areNo
then we consider the vote conclusive. - Unknown or unacceptable votes (zero ID) are included in the last 16 votes. They will prevent a block vote from being conclusive if there are enough of them.
- If the vote is conclusive, and it agrees with our current state, either
Preferred
orNot Preferred
, then we increment a confidence counter by 1.- If the confidence counter is >=
160
and the current state isPreferred
, then we mark the block asFinalized
and mark all conflicting blocks asRejected
. - If the confidence counter is >=
160
and the current state isNot Preferred
, then we do nothing. Eventually a conflicting block will finalize resulting in this one being marked asRejected
.
- If the confidence counter is >=
- If the vote is conclusive, and it does not agree with our current state, either
Preferred
orNot Preferred
, then we flip our current preference and reset our confidence counter to zero.- If the preference flipped from
Not Preferred
toPreferred
then all conflicting blocks must also flip toNotPreferred
by virtue of the same number ofNo
votes having been cast for them. - If the preference flipped from
Preferred
toNotPreferred
and we have no other preferred blocks. We selected a newPreferred
block from the list ofAcceptable
blocks. If no blocks areAcceptable
then have no preference and respond toMsgAvaRequest
s with a zero ID.
- If the preference flipped from
- We record a
- Simultaneously we work to finalize the leading bits of the block ID.
- We start with the most significant bit (MSB). When a block ID vote is recorded we examine the MSB of the block ID.
- If the MSB is a 0 we record a
Zero
vote for the MSB. - If the MSB is a 1 we record a
One
vote for the MSB. - Unknown or unacceptable votes (zero ID) are included in the last 16 votes. They will prevent a bit vote from being conclusive if there are enough of them.
- If
>12
out of the last16
bit votes are the same we consider the vote conclusive.- We increment the confidence counter for that bit.
- If the current
Preferred
block does not start with the same MSB we flip our preference to a different block that does match the preferred MSB.
- If the confidence counter is >=
160
we consider the MSB finalized and repeat the process for the remaining bits.
- If the MSB is a 0 we record a
- We start with the most significant bit (MSB). When a block ID vote is recorded we examine the MSB of the block ID.
In situations where there are more than two conflicting blocks at the same height, the bit finalization helps to coordinate preferences by reducing the candidate set until a block eventually finalizes.