Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 90797ce

Browse files
authoredMay 5, 2020
Revert "document state sync ABCI interface and P2P protocol (celestiaorg#90)" (celestiaorg#92)
This reverts commit 9842b4b.
1 parent 9842b4b commit 90797ce

File tree

4 files changed

+9
-353
lines changed

4 files changed

+9
-353
lines changed
 

‎spec/abci/abci.md

+7-124
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,17 @@
55
The ABCI message types are defined in a [protobuf
66
file](https://github.com/tendermint/tendermint/blob/master/abci/types/types.proto).
77

8-
ABCI methods are split across four separate ABCI _connections_:
8+
ABCI methods are split across 3 separate ABCI _connections_:
99

10-
- Consensus connection: `InitChain`, `BeginBlock`, `DeliverTx`, `EndBlock`, `Commit`
11-
- Mempool connection: `CheckTx`
12-
- Info connection: `Info`, `SetOption`, `Query`
13-
- Snapshot connection: `ListSnapshots`, `LoadSnapshotChunk`, `OfferSnapshot`, `ApplySnapshotChunk`
10+
- `Consensus Connection`: `InitChain, BeginBlock, DeliverTx, EndBlock, Commit`
11+
- `Mempool Connection`: `CheckTx`
12+
- `Info Connection`: `Info, SetOption, Query`
1413

15-
The consensus connection is driven by a consensus protocol and is responsible
14+
The `Consensus Connection` is driven by a consensus protocol and is responsible
1615
for block execution.
17-
18-
The mempool connection is for validating new transactions, before they're
16+
The `Mempool Connection` is for validating new transactions, before they're
1917
shared or included in a block.
20-
21-
The info connection is for initialization and for queries from the user.
22-
23-
The snapshot connection is for serving and restoring [state sync snapshots](apps.md#state-sync).
18+
The `Info Connection` is for initialization and for queries from the user.
2419

2520
Additionally, there is a `Flush` method that is called on every connection,
2621
and an `Echo` method that is just for debugging.
@@ -156,22 +151,6 @@ The result is an updated application state.
156151
Cryptographic commitments to the results of DeliverTx, EndBlock, and
157152
Commit are included in the header of the next block.
158153

159-
## State Sync
160-
161-
State sync allows new nodes to rapidly bootstrap by discovering, fetching, and applying
162-
state machine snapshots instead of replaying historical blocks. For more details, see the
163-
[state sync section](apps.md#state-sync).
164-
165-
When a new node is discovering snapshots in the P2P network, existing nodes will call
166-
`ListSnapshots` on the application to retrieve any local state snapshots. The new node will
167-
offer these snapshots to its local application via `OfferSnapshot`.
168-
169-
Once the application accepts a snapshot and begins restoring it, Tendermint will fetch snapshot
170-
chunks from existing nodes via `LoadSnapshotChunk` and apply them sequentially to the local
171-
application with `ApplySnapshotChunk`. When all chunks have been applied, the application
172-
`AppHash` is retrieved via an `Info` query and compared to the blockchain's `AppHash` verified
173-
via light client.
174-
175154
## Messages
176155

177156
### Echo
@@ -409,83 +388,6 @@ via light client.
409388
other purposes, e.g. auditing, replay of non-persisted heights, light client
410389
verification, and so on.
411390

412-
### ListSnapshots
413-
414-
- **Response**:
415-
- `Snapshots ([]Snapshot)`: List of local state snapshots.
416-
- **Usage**:
417-
- Used during state sync to discover available snapshots on peers.
418-
- See `Snapshot` data type for details.
419-
420-
### LoadSnapshotChunk
421-
422-
- **Request**:
423-
- `Height (uint64)`: The height of the snapshot the chunks belongs to.
424-
- `Format (uint32)`: The application-specific format of the snapshot the chunk belongs to.
425-
- `Chunk (uint32)`: The chunk index, starting from `0` for the initial chunk.
426-
- **Response**:
427-
- `Chunk ([]byte)`: The binary chunk contents, in an arbitray format. Chunk messages cannot be
428-
larger than 16 MB _including metadata_, so 10 MB is a good starting point.
429-
- **Usage**:
430-
- Used during state sync to retrieve snapshot chunks from peers.
431-
432-
### OfferSnapshot
433-
434-
- **Request**:
435-
- `Snapshot (Snapshot)`: The snapshot offered for restoration.
436-
- `AppHash ([]byte)`: The light client-verified app hash for this height, from the blockchain.
437-
- **Response**:
438-
- `Result (Result)`: The result of the snapshot offer.
439-
- `accept`: Snapshot is accepted, start applying chunks.
440-
- `abort`: Abort snapshot restoration, and don't try any other snapshots.
441-
- `reject`: Reject this specific snapshot, try others.
442-
- `reject_format`: Reject all snapshots with this `format`, try others.
443-
- `reject_senders`: Reject all snapshots from all senders of this snapshot, try others.
444-
- **Usage**:
445-
- `OfferSnapshot` is called when bootstrapping a node using state sync. The application may
446-
accept or reject snapshots as appropriate. Upon accepting, Tendermint will retrieve and
447-
apply snapshot chunks via `ApplySnapshotChunk`. The application may also choose to reject a
448-
snapshot in the chunk response, in which case it should be prepared to accept further
449-
`OfferSnapshot` calls.
450-
- Only `AppHash` can be trusted, as it has been verified by the light client. Any other data
451-
can be spoofed by adversaries, so applications should employ additional verification schemes
452-
to avoid denial-of-service attacks. The verified `AppHash` is automatically checked against
453-
the restored application at the end of snapshot restoration.
454-
- For more information, see the `Snapshot` data type or the [state sync section](apps.md#state-sync).
455-
456-
### ApplySnapshotChunk
457-
458-
- **Request**:
459-
- `Index (uint32)`: The chunk index, starting from `0`. Tendermint applies chunks sequentially.
460-
- `Chunk ([]byte)`: The binary chunk contents, as returned by `LoadSnapshotChunk`.
461-
- `Sender (string)`: The P2P ID of the node who sent this chunk.
462-
- **Response**:
463-
- `Result (Result)`: The result of applying this chunk.
464-
- `accept`: The chunk was accepted.
465-
- `abort`: Abort snapshot restoration, and don't try any other snapshots.
466-
- `retry`: Reapply this chunk, combine with `RefetchChunks` and `RejectSenders` as appropriate.
467-
- `retry_snapshot`: Restart this snapshot from `OfferSnapshot`, reusing chunks unless
468-
instructed otherwise.
469-
- `reject_snapshot`: Reject this snapshot, try a different one.
470-
- `RefetchChunks ([]uint32)`: Refetch and reapply the given chunks, regardless of `Result`. Only
471-
the listed chunks will be refetched, and reapplied in sequential order.
472-
- `RejectSenders ([]string)`: Reject the given P2P senders, regardless of `Result`. Any chunks
473-
already applied will not be refetched unless explicitly requested, but queued chunks from these senders will be discarded, and new chunks or other snapshots rejected.
474-
- **Usage**:
475-
- The application can choose to refetch chunks and/or ban P2P peers as appropriate. Tendermint
476-
will not do this unless instructed by the application.
477-
- The application may want to verify each chunk, e.g. by attaching chunk hashes in
478-
`Snapshot.Metadata` and/or incrementally verifying contents against `AppHash`.
479-
- When all chunks have been accepted, Tendermint will make an ABCI `Info` call to verify that
480-
`LastBlockAppHash` and `LastBlockHeight` matches the expected values, and record the
481-
`AppVersion` in the node state. It then switches to fast sync or consensus and joins the
482-
network.
483-
- If Tendermint is unable to retrieve the next chunk after some time (e.g. because no suitable
484-
peers are available), it will reject the snapshot and try a different one via `OfferSnapshot`.
485-
The application should be prepared to reset and accept it or abort as appropriate.
486-
487-
###
488-
489391
## Data Types
490392

491393
### Header
@@ -638,22 +540,3 @@ via light client.
638540
- `Type (string)`: Type of Merkle proof and how it's encoded.
639541
- `Key ([]byte)`: Key in the Merkle tree that this proof is for.
640542
- `Data ([]byte)`: Encoded Merkle proof for the key.
641-
642-
### Snapshot
643-
644-
- **Fields**:
645-
- `Height (uint64)`: The height at which the snapshot was taken (after commit).
646-
- `Format (uint32)`: An application-specific snapshot format, allowing applications to version
647-
their snapshot data format and make backwards-incompatible changes. Tendermint does not
648-
interpret this.
649-
- `Chunks (uint32)`: The number of chunks in the snapshot. Must be at least 1 (even if empty).
650-
- `Hash (bytes)`: An arbitrary snapshot hash. Must be equal only for identical snapshots across
651-
nodes. Tendermint does not interpret the hash, it only compares them.
652-
- `Metadata (bytes)`: Arbitrary application metadata, for example chunk hashes or other
653-
verification data.
654-
655-
- **Usage**:
656-
- Used for state sync snapshots, see [separate section](apps.md#state-sync) for details.
657-
- A snapshot is considered identical across nodes only if _all_ fields are equal (including
658-
`Metadata`). Chunks may be retrieved from all nodes that have the same snapshot.
659-
- When sent across the network, a snapshot message can be at most 4 MB.

‎spec/abci/apps.md

+1-151
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@ Here we cover the following components of ABCI applications:
1414
application state
1515
- [Crash Recovery](#crash-recovery) - handshake protocol to synchronize
1616
Tendermint and the application on startup.
17-
- [State Sync](#state-sync) - rapid bootstrapping of new nodes by restoring state machine snapshots
1817

1918
## State
2019

21-
Since Tendermint maintains four concurrent ABCI connections, it is typical
20+
Since Tendermint maintains three concurrent ABCI connections, it is typical
2221
for an application to maintain a distinct state for each, and for the states to
2322
be synchronized during `Commit`.
2423

@@ -93,11 +92,6 @@ QueryState should be set to the latest `DeliverTxState` at the end of every `Com
9392
ie. after the full block has been processed and the state committed to disk.
9493
Otherwise it should never be modified.
9594

96-
### Snapshot Connection
97-
98-
The Snapshot Connection is optional, and is only used to serve state sync snapshots for other nodes
99-
and/or restore state sync snapshots to a local node being bootstrapped.
100-
10195
## Transaction Results
10296

10397
`ResponseCheckTx` and `ResponseDeliverTx` contain the same fields.
@@ -470,147 +464,3 @@ If `appBlockHeight == storeBlockHeight`
470464
update the state using the saved ABCI responses but dont run the block against the real app.
471465
This happens if we crashed after the app finished Commit but before Tendermint saved the state.
472466

473-
## State Sync
474-
475-
A new node joining the network can simply join consensus at the genesis height and replay all
476-
historical blocks until it is caught up. However, for large chains this can take a significant
477-
amount of time, often on the order of weeks or months.
478-
479-
State sync is an alternative mechanism for bootstrapping a new node, where it fetches a snapshot
480-
of the state machine at a given height and restores it. Depending on the application, this can
481-
be several orders of magnitude faster than replaying blocks.
482-
483-
Note that state sync does not currently backfill historical blocks, so the node will have a
484-
truncated block history - users are advised to consider the broader network implications of this in
485-
terms of block availability and auditability. This functionality may be added in the future.
486-
487-
For details on the specific ABCI calls and types, see the [methods and types section](abci.md).
488-
489-
### Taking Snapshots
490-
491-
Applications that want to support state syncing must take state snapshots at regular intervals. How
492-
this is accomplished is entirely up to the application. A snapshot consists of some metadata and
493-
a set of binary chunks in an arbitrary format:
494-
495-
* `Height (uint64)`: The height at which the snapshot is taken. It must be taken after the given
496-
height has been committed, and must not contain data from any later heights.
497-
498-
* `Format (uint32)`: An arbitrary snapshot format identifier. This can be used to version snapshot
499-
formats, e.g. to switch from Protobuf to MessagePack for serialization. The application can use
500-
this when restoring to choose whether to accept or reject a snapshot.
501-
502-
* `Chunks (uint32)`: The number of chunks in the snapshot. Each chunk contains arbitrary binary
503-
data, and should be less than 16 MB; 10 MB is a good starting point.
504-
505-
* `Hash ([]byte)`: An arbitrary hash of the snapshot. This is used to check whether a snapshot is
506-
the same across nodes when downloading chunks.
507-
508-
* `Metadata ([]byte)`: Arbitrary snapshot metadata, e.g. chunk hashes for verification or any other
509-
necessary info.
510-
511-
For a snapshot to be considered the same across nodes, all of these fields must be identical. When
512-
sent across the network, snapshot metadata messages are limited to 4 MB.
513-
514-
When a new node is running state sync and discovering snapshots, Tendermint will query an existing
515-
application via the ABCI `ListSnapshots` method to discover available snapshots, and load binary
516-
snapshot chunks via `LoadSnapshotChunk`. The application is free to choose how to implement this
517-
and which formats to use, but should provide the following guarantees:
518-
519-
* **Consistent:** A snapshot should be taken at a single isolated height, unaffected by
520-
concurrent writes. This can e.g. be accomplished by using a data store that supports ACID
521-
transactions with snapshot isolation.
522-
523-
* **Asynchronous:** Taking a snapshot can be time-consuming, so it should not halt chain progress,
524-
for example by running in a separate thread.
525-
526-
* **Deterministic:** A snapshot taken at the same height in the same format should be identical
527-
(at the byte level) across nodes, including all metadata. This ensures good availability of
528-
chunks, and that they fit together across nodes.
529-
530-
A very basic approach might be to use a datastore with MVCC transactions (such as RocksDB),
531-
start a transaction immediately after block commit, and spawn a new thread which is passed the
532-
transaction handle. This thread can then export all data items, serialize them using e.g.
533-
Protobuf, hash the byte stream, split it into chunks, and store the chunks in the file system
534-
along with some metadata - all while the blockchain is applying new blocks in parallel.
535-
536-
A more advanced approach might include incremental verification of individual chunks against the
537-
chain app hash, parallel or batched exports, compression, and so on.
538-
539-
Old snapshots should be removed after some time - generally only the last two snapshots are needed
540-
(to prevent the last one from being removed while a node is restoring it).
541-
542-
### Bootstrapping a Node
543-
544-
An empty node can be state synced by setting the configuration option `statesync.enabled =
545-
true`. The node also needs the chain genesis file for basic chain info, and configuration for
546-
light client verification of the restored snapshot: a set of Tendermint RPC servers, and a
547-
trusted header hash and corresponding height from a trusted source, via the `statesync`
548-
configuration section.
549-
550-
Once started, the node will connect to the P2P network and begin discovering snapshots. These
551-
will be offered to the local application, and once a snapshot is accepted Tendermint will fetch
552-
and apply the snapshot chunks. After all chunks have been successfully applied, Tendermint verifies
553-
the app's `AppHash` against the chain using the light client, then switches the node to normal
554-
consensus operation.
555-
556-
#### Snapshot Discovery
557-
558-
When the empty node join the P2P network, it asks all peers to report snapshots via the
559-
`ListSnapshots` ABCI call (limited to 10 per node). After some time, the node picks the most
560-
suitable snapshot (generally prioritized by height, format, and number of peers), and offers it
561-
to the application via `OfferSnapshot`. The application can choose a number of responses,
562-
including accepting or rejecting it, rejecting the offered format, rejecting the peer who sent
563-
it, and so on. Tendermint will keep discovering and offering snapshots until one is accepted or
564-
the application aborts.
565-
566-
#### Snapshot Restoration
567-
568-
Once a snapshot has been accepted via `OfferSnapshot`, Tendermint begins downloading chunks from
569-
any peers that have the same snapshot (i.e. that have identical metadata fields). Chunks are
570-
spooled in a temporary directory, and then given to the application in sequential order via
571-
`ApplySnapshotChunk` until all chunks have been accepted.
572-
573-
As with taking snapshots, the method for restoring them is entirely up to the application, but will
574-
generally be the inverse of how they are taken.
575-
576-
During restoration, the application can respond to `ApplySnapshotChunk` with instructions for how
577-
to continue. This will typically be to accept the chunk and await the next one, but it can also
578-
ask for chunks to be refetched (either the current one or any number of previous ones), P2P peers
579-
to be banned, snapshots to be rejected or retried, and a number of other responses - see the ABCI
580-
reference for details.
581-
582-
If Tendermint fails to fetch a chunk after some time, it will reject the snapshot and try a
583-
different one via `OfferSnapshot` - the application can choose whether it wants to support
584-
restarting restoration, or simply abort with an error.
585-
586-
#### Snapshot Verification
587-
588-
Once all chunks have been accepted, Tendermint issues an `Info` ABCI call to retrieve the
589-
`LastBlockAppHash`. This is compared with the trusted app hash from the chain, retrieved and
590-
verified using the light client. Tendermint also checks that `LastBlockHeight` corresponds to the
591-
height of the snapshot.
592-
593-
This verification ensures that an application is valid before joining the network. However, the
594-
snapshot restoration may take a long time to complete, so applications may want to employ additional
595-
verification during the restore to detect failures early. This might e.g. include incremental
596-
verification of each chunk against the app hash (using bundled Merkle proofs), checksums to
597-
protect against data corruption by the disk or network, and so on. However, it is important to
598-
note that the only trusted information available is the app hash, and all other snapshot metadata
599-
can be spoofed by adversaries.
600-
601-
Apps may also want to consider state sync denial-of-service vectors, where adversaries provide
602-
invalid or harmful snapshots to prevent nodes from joining the network. The application can
603-
counteract this by asking Tendermint to ban peers. As a last resort, node operators can use
604-
P2P configuration options to whitelist a set of trusted peers that can provide valid snapshots.
605-
606-
#### Transition to Consensus
607-
608-
Once the snapshot has been restored, Tendermint gathers additional information necessary for
609-
bootstrapping the node (e.g. chain ID, consensus parameters, validator sets, and block headers)
610-
from the genesis file and light client RPC servers. It also fetches and records the `AppVersion`
611-
from the ABCI application.
612-
613-
Once the node is bootstrapped with this information and the restored state machine, it transitions
614-
to fast sync (if enabled) to fetch any remaining blocks up the the chain head, and then
615-
transitions to regular consensus operation. At this point the node operates like any other node,
616-
apart from having a truncated block history at the height of the restored snapshot.

‎spec/abci/client-server.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ it is the standard way to encode integers in Protobuf. It is also generally shor
8585
As noted above, this prefixing does not apply for GRPC.
8686

8787
An ABCI server must also be able to support multiple connections, as
88-
Tendermint uses four connections.
88+
Tendermint uses three connections.
8989

9090
### Async vs Sync
9191

‎spec/reactors/state_sync/reactor.md

-77
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.