github.com/number571/tendermint@v0.34.11-gost/docs/architecture/adr-042-state-sync.md (about)

     1  # ADR 042: State Sync Design
     2  
     3  ## Changelog
     4  
     5  2019-06-27: Init by EB
     6  2019-07-04: Follow up by brapse
     7  
     8  ## Context
     9  StateSync is a feature which would allow a new node to receive a
    10  snapshot of the application state without downloading blocks or going
    11  through consensus. Once downloaded, the node could switch to FastSync
    12  and eventually participate in consensus. The goal of StateSync is to
    13  facilitate setting up a new node as quickly as possible.
    14  
    15  ## Considerations
    16  Because Tendermint doesn't know anything about the application state,
    17  StateSync will broker messages between nodes and through
    18  the ABCI to an opaque applicaton. The implementation will have multiple
    19  touch points on both the tendermint code base and ABCI application.
    20  
    21  * A StateSync reactor to facilitate peer communication - Tendermint
    22  * A Set of ABCI messages to transmit application state to the reactor - Tendermint
    23  * A Set of MultiStore APIs for exposing snapshot data to the ABCI - ABCI application
    24  * A Storage format with validation and performance considerations - ABCI application
    25  
    26  ### Implementation Properties
    27  Beyond the approach, any implementation of StateSync can be evaluated
    28  across different criteria:
    29  
    30  * Speed: Expected throughput of producing and consuming snapshots
    31  * Safety: Cost of pushing invalid snapshots to a node
    32  * Liveness: Cost of preventing a node from receiving/constructing a snapshot
    33  * Effort: How much effort does an implementation require
    34  
    35  ### Implementation Question
    36  * What is the format of a snapshot
    37      * Complete snapshot
    38      * Ordered IAVL key ranges
    39      * Compressed individually chunks which can be validated
    40  * How is data validated
    41      * Trust a peer with it's data blindly
    42      * Trust a majority of peers
    43      * Use light client validation to validate each chunk against consensus
    44        produced merkle tree root
    45  * What are the performance characteristics
    46      * Random vs sequential reads
    47      * How parallelizeable is the scheduling algorithm
    48  
    49  ### Proposals
    50  Broadly speaking there are two approaches to this problem which have had
    51  varying degrees of discussion and progress. These approach can be
    52  summarized as:
    53  
    54  **Lazy:** Where snapshots are produced dynamically at request time. This
    55  solution would use the existing data structure.
    56  **Eager:** Where snapshots are produced periodically and served from disk at
    57  request time. This solution would create an auxiliary data structure
    58  optimized for batch read/writes.
    59  
    60  Additionally the propsosals tend to vary on how they provide safety
    61  properties.
    62  
    63  **LightClient** Where a client can aquire the merkle root from the block
    64  headers synchronized from a trusted validator set. Subsets of the application state,
    65  called chunks can therefore be validated on receipt to ensure each chunk
    66  is part of the merkle root.
    67  
    68  **Majority of Peers** Where manifests of chunks along with checksums are
    69  downloaded and compared against versions provided by a majority of
    70  peers.
    71  
    72  #### Lazy StateSync
    73  An initial specification was published by Alexis Sellier.
    74  In this design, the state has a given `size` of primitive elements (like
    75  keys or nodes), each element is assigned a number from 0 to `size-1`,
    76  and chunks consists of a range of such elements.  Ackratos raised
    77  [some concerns](https://docs.google.com/document/d/1npGTAa1qxe8EQZ1wG0a0Sip9t5oX2vYZNUDwr_LVRR4/edit)
    78  about this design, somewhat specific to the IAVL tree, and mainly concerning
    79  performance of random reads and of iterating through the tree to determine element numbers
    80  (ie. elements aren't indexed by the element number).
    81  
    82  An alternative design was suggested by Jae Kwon in
    83  [#3639](https://github.com/number571/tendermint/issues/3639) where chunking
    84  happens lazily and in a dynamic way: nodes request key ranges from their peers,
    85  and peers respond with some subset of the
    86  requested range and with notes on how to request the rest in parallel from other
    87  peers. Unlike chunk numbers, keys can be verified directly. And if some keys in the
    88  range are ommitted, proofs for the range will fail to verify.
    89  This way a node can start by requesting the entire tree from one peer,
    90  and that peer can respond with say the first few keys, and the ranges to request
    91  from other peers.
    92  
    93  Additionally, per chunk validation tends to come more naturally to the
    94  Lazy approach since it tends to use the existing structure of the tree
    95  (ie. keys or nodes) rather than state-sync specific chunks. Such a
    96  design for tendermint was originally tracked in
    97  [#828](https://github.com/number571/tendermint/issues/828).
    98  
    99  #### Eager StateSync
   100  Warp Sync as implemented in OpenEthereum to rapidly
   101  download both blocks and state snapshots from peers. Data is carved into ~4MB
   102  chunks and snappy compressed. Hashes of snappy compressed chunks are stored in a
   103  manifest file which co-ordinates the state-sync. Obtaining a correct manifest
   104  file seems to require an honest majority of peers. This means you may not find
   105  out the state is incorrect until you download the whole thing and compare it
   106  with a verified block header.
   107  
   108  A similar solution was implemented by Binance in
   109  [#3594](https://github.com/number571/tendermint/pull/3594)
   110  based on their initial implementation in
   111  [PR #3243](https://github.com/number571/tendermint/pull/3243)
   112  and [some learnings](https://docs.google.com/document/d/1npGTAa1qxe8EQZ1wG0a0Sip9t5oX2vYZNUDwr_LVRR4/edit).
   113  Note this still requires the honest majority peer assumption.
   114  
   115  As an eager protocol, warp-sync can efficiently compress larger, more
   116  predicatable chunks once per snapshot and service many new peers. By
   117  comparison lazy chunkers would have to compress each chunk at request
   118  time.
   119  
   120  ### Analysis of Lazy vs Eager
   121  Lazy vs Eager have more in common than they differ. They all require
   122  reactors on the tendermint side, a set of ABCI messages and a method for
   123  serializing/deserializing snapshots facilitated by a SnapshotFormat.
   124  
   125  The biggest difference between Lazy and Eager proposals is in the
   126  read/write patterns necessitated by serving a snapshot chunk.
   127  Specifically, Lazy State Sync performs random reads to the underlying data
   128  structure while Eager can optimize for sequential reads.
   129  
   130  This distinctin between approaches was demonstrated by Binance's
   131  [ackratos](https://github.com/ackratos) in their implementation of [Lazy
   132  State sync](https://github.com/number571/tendermint/pull/3243), The
   133  [analysis](https://docs.google.com/document/d/1npGTAa1qxe8EQZ1wG0a0Sip9t5oX2vYZNUDwr_LVRR4/)
   134  of the performance, and follow up implementation of [Warp
   135  Sync](http://github.com/number571/tendermint/pull/3594).
   136  
   137  #### Compairing Security Models
   138  There are several different security models which have been
   139  discussed/proposed in the past but generally fall into two categories.
   140  
   141  Light client validation: In which the node receiving data is expected to
   142  first perform a light client sync and have all the nessesary block
   143  headers. Within the trusted block header (trusted in terms of from a
   144  validator set subject to [weak
   145  subjectivity](https://github.com/number571/tendermint/pull/3795)) and
   146  can compare any subset of keys called a chunk against the merkle root.
   147  The advantage of light client validation is that the block headers are
   148  signed by validators which have something to lose for malicious
   149  behaviour. If a validator were to provide an invalid proof, they can be
   150  slashed.
   151  
   152  Majority of peer validation: A manifest file containing a list of chunks
   153  along with checksums of each chunk is downloaded from a
   154  trusted source. That source can be a community resource similar to
   155  [sum.golang.org](https://sum.golang.org) or downloaded from the majority
   156  of peers. One disadantage of the majority of peer security model is the
   157  vuliberability to eclipse attacks in which a malicious users looks to
   158  saturate a target node's peer list and produce a manufactured picture of
   159  majority.
   160  
   161  A third option would be to include snapshot related data in the
   162  block header. This could include the manifest with related checksums and be
   163  secured through consensus. One challenge of this approach is to
   164  ensure that creating snapshots does not put undo burden on block
   165  propsers by synchronizing snapshot creation and block creation. One
   166  approach to minimizing the burden is for snapshots for height
   167  `H` to be included in block `H+n` where `n` is some `n` block away,
   168  giving the block propser enough time to complete the snapshot
   169  asynchronousy.
   170  
   171  ## Proposal: Eager StateSync With Per Chunk Light Client Validation
   172  The conclusion after some concideration of the advantages/disadvances of
   173  eager/lazy and different security models is to produce a state sync
   174  which eagerly produces snapshots and uses light client validation. This
   175  approach has the performance advantages of pre-computing efficient
   176  snapshots which can streamed to new nodes on demand using sequential IO.
   177  Secondly, by using light client validation we cna validate each chunk on
   178  receipt and avoid the potential eclipse attack of majority of peer based
   179  security.
   180  
   181  ### Implementation
   182  Tendermint is responsible for downloading and verifying chunks of
   183  AppState from peers. ABCI Application is responsible for taking
   184  AppStateChunk objects from TM and constructing a valid state tree whose
   185  root corresponds with the AppHash of syncing block. In particular we
   186  will need implement:
   187  
   188  * Build new StateSync reactor brokers message transmission between the peers
   189    and the ABCI application
   190  * A set of ABCI Messages
   191  * Design SnapshotFormat as an interface which can:
   192      * validate chunks
   193      * read/write chunks from file
   194      * read/write chunks to/from application state store
   195      * convert manifests into chunkRequest ABCI messages
   196  * Implement SnapshotFormat for cosmos-hub with concrete implementation for:
   197      * read/write chunks in a way which can be:
   198          * parallelized across peers
   199          * validated on receipt
   200      * read/write to/from IAVL+ tree
   201  
   202  ![StateSync Architecture Diagram](img/state-sync.png)
   203  
   204  ## Implementation Path
   205  * Create StateSync reactor based on  [#3753](https://github.com/number571/tendermint/pull/3753)
   206  * Design SnapshotFormat with an eye towards cosmos-hub implementation
   207  * ABCI message to send/receive SnapshotFormat
   208  * IAVL+ changes to support SnapshotFormat
   209  * Deliver Warp sync (no chunk validation)
   210  * light client implementation for weak subjectivity
   211  * Deliver StateSync with chunk validation
   212  
   213  ## Status
   214  
   215  Proposed
   216  
   217  ## Concequences
   218  
   219  ### Neutral
   220  
   221  ### Positive
   222  * Safe & performant state sync design substantiated with real world implementation experience
   223  * General interfaces allowing application specific innovation
   224  * Parallizable implementation trajectory with reasonable engineering effort
   225  
   226  ### Negative
   227  * Static Scheduling lacks opportunity for real time chunk availability optimizations
   228  
   229  ## References
   230  [sync: Sync current state without full replay for Applications](https://github.com/number571/tendermint/issues/828) - original issue
   231  [tendermint state sync proposal 2](https://docs.google.com/document/d/1npGTAa1qxe8EQZ1wG0a0Sip9t5oX2vYZNUDwr_LVRR4/edit) - ackratos proposal
   232  [proposal 2 implementation](https://github.com/number571/tendermint/pull/3243)  - ackratos implementation
   233  [WIP General/Lazy State-Sync pseudo-spec](https://github.com/number571/tendermint/issues/3639) - Jae Proposal
   234  [Warp Sync Implementation](https://github.com/number571/tendermint/pull/3594) - ackratos
   235  [Chunk Proposal](https://github.com/number571/tendermint/pull/3799) - Bucky proposed