Browse Source

Merge remote-tracking branch 'remotes/origin/master' into zm_lite_client_algo

# Conflicts:
#	spec/consensus/light-client.md
pull/7804/head
Zarko Milosevic 5 years ago
parent
commit
8528cdb314
17 changed files with 208 additions and 107 deletions
  1. +17
    -9
      spec/README.md
  2. +5
    -1
      spec/abci/README.md
  3. +1
    -4
      spec/abci/abci.md
  4. +62
    -51
      spec/blockchain/blockchain.md
  5. +22
    -2
      spec/blockchain/encoding.md
  6. +5
    -0
      spec/blockchain/readme.md
  7. +3
    -0
      spec/blockchain/state.md
  8. +26
    -17
      spec/consensus/consensus-paper/definitions.tex
  9. +9
    -9
      spec/consensus/fork-accountability.md
  10. +5
    -0
      spec/consensus/readme.md
  11. +1
    -1
      spec/consensus/wal.md
  12. +12
    -0
      spec/p2p/config.md
  13. +5
    -0
      spec/p2p/readme.md
  14. +21
    -10
      spec/reactors/consensus/consensus-reactor.md
  15. +1
    -1
      spec/reactors/mempool/config.md
  16. +8
    -2
      spec/reactors/pex/pex.md
  17. +5
    -0
      spec/reactors/readme.md

+ 17
- 9
spec/README.md View File

@ -1,4 +1,12 @@
# Overview
---
order: 1
title: Overview
parent:
title: Tendermint Spec
order: 7
---
# Tendermint Spec
This is a markdown specification of the Tendermint blockchain.
It defines the base data structures, how they are validated,
@ -27,18 +35,18 @@ please submit them to our [bug bounty](https://tendermint.com/security)!
### P2P and Network Protocols
- [The Base P2P Layer](./p2p/): multiplex the protocols ("reactors") on authenticated and encrypted TCP connections
- [Peer Exchange (PEX)](./reactors/pex/): gossip known peer addresses so peers can find each other
- [Block Sync](./reactors/block_sync/): gossip blocks so peers can catch up quickly
- [Consensus](./reactors/consensus/): gossip votes and block parts so new blocks can be committed
- [Mempool](./reactors/mempool/): gossip transactions so they get included in blocks
- [Evidence](./reactors/evidence/): sending invalid evidence will stop the peer
- [The Base P2P Layer](./p2p/node.md): multiplex the protocols ("reactors") on authenticated and encrypted TCP connections
- [Peer Exchange (PEX)](./reactors/pex/reactor.md): gossip known peer addresses so peers can find each other
- [Block Sync](./reactors/block_sync/reactor.md): gossip blocks so peers can catch up quickly
- [Consensus](./reactors/consensus/consensus.md): gossip votes and block parts so new blocks can be committed
- [Mempool](./reactors/mempool/reactor.md): gossip transactions so they get included in blocks
- [Evidence](./reactors/evidence/reactor.md): sending invalid evidence will stop the peer
### Software
- [ABCI](./software/abci.md): Details about interactions between the
- [ABCI](./abci/README.md): Details about interactions between the
application and consensus engine over ABCI
- [Write-Ahead Log](./software/wal.md): Details about how the consensus
- [Write-Ahead Log](./consensus/wal.md): Details about how the consensus
engine preserves data and recovers from crash failures
## Overview


+ 5
- 1
spec/abci/README.md View File

@ -1,4 +1,8 @@
# Overview
---
cards: true
---
# ABCI
ABCI is the interface between Tendermint (a state-machine replication engine)
and your application (the actual state machine). It consists of a set of


+ 1
- 4
spec/abci/abci.md View File

@ -54,7 +54,7 @@ Each event has a `type` which is meant to categorize the event for a particular
`Response*` or tx. A `Response*` or tx may contain multiple events with duplicate
`type` values, where each distinct entry is meant to categorize attributes for a
particular event. Every key and value in an event's attributes must be UTF-8
encoded strings along with the even type itself.
encoded strings along with the event type itself.
Example:
@ -393,9 +393,6 @@ Commit are included in the header of the next block.
For heights > 1, it's the weighted median of the timestamps of the valid
votes in the block.LastCommit.
For height == 1, it's genesis time.
- `NumTxs (int32)`: Number of transactions in the block
- `TotalTxs (int64)`: Total number of transactions in the blockchain until
now
- `LastBlockID (BlockID)`: Hash of the previous (parent) block
- `LastCommitHash ([]byte)`: Hash of the previous block's commit
- `ValidatorsHash ([]byte)`: Hash of the validator set for this block


+ 62
- 51
spec/blockchain/blockchain.md View File

@ -29,7 +29,7 @@ type Block struct {
}
```
Note the `LastCommit` is the set of votes that committed the last block.
Note the `LastCommit` is the set of signatures of validators that committed the last block.
## Header
@ -43,8 +43,6 @@ type Header struct {
ChainID string
Height int64
Time Time
NumTxs int64
TotalTxs int64
// prev block info
LastBlockID BlockID
@ -123,18 +121,47 @@ type Data struct {
## Commit
Commit is a simple wrapper for a list of votes, with one vote for each
validator. It also contains the relevant BlockID:
Commit is a simple wrapper for a list of signatures, with one for each
validator. It also contains the relevant BlockID, height and round:
```
```go
type Commit struct {
BlockID BlockID
Precommits []Vote
Height int64
Round int
BlockID BlockID
Signatures []CommitSig
}
```
## CommitSig
`CommitSig` represents a signature of a validator, who has voted either for nil,
a particular `BlockID` or was absent. It's a part of the `Commit` and can be used
to reconstruct the vote set given the validator set.
```go
type BlockIDFlag byte
const (
// BlockIDFlagAbsent - no vote was received from a validator.
BlockIDFlagAbsent BlockIDFlag = 0x01
// BlockIDFlagCommit - voted for the Commit.BlockID.
BlockIDFlagCommit = 0x02
// BlockIDFlagNil - voted for nil.
BlockIDFlagNil = 0x03
)
type CommitSig struct {
BlockIDFlag BlockIDFlag
ValidatorAddress Address
Timestamp time.Time
Signature []byte
}
```
NOTE: this will likely change to reduce the commit size by eliminating redundant
information - see [issue #1648](https://github.com/tendermint/tendermint/issues/1648).
NOTE: `ValidatorAddress` and `Timestamp` fields may be removed in the future
(see
[ADR-25](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-025-commit.md)).
## Vote
@ -168,7 +195,7 @@ See the [signature spec](./encoding.md#key-types) for more.
EvidenceData is a simple wrapper for a list of evidence:
```go
```
type EvidenceData struct {
Evidence []Evidence
}
@ -189,6 +216,8 @@ type DuplicateVoteEvidence struct {
}
```
Votes are lexicographically sorted on `BlockID`.
See the [pubkey spec](./encoding.md#key-types) for more.
## Validation
@ -248,7 +277,7 @@ block.Header.Timestamp == MedianTime(block.LastCommit, state.LastValidators)
```
The block timestamp must be monotonic.
It must equal the weighted median of the timestamps of the valid votes in the block.LastCommit.
It must equal the weighted median of the timestamps of the valid signatures in the block.LastCommit.
Note: the timestamp of a vote must be greater by at least one millisecond than that of the
block being voted on.
@ -264,24 +293,6 @@ if block.Header.Height == 1 {
See the section on [BFT time](../consensus/bft-time.md) for more details.
### NumTxs
```go
block.Header.NumTxs == len(block.Txs.Txs)
```
Number of transactions included in the block.
### TotalTxs
```go
block.Header.TotalTxs == prevBlock.Header.TotalTxs + block.Header.NumTxs
```
The cumulative sum of all transactions included in this blockchain.
The first block has `block.Header.TotalTxs = block.Header.NumberTxs`.
### LastBlockID
LastBlockID is the previous block's BlockID:
@ -302,11 +313,12 @@ The first block has `block.Header.LastBlockID == BlockID{}`.
### LastCommitHash
```go
block.Header.LastCommitHash == MerkleRoot(block.LastCommit.Precommits)
block.Header.LastCommitHash == MerkleRoot(block.LastCommit.Signatures)
```
MerkleRoot of the votes included in the block.
These are the votes that committed the previous block.
MerkleRoot of the signatures included in the block.
These are the commit signatures of the validators that committed the previous
block.
The first block has `block.Header.LastCommitHash == []byte{}`
@ -394,11 +406,11 @@ Arbitrary length array of arbitrary length byte-arrays.
## LastCommit
The first height is an exception - it requires the LastCommit to be empty:
The first height is an exception - it requires the `LastCommit` to be empty:
```go
if block.Header.Height == 1 {
len(b.LastCommit) == 0
len(b.LastCommit) == 0
}
```
@ -406,33 +418,32 @@ Otherwise, we require:
```go
len(block.LastCommit) == len(state.LastValidators)
talliedVotingPower := 0
for i, vote := range block.LastCommit{
if vote == nil{
continue
}
vote.Type == 2
vote.Height == block.LastCommit.Height()
vote.Round == block.LastCommit.Round()
vote.BlockID == block.LastBlockID
for i, commitSig := range block.LastCommit.Signatures {
if commitSig.Absent() {
continue
}
vote.BlockID == block.LastBlockID
val := state.LastValidators[i]
vote.Verify(block.ChainID, val.PubKey) == true
val := state.LastValidators[i]
vote.Verify(block.ChainID, val.PubKey) == true
talliedVotingPower += val.VotingPower
talliedVotingPower += val.VotingPower
}
talliedVotingPower > (2/3) * TotalVotingPower(state.LastValidators)
talliedVotingPower > (2/3)*TotalVotingPower(state.LastValidators)
```
Includes one (possibly nil) vote for every current validator.
Non-nil votes must be Precommits.
All votes must be for the same height and round.
All votes must be for the previous block.
Includes one vote for every current validator.
All votes must either be for the previous block, nil or absent.
All votes must have a valid signature from the corresponding validator.
The sum total of the voting power of the validators that voted
must be greater than 2/3 of the total voting power of the complete validator set.
The number of votes in a commit is limited to 10000 (see `types.MaxVotesCount`).
### Vote
A vote is a signed message broadcast in the consensus for a particular block at a particular height and round.


+ 22
- 2
spec/blockchain/encoding.md View File

@ -62,8 +62,10 @@ You can simply use below table and concatenate Prefix || Length (of raw bytes) |
| Type | Name | Prefix | Length | Notes |
| ----------------------- | ---------------------------------- | ---------- | -------- | ----- |
| PubKeyEd25519 | tendermint/PubKeyEd25519 | 0x1624DE64 | 0x20 | |
| PubKeySr25519 | tendermint/PubKeySr25519 | 0x0DFB1005 | 0x20 | |
| PubKeySecp256k1 | tendermint/PubKeySecp256k1 | 0xEB5AE987 | 0x21 | |
| PrivKeyEd25519 | tendermint/PrivKeyEd25519 | 0xA3288910 | 0x40 | |
| PrivKeySr25519 | tendermint/PrivKeySr25519 | 0x2F82D78B | 0x20 | |
| PrivKeySecp256k1 | tendermint/PrivKeySecp256k1 | 0xE1B0F79B | 0x20 | |
| PubKeyMultisigThreshold | tendermint/PubKeyMultisigThreshold | 0x22C1F7E2 | variable | |
@ -90,6 +92,18 @@ address = SHA256(pubkey)[:20]
The signature is the raw 64-byte ED25519 signature.
#### Sr25519
TODO: pubkey
The address is the first 20-bytes of the SHA256 hash of the raw 32-byte public key:
```
address = SHA256(pubkey)[:20]
```
The signature is the raw 64-byte ED25519 signature.
#### Secp256k1
TODO: pubkey
@ -155,7 +169,9 @@ See details of SimpleProof, below.
### MakeParts
Encode an object using Amino and slice it into parts.
Tendermint uses a part size of 65536 bytes.
Tendermint uses a part size of 65536 bytes, and allows a maximum of 1601 parts
(see `types.MaxBlockPartsCount`). This corresponds to the hard-coded block size
limit of 100MB.
```go
func MakeParts(block Block) []Part
@ -288,9 +304,13 @@ func computeHashFromAunts(index, total int, leafHash []byte, innerHashes [][]byt
}
```
The number of aunts is limited to 100 (`MaxAunts`) to protect the node against DOS attacks.
This limits the tree size to 2^100 leaves, which should be sufficient for any
conceivable purpose.
### IAVL+ Tree
Because Tendermint only uses a Simple Merkle Tree, application developers are expect to use their own Merkle tree in their applications. For example, the IAVL+ Tree - an immutable self-balancing binary tree for persisting application state is used by the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk/blob/master/docs/clients/lite/specification.md)
Because Tendermint only uses a Simple Merkle Tree, application developers are expect to use their own Merkle tree in their applications. For example, the IAVL+ Tree - an immutable self-balancing binary tree for persisting application state is used by the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk/blob/ae77f0080a724b159233bd9b289b2e91c0de21b5/docs/interfaces/lite/specification.md)
## JSON


+ 5
- 0
spec/blockchain/readme.md View File

@ -0,0 +1,5 @@
---
cards: true
---
# Blockchain

+ 3
- 0
spec/blockchain/state.md View File

@ -27,6 +27,9 @@ type State struct {
}
```
Note there is a hard-coded limit of 10000 validators. This is inherited from the
limit on the number of votes in a commit.
### Result
```go


+ 26
- 17
spec/consensus/consensus-paper/definitions.tex View File

@ -4,7 +4,7 @@
We consider a system of processes that communicate by exchanging messages.
Processes can be correct or faulty, where a faulty process can behave in an
arbitrary way, i.e., Byzantine faults. We assume that each process
arbitrary way, i.e., we consider Byzantine faults. We assume that each process
has some amount of voting power (voting power of a process can be $0$).
Processes in our model are not part of a single administrative domain;
therefore we cannot enforce a direct network connectivity between all
@ -13,19 +13,30 @@ processes called peers, such that there is an indirect communication channel
between all correct processes. Communication between processes is established
using a gossip protocol \cite{Dem1987:gossip}.
Formally, we model the network communication using the \emph{partially
Formally, we model the network communication using a variant of the \emph{partially
synchronous system model}~\cite{DLS88:jacm}: in all executions of the system
there is a bound $\Delta$ and an instant GST (Global Stabilization Time) such
that all communication among correct processes after GST is reliable and
$\Delta$-timely, i.e., if a correct process $p$ sends message $m$ at time $t
\ge GST$ to correct process $q$, then $q$ will receive $m$ before $t +
\ge GST$ to a correct process $q$, then $q$ will receive $m$ before $t +
\Delta$\footnote{Note that as we do not assume direct communication channels
among all correct processes, this implies that before the message $m$
reaches $q$, it might pass through a number of correct processes that will
forward the message $m$ using gossip protocol towards $q$.}. Messages among
correct processes can be delayed, dropped or duplicated before GST.
Spoofing/impersonation attacks are assumed to be impossible at all times due to
the use of public-key cryptography. The bound $\Delta$ and GST are system
forward the message $m$ using gossip protocol towards $q$.}.
In addition to the standard \emph{partially
synchronous system model}~\cite{DLS88:jacm}, we assume an auxiliary property
that captures gossip-based nature of communication\footnote{The details of the Tendermint gossip protocol will be discussed in a separate
technical report. }:
\begin{itemize} \item \emph{Gossip communication:} If a correct process $p$
sends some message $m$ at time $t$, all correct processes will receive
$m$ before $max\{t, GST\} + \Delta$. Furthermore, if a correct process $p$
receives some message $m$ at time $t$, all correct processes will receive
$m$ before $max\{t, GST\} + \Delta$. \end{itemize}
The bound $\Delta$ and GST are system
parameters whose values are not required to be known for the safety of our
algorithm. Termination of the algorithm is guaranteed within a bounded duration
after GST. In practice, the algorithm will work correctly in the slightly
@ -37,18 +48,16 @@ lost), but consideration of the GST model simplifies the discussion.
We assume that process steps (which might include sending and receiving
messages) take zero time. Processes are equipped with clocks so they can
measure local timeouts. All protocol messages are signed, i.e., when a correct
measure local timeouts.
Spoofing/impersonation attacks are assumed to be impossible at all times due to
the use of public-key cryptography, i.e., we assume that all protocol messages contains a digital signature.
Therefore, when a correct
process $q$ receives a signed message $m$ from its peer, the process $q$ can
verify who was the original sender of the message $m$.
verify who was the original sender of the message $m$ and if the message signature is valid.
We do not explicitly state a signature verification step in the pseudo-code of the algorithm to improve readability;
we assume that only messages with the valid signature are considered at that level (and messages with invalid signatures
are dropped).
The details of the Tendermint gossip protocol will be discussed in a separate
technical report. For the sake of this paper it is sufficient to assume that
messages are being gossiped between processes and the following property holds
(in addition to the partial synchrony network assumptions):
\begin{itemize} \item \emph{Gossip communication:} If a correct process $p$
receives some message $m$ at time $t$, all correct processes will receive
$m$ before $max\{t, GST\} + \Delta$. \end{itemize}
%Messages that are being gossiped are created by the consensus layer. We can


+ 9
- 9
spec/consensus/fork-accountability.md View File

@ -187,7 +187,7 @@ Validators:
Execution:
* for the main chain F behaves nicely
* F coordinates to sign a block B that is different from the one on the main chain.
* the lite clients obtains B and trusts at as it is signed by more and 2/3 of the voting power.
* the lite clients obtains B and trusts at as it is signed by more than 2/3 of the voting power.
Consequences:
@ -251,11 +251,11 @@ Consequences:
Only in case they signed something which conflicts with the application this can be used against them. Otherwise they do not do anything incorrect.
* This case is not covered by the report https://docs.google.com/document/d/11ZhMsCj3y7zIZz4udO9l25xqb0kl7gmWqNpGVRzOeyY/edit?usp=sharing as it only assumes at most 2/3 of faulty validators.
**Q:** do we need to define a special kind of attack for the case where a validator sign arbitrarily state? It seems that detecting such attack requires different mechanism that would require as an evidence a sequence of blocks that lead to that state. This might be very tricky to implement.
**Q:** do we need to define a special kind of attack for the case where a validator sign arbitrarily state? It seems that detecting such attack requires a different mechanism that would require as an evidence a sequence of blocks that led to that state. This might be very tricky to implement.
### Back to the past
In this kind of attacks faulty validators take advantage of the fact that they did not sign messages in some of the past rounds. Due to the asynchronous network in which Tendermint operates, we cannot easily differentiate between such an attack and delayed message. This kind of attack can be used at both full nodes and lite clients.
In this kind of attack, faulty validators take advantage of the fact that they did not sign messages in some of the past rounds. Due to the asynchronous network in which Tendermint operates, we cannot easily differentiate between such an attack and delayed message. This kind of attack can be used at both full nodes and lite clients.
#### Scenario 5:
@ -271,7 +271,7 @@ Validators:
Execution:
* in a round *r* of height *h* we have C1 precommitting a value A,
* C2 precommits nil,
* C2 precommits nil,
* F does not send any message
* *q* precommits nil.
* In some round *r' > r*, F and *q* and C2 commit some other value B different from A.
@ -283,7 +283,7 @@ Consequences:
* Only a single faulty validator that previously precommited nil did equivocation, while the other 1/3 of faulty validators actually executed an attack that has exactly the same sequence of messages as part of amnesia attack. Detecting this kind of attack boil down to mechanisms for equivocation and amnesia.
**Q:** should we keep this as a separate kind of attack? It seems that equivocation, amnesia and phantom validators are the only kind of attack we need to support and this gives us security also in other cases. This would not be surprising as equivocation and amnesia are attacks that followed from the protocol and phantom attack is not really an attack to Tendermint but more to the Proof of stake module.
**Q:** should we keep this as a separate kind of attack? It seems that equivocation, amnesia and phantom validators are the only kind of attack we need to support and this gives us security also in other cases. This would not be surprising as equivocation and amnesia are attacks that followed from the protocol and phantom attack is not really an attack to Tendermint but more to the Proof of Stake module.
### Phantom validators
@ -296,19 +296,19 @@ Validators:
Execution:
* There is a fork, and there exists two different headers for height *h + k*, with different validator sets:
* There is a fork, and there exist two different headers for height *h + k*, with different validator sets:
- VS2 on the main chain
- forged header VS2', signed by F (and others)
* a lite client has a trust in a header for height *h* (and the corresponding validator set VS1).
* As part of bisection header verification, it verifies header at height *h + k* with new validator set VS2'.
* As part of bisection header verification, it verifies the header at height *h + k* with new validator set VS2'.
Consequences:
* To detect this, a node needs to see both, the forged header and the canonical header from the chain.
* If this is the case, detecting these kind of attacks is easy as it just requires verifying if processes are signing messages in heights in which they are not part of the validator set.
**Remark.** We can have phantom-validator-based attacks as a follow up of equivocation or amnesia based attack where forked state contains validators that are not part of the validator set at the main chain. In this case, they keep signing messages contributed to a forked chain (the wrong branch) although they are not part of the validator set on the main chain. This attack can also be used to attack full node during a period of time he is eclipsed.
**Remark.** We can have phantom-validator-based attacks as a follow up of equivocation or amnesia based attack where forked state contains validators that are not part of the validator set at the main chain. In this case, they keep signing messages contributed to a forked chain (the wrong branch) although they are not part of the validator set on the main chain. This attack can also be used to attack full node during a period of time it is eclipsed.
### Lunatic validator
@ -316,4 +316,4 @@ Lunatic validator agrees to sign commit messages for arbitrary application state
Note that detecting this behavior require application knowledge. Detecting this behavior can probably be done by
referring to the block before the one in which height happen.
**Q:** can we say that in this case a validator ignore to check if proposed value is valid before voting for it?
**Q:** can we say that in this case a validator declines to check if a proposed value is valid before voting for it?

+ 5
- 0
spec/consensus/readme.md View File

@ -0,0 +1,5 @@
---
cards: true
---
# Consensus

+ 1
- 1
spec/consensus/wal.md View File

@ -28,5 +28,5 @@ WAL. Then it will go to precommit, and that time it will work because the
private validator contains the `LastSignBytes` and then we’ll replay the
precommit from the WAL.
Make sure to read about [WAL corruption](https://github.com/tendermint/tendermint/blob/master/docs/tendermint-core/running-in-production.md#wal-corruptionn)
Make sure to read about [WAL corruption](https://github.com/tendermint/tendermint/blob/master/docs/tendermint-core/running-in-production.md#wal-corruption)
and recovery strategies.

+ 12
- 0
spec/p2p/config.md View File

@ -26,6 +26,10 @@ These are intended to be trusted persistent peers that can help
anchor us in the p2p network. The auto-redial uses exponential
backoff and will give up after a day of trying to connect.
But If `persistent_peers_max_dial_period` is set greater than zero,
pause between each dial to each persistent peer will not exceed `persistent_peers_max_dial_period`
during exponential backoff and we keep trying again without giving up
**Note:** If `seeds` and `persistent_peers` intersect,
the user will be warned that seeds may auto-close connections
and that the node may not be able to keep the connection persistent.
@ -36,3 +40,11 @@ and that the node may not be able to keep the connection persistent.
These are IDs of the peers that we do not add to the address book or gossip to
other peers. They stay private to us.
## Unconditional Peers
`--p2p.unconditional_peer_ids “id100000000000000000000000000000000,id200000000000000000000000000000000”`
These are IDs of the peers which are allowed to be connected by both inbound or outbound regardless of
`max_num_inbound_peers` or `max_num_outbound_peers` of user's node reached or not.

+ 5
- 0
spec/p2p/readme.md View File

@ -0,0 +1,5 @@
---
cards: true
---
# P2P

+ 21
- 10
spec/reactors/consensus/consensus-reactor.md View File

@ -40,7 +40,7 @@ RoundState defines the internal consensus state. It contains height, round, roun
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
```go
type RoundState struct {
Height int64
Round int
@ -96,11 +96,13 @@ type PeerRoundState struct {
## 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
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.
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
@ -134,13 +136,16 @@ handleMessage(msg):
```
handleMessage(msg):
if prs.Height != msg.Height then return
if prs.Round != msg.Round && !msg.IsCommit then return
prs.ProposalBlockPartsHeader = msg.BlockPartsHeader
prs.ProposalBlockParts = msg.BlockParts
```
The number of block parts is limited to 1601 (`types.MaxBlockPartsCount`) to
protect the node against DOS attacks.
### HasVoteMessage handler
```
@ -179,6 +184,9 @@ handleMessage(msg):
prs.ProposalPOL = msg.ProposalPOL
```
The number of votes is limited to 10000 (`types.MaxVotesCount`) to protect the
node against DOS attacks.
### BlockPartMessage handler
```
@ -203,6 +211,9 @@ handleMessage(msg):
Update prs for the bit-array of votes peer claims to have for the msg.BlockID
```
The number of votes is limited to 10000 (`types.MaxVotesCount`) to protect the
node against DOS attacks.
## Gossip Data Routine
It is used to send the following messages to the peer: `BlockPartMessage`, `ProposalMessage` and
@ -329,7 +340,7 @@ BlockID has seen +2/3 votes. This routine is based on the local RoundState (`rs`
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)
m = VoteSetMaj23Message(prs.Height,Commit.Round,Precommit,Commit.BlockID)
Send m to peer
Sleep PeerQueryMaj23SleepDuration
@ -338,7 +349,7 @@ BlockID has seen +2/3 votes. This routine is based on the local RoundState (`rs`
## Broadcast routine
The Broadcast routine subscribes to an internal event bus to receive new round steps and votes messages, and broadcasts messages to peers upon receiving those
The Broadcast routine subscribes to an internal event bus to receive new round steps and votes 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.


+ 1
- 1
spec/reactors/mempool/config.md View File

@ -51,4 +51,4 @@ If the directory passed in is an absolute path, the wal file is
created there. If the directory is a relative path, the path is
appended to home directory of the tendermint process to
generate an absolute path to the wal directory
(default `$HOME/.tendermint` or set via `TM_HOME` or `--home``)
(default `$HOME/.tendermint` or set via `TM_HOME` or `--home`)

+ 8
- 2
spec/reactors/pex/pex.md View File

@ -31,7 +31,12 @@ On startup, we will also immediately dial the given list of `persistent_peers`,
and will attempt to maintain persistent connections with them. If the
connections die, or we fail to dial, we will redial every 5s for a few minutes,
then switch to an exponential backoff schedule, and after about a day of
trying, stop dialing the peer.
trying, stop dialing the peer. This behavior is when `persistent_peers_max_dial_period` is configured to zero.
But If `persistent_peers_max_dial_period` is set greater than zero, terms between each dial to each persistent peer
will not exceed `persistent_peers_max_dial_period` during exponential backoff.
Therefore, `dial_period` = min(`persistent_peers_max_dial_period`, `exponential_backoff_dial_period`)
and we keep trying again regardless of `maxAttemptsToDial`
As long as we have less than `MaxNumOutboundPeers`, we periodically request
additional peers from each of our own and try seeds.
@ -93,7 +98,8 @@ the selection process happens every `ensurePeersPeriod`, we might not end up
dialing a peer for much longer than the backoff duration.
If we fail to connect to the peer after 16 tries (with exponential backoff), we
remove from address book completely.
remove from address book completely. But for persistent peers, we indefinitely try to
dial all persistent peers unless `persistent_peers_max_dial_period` is configured to zero
## Select Peers to Exchange


+ 5
- 0
spec/reactors/readme.md View File

@ -0,0 +1,5 @@
---
cards: true
---
# Reactors

Loading…
Cancel
Save