mirror of
https://github.com/tendermint/tendermint.git
synced 2026-01-08 14:21:14 +00:00
docs: cleanup (#5252)
This commit is contained in:
@@ -1,16 +1,18 @@
|
||||
# Tendermint Architectural Overview
|
||||
|
||||
|
||||
> **November 2019**
|
||||
|
||||
Over the next few weeks, @brapse, @marbar3778 and I (@tessr) are having a series of meetings to go over the architecture of Tendermint Core. These are my notes from these meetings, which will either serve as an artifact for onboarding future engineers; or will provide the basis for such a document.
|
||||
|
||||
## Communication
|
||||
|
||||
There are three forms of communication (e.g., requests, responses, connections) that can happen in Tendermint Core: *internode communication*, *intranode communication*, and *client communication*.
|
||||
There are three forms of communication (e.g., requests, responses, connections) that can happen in Tendermint Core: *internode communication*, *intranode communication*, and *client communication*.
|
||||
|
||||
- Internode communication: Happens between a node and other peers. This kind of communication happens over TCP or HTTP. More on this below.
|
||||
- Intranode communication: Happens within the node itself (i.e., between reactors or other components). These are typically function or method calls, or occasionally happen through an event bus.
|
||||
- Client communiation: Happens between a client (like a wallet or a browser) and a node on the network.
|
||||
- Internode communication: Happens between a node and other peers. This kind of communication happens over TCP or HTTP. More on this below.
|
||||
- Intranode communication: Happens within the node itself (i.e., between reactors or other components). These are typically function or method calls, or occasionally happen through an event bus.
|
||||
|
||||
- Client communication: Happens between a client (like a wallet or a browser) and a node on the network.
|
||||
|
||||
### Internode Communication
|
||||
|
||||
@@ -19,17 +21,17 @@ Internode communication can happen in two ways:
|
||||
1. TCP connections through the p2p package
|
||||
- Most common form of internode communication
|
||||
- Connections between nodes are persisted and shared across reactors, facilitated by the switch. (More on the switch below.)
|
||||
2. RPC over HTTP
|
||||
2. RPC over HTTP
|
||||
- Reserved for short-lived, one-off requests
|
||||
- Example: reactor-specific state, like height
|
||||
- Also possible: websocks connected to channels for notifications (like new transactions)
|
||||
- Also possible: web-sockets connected to channels for notifications (like new transactions)
|
||||
|
||||
### P2P Business (the Switch, the PEX, and the Address Book)
|
||||
|
||||
When writing a p2p service, there are two primary responsibilities:
|
||||
|
||||
1. Routing: Who gets which messages?
|
||||
2. Peer management: Who can you talk to? What is their state? And how can you do peer discovery?
|
||||
2. Peer management: Who can you talk to? What is their state? And how can you do peer discovery?
|
||||
|
||||
The first responsibility is handled by the Switch:
|
||||
|
||||
@@ -37,15 +39,15 @@ The first responsibility is handled by the Switch:
|
||||
- Notably _only handles TCP connections_; RPC/HTTP is separate
|
||||
- Is a dependency for every reactor; all reactors expose a function `setSwitch`
|
||||
- Holds onto channels (channels on the TCP connection--NOT Go channels) and uses them to route
|
||||
- Is a global object, with a global namespace for messages
|
||||
- Is a global object, with a global namespace for messages
|
||||
- Similar functionality to libp2p
|
||||
|
||||
TODO: More information (maybe) on the implementation of the Switch.
|
||||
TODO: More information (maybe) on the implementation of the Switch.
|
||||
|
||||
The second responsibility is handled by a combination of the PEX and the Address Book.
|
||||
The second responsibility is handled by a combination of the PEX and the Address Book.
|
||||
|
||||
TODO: What is the PEX and the Address Book?
|
||||
|
||||
TODO: What is the PEX and the Address Book?
|
||||
|
||||
#### The Nature of TCP, and Introduction to the `mconnection`
|
||||
|
||||
Here are some relevant facts about TCP:
|
||||
@@ -60,50 +62,51 @@ In order to have performant TCP connections under the conditions created in Ten
|
||||
|
||||
The `mconnection` is represented by a struct, which contains a batch of messages, read and write buffers, and a map of channel IDs to reactors. It communicates with TCP via file descriptors, which it can write to. There is one `mconnection` per peer connection.
|
||||
|
||||
The `mconnection` has two methods: `send`, which takes a raw handle to the socket and writes to it; and `trySend`, which writes to a different buffer. (TODO: which buffer?)
|
||||
The `mconnection` has two methods: `send`, which takes a raw handle to the socket and writes to it; and `trySend`, which writes to a different buffer. (TODO: which buffer?)
|
||||
|
||||
The `mconnection` is owned by a peer, which is owned (potentially with many other peers) by a (global) transport, which is owned by the (global) switch:
|
||||
The `mconnection` is owned by a peer, which is owned (potentially with many other peers) by a (global) transport, which is owned by the (global) switch:
|
||||
|
||||
<!-- markdownlint-disable -->
|
||||
```
|
||||
switch
|
||||
transport
|
||||
peer
|
||||
mconnection
|
||||
peer
|
||||
mconnection
|
||||
peer
|
||||
mconnection
|
||||
transport
|
||||
peer
|
||||
mconnection
|
||||
peer
|
||||
mconnection
|
||||
peer
|
||||
mconnection
|
||||
```
|
||||
<!-- markdownlint-restore -->
|
||||
|
||||
## node.go
|
||||
## node.go
|
||||
|
||||
node.go is the entrypoint for running a node. It sets up reactors, sets up the switch, and registers all the RPC endpoints for a node.
|
||||
|
||||
## Types of Nodes
|
||||
|
||||
1. Validator Node:
|
||||
|
||||
1. Validator Node:
|
||||
2. Full Node:
|
||||
3. Seed Node:
|
||||
|
||||
TODO: Flesh out the differences between the types of nodes and how they're configured.
|
||||
TODO: Flesh out the differences between the types of nodes and how they're configured.
|
||||
|
||||
## Reactors
|
||||
## Reactors
|
||||
|
||||
Here are some Reactor Facts:
|
||||
Here are some Reactor Facts:
|
||||
|
||||
- Every reactor holds a pointer to the global switch (set through `SetSwitch()`)
|
||||
- The switch holds a pointer to every reactor (`addReactor()`)
|
||||
- Every reactor gets set up in node.go (and if you are using custom reactors, this is where you specify that)
|
||||
- `addReactor` is called by the switch; `addReactor` calls `setSwitch` for that reactor
|
||||
- There's an assumption that all the reactors are added before
|
||||
- `addReactor` is called by the switch; `addReactor` calls `setSwitch` for that reactor
|
||||
- There's an assumption that all the reactors are added before
|
||||
- Sometimes reactors talk to each other by fetching references to one another via the switch (which maintains a pointer to each reactor). **Question: Can reactors talk to each other in any other way?**
|
||||
|
||||
Furthermore, all reactors expose:
|
||||
|
||||
1. A TCP channel
|
||||
2. A `receive` method
|
||||
2. A `receive` method
|
||||
3. An `addReactor` call
|
||||
|
||||
The `receive` method can be called many times by the mconnection. It has the same signature across all reactors.
|
||||
@@ -113,16 +116,17 @@ The `addReactor` call does a for loop over all the channels on the reactor and c
|
||||
The following is an exhaustive (?) list of reactors:
|
||||
|
||||
- Blockchain Reactor
|
||||
- Consensus Reactor
|
||||
- Evidence Reactor
|
||||
- Consensus Reactor
|
||||
- Evidence Reactor
|
||||
- Mempool Reactor
|
||||
- PEX Reactor
|
||||
|
||||
Each of these will be discussed in more detail later.
|
||||
|
||||
### Blockchain Reactor
|
||||
|
||||
The blockchain reactor has two responsibilities:
|
||||
### Blockchain Reactor
|
||||
|
||||
1. Serve blocks at the request of peers
|
||||
2. TODO: learn about the second responsibility of the blockchain reactor
|
||||
The blockchain reactor has two responsibilities:
|
||||
|
||||
1. Serve blocks at the request of peers
|
||||
2. TODO: learn about the second responsibility of the blockchain reactor
|
||||
|
||||
@@ -13,10 +13,9 @@ To download pre-built binaries, see the [releases page](https://github.com/tende
|
||||
You'll need `go` [installed](https://golang.org/doc/install) and the required
|
||||
environment variables set, which can be done with the following commands:
|
||||
|
||||
```bash
|
||||
```sh
|
||||
echo export GOPATH=\"\$HOME/go\" >> ~/.bash_profile
|
||||
echo export PATH=\"\$PATH:\$GOPATH/bin\" >> ~/.bash_profile
|
||||
echo export GO111MODULE=on >> ~/.bash_profile
|
||||
```
|
||||
|
||||
### Get Source Code
|
||||
|
||||
@@ -16,7 +16,7 @@ works and want to get started right away, continue.
|
||||
To quickly get Tendermint installed on a fresh
|
||||
Ubuntu 16.04 machine, use [this script](https://git.io/fFfOR).
|
||||
|
||||
WARNING: do not run this on your local machine.
|
||||
> :warning: Do not copy scripts to run on your machine without knowing what they do.
|
||||
|
||||
```sh
|
||||
curl -L https://git.io/fFfOR | bash
|
||||
@@ -62,6 +62,8 @@ Start tendermint with a simple in-process application:
|
||||
tendermint node --proxy_app=kvstore
|
||||
```
|
||||
|
||||
> Note: `kvstore` is a non persistent app, if you would like to run an application with persistence run `--proxy_app=persistent_kvstore`
|
||||
|
||||
and blocks will start to stream in:
|
||||
|
||||
```sh
|
||||
|
||||
@@ -299,8 +299,8 @@ introduces a few **locking** rules which modulate which paths can be
|
||||
followed in the flow diagram. Once a validator precommits a block, it is
|
||||
locked on that block. Then,
|
||||
|
||||
1. it must prevote for the block it is locked on
|
||||
2. it can only unlock, and precommit for a new block, if there is a
|
||||
1. it must prevote for the block it is locked on
|
||||
2. it can only unlock, and precommit for a new block, if there is a
|
||||
polka for that block in a later round
|
||||
|
||||
## Stake
|
||||
|
||||
Reference in New Issue
Block a user