tendermint/docs/specification/new-spec/blockchain_reactor.md

92 lines
2.8 KiB
Markdown
Raw Normal View History

2018-01-03 11:29:19 +01:00
# Blockchain Reactor
2018-01-04 11:52:53 -05:00
The Blockchain Reactor's high level responsibility is to enable peers who are
far behind the current state of the consensus to quickly catch up by downloading
many blocks in parallel, verifying their commits, and executing them against the
ABCI application.
Tendermint full nodes run the Blockchain Reactor as a service to provide blocks
to new nodes. New nodes run the Blockchain Reactor in "fast_sync" mode,
where they actively make requests for more blocks until they sync up.
Once caught up, they disable "fast_sync" mode, and turn on the Consensus Reactor.
2018-01-03 14:39:00 +01:00
## Message Types
```go
const (
msgTypeBlockRequest = byte(0x10)
msgTypeBlockResponse = byte(0x11)
msgTypeNoBlockResponse = byte(0x12)
msgTypeStatusResponse = byte(0x20)
msgTypeStatusRequest = byte(0x21)
)
```
```go
type bcBlockRequestMessage struct {
Height int64
}
type bcNoBlockResponseMessage struct {
Height int64
}
type bcBlockResponseMessage struct {
2018-01-04 11:52:53 -05:00
Block Block
2018-01-03 14:39:00 +01:00
}
type bcStatusRequestMessage struct {
Height int64
type bcStatusResponseMessage struct {
Height int64
}
```
2018-01-03 11:29:19 +01:00
2018-01-04 11:52:53 -05:00
## Blockchain Reactor
2018-01-03 11:29:19 +01:00
2018-01-03 14:39:00 +01:00
* coordinates the pool for syncing
* coordinates the store for persistence
* coordinates the playing of blocks towards the app using a sm.BlockExecutor
* handles switching between fastsync and consensus
* it is a p2p.BaseReactor
* starts the pool.Start() and its poolRoutine()
* registers all the concrete types and interfaces for serialisation
### poolRoutine
2018-01-03 14:39:00 +01:00
* listens to these channels:
* pool requests blocks from a specific peer by posting to requestsCh, block reactor then sends
a &bcBlockRequestMessage for a specific height
* pool signals timeout of a specific peer by posting to timeoutsCh
* switchToConsensusTicker to periodically try and switch to consensus
* trySyncTicker to periodically check if we have fallen behind and then catch-up sync
* if there aren't any new blocks available on the pool it skips syncing
* tries to sync the app by taking downloaded blocks from the pool, gives them to the app and stores
them on disk
2018-01-03 14:39:00 +01:00
* implements Receive which is called by the switch/peer
* calls AddBlock on the pool when it receives a new block from a peer
2018-01-03 11:29:19 +01:00
## Block Pool
2018-01-03 14:39:00 +01:00
* responsible for downloading blocks from peers
* makeRequestersRoutine()
* removes timeout peers
* starts new requesters by calling makeNextRequester()
* requestRoutine():
* picks a peer and sends the request, then blocks until:
* pool is stopped by listening to pool.Quit
* requester is stopped by listening to Quit
* request is redone
* we receive a block
* gotBlockCh is strange
2018-01-03 11:29:19 +01:00
## Block Store
* persists blocks to disk
2018-01-03 14:39:00 +01:00
# TODO
* How does the switch from bcR to conR happen? Does conR persist blocks to disk too?
* What is the interaction between the consensus and blockchain reactors?