# Ethereum blockchain state on swarm This document describes a way to put ethereum state data on swarm, gives a 4 step roadmap and discusses the potential merits of the approach. ## Ethereum state on swarm The simplest idea is to treat trie nodes as a chunk type, using their ethereum keccak256 hash as content address. With this, the state tries (log, contract storage, tx) become content address-linked native data structures on swarm. ### bzzeth-raw The first phase is to introduce a raw API over these chunks to allow retrieval of trie nodes by hash. bzz-eth-raw://<sha3-hash>/ results in the binary trie node blob whose hash is in the host part of the url. The second phase the protocol is aware of the internal structure of the trie node and is able to traverse the trie. The URL path can serve as intructions for the protocol to traverse along the branches based on the partial key given in the url path. bzz-eth-raw://<sha3hash>/<partial-address>/ results in the non-root trie node reached by traversing the trie following the branch corresponding to successive hex digits of the partial address. If a root trie node hash and a full address are given (as host and path part of the URL respectively), the url retrieves an account node (ECA or contract). This supports the use-case of a simple decentralised blockchain explorer API. If anywhere along the path an empty subtrie is encountered, i.e., the trie node at `<address>[:i]` is non-branching on `<address>[i]`, then the response should be an empty body with status code 200 (2XX). Importantly, this is to be distinguished from a 404 response which means that a properly referenced trie node chunk (the one in the url or along the traversed path) is not retrievable from swarm. Caveats: the size of chunks is not limited in theory, especially contract creation transactions can be of arbitrary size. If no reasonable upper limit applies to nodes, trie node chunk delivery could be used for DoS attacks Empirical analysis is needed to investigate the distribution of transaction sizes. ### bzz-eth The third phase involves a non-raw `bzz-eth` scheme bzz-eth://<sha3hash>/<partial-address>/ resolves to the ordered sequence of leaf nodes under the trie node of the corresponding raw call. In other words the tries are considered to encode the datastream as a file (in a similar way to the swarm hash). If served via streams, this can be used to aid fast syncing snapshots. ### Outsourced traversal with Merkle proofs The trie node traversal can be defined as a PSS PubSub protocol, i.e., the same as in local traversal but carried out by forwarding to the child node and cumulating the merkle proof on the way back. This allows for light client requests without light servers and their throughput management. SWAP incentivisation can be extended to this scenario. ### Syncing support The statetrie's retrieval is way more economical if only the leaf nodes are downloaded. All the intermediate nodes can be reconstructed locally and validated against trie roots. Nodes that keep state locally can pin trie nodes and advertise that the leaf data can be streamed from them. Nodes would connect to these state seeder(s) (either directly or via pss) and leech the data from them using the stream! protocol. This would be exactly the same mechanism as the one used for webzztorrent, torrent-like stream download of files. Nodes that pin content can notify the content owner (defined as the ens owner or publisher of the root manifest) who maintains and publishes a pinning feed, pointing to a resource including addresses of content providers similar to torrent trackers. Consumers of large files or large merklized structures can then choose to retrieve content via the stream protocol. Servers only need to store the leaf chunks and keep the sequence of hashes of leaf chunks as special streamable chunks content addressed by the appropriate merkle hash, ie. the swarm hash for files and patricia merkle trie root hash in the other. ## Discussion Fast sync loads a snapshot of a state. Downloading the snapshot from swarm enjoys the benefit of load-balanced parallel downloads as well as latency/availability boost due to caching. Using a snapshot with a format that needs to be create raises problems. Checkpointing is deemed prohibitive since the creating the snapshot - defined here as a fixed format describing the state - is computationally intensive. Purely iterating over all trie nodes takes 15 minutes. Even if such a snapshot is created by some service once, generating updates would not be feasible. If there was a format with which a node can generate diffs to the previous state, it may be possible, since a node would need to keep all state info only until the next checkpoint snapshot is created. With diffs available, clients could sync by downloading a chain of diffs and apply to the genesis snapshot, to come to a state. Surely this also has the caveat that as the diffs to apply increase, the more past state will have stale nodes which were fetched initially creating unnecessary downloads. Adding this file to the swarm raises further problems. If swarm has no spam protection, the system is attackable by DDOS. If POB based spam protection is in place then full nodes have a barrier of entry for even the charitable service they provide. While in theory incentivisation could somehow solve the sustainability of such a service, it is complex to implement. The other issue is that with content address storage, if state snapshots and their diffs are to be retrieved based on their address, there needs to be a trusted translation service to advise clients about the content address of new state diffs. Such a service is difficult to incentivise and in any case requires staked nodes for accountability so raises the same problem as upload itself. Putting the state tries as a native data structure on swarm, i.e., trie node hashes are the content address itself, has many advantages. We can assume that any client has the header chain available and therefore knows the root hashes of state tries. The client would start to download the nodes of the latest state. As the header chain progresses, the client can always switch to the latest root, and 'apply the diff'. Those try nodes that are preserved in the new state will simply find the trie node chunk locally. The snapshot is purely the set of trie nodes constituting a state. Diffs are automatically defined as those trie nodes that are not in the previous set. Creating the snapshot is a non-issue and uploading can be load-balanced among a cluster of nodes and be guaranteed by charitable volunteers initially until properly incentivised. As the trie roots are part of the block header, any client having the header chain will immediately allow the use of swarm retrieval without a mapping service. Designating specific checkpoints is unnecessary for the correctness but can help diffs of a particular state become more wide spread through swarm caching, thereby increasing availability and decreasing latency of retrieval. Consequently coordinating on checkpoints at consensual puntcuated intervals will help further. This same structure supports retrieval of trie nodes by hash or random access to trie (state data) therefore serving LES requests, or even serve as a remote trie implementation. Using the scheme to bootsrap a full node then is the same mechanism as light nodes. If the trie falls back to on demand retrieval via swarm, then running the VM will only populate the db with trie nodes that transactions reference, therefore they can bootstrap in a short amount of time, requiring nothing special. Ultimately, the client will have the full state and act as a full node, able to serve the eth protocol. Beyond archive, full and light nodes, there has been proposals to introduce a 4th type of node syncing, which prunes historical blocks. Such a pruned state is much easier to bootsrap from. The caveat is that without incentives this might discourage participants to operate proper full nodes and with time run the danger of historical blocks disappearing. A solution to this problem if we make sure that historical blocks, though not stored on each full node, at least stay available collectively in swarm. First a service run by a charitable entity could make sure these pruned blocks and their states remain available by uploading them to swarm. This process could be collectivised, but uploading the pruned blocks will raise the spam issue. if state pruning was just done by swarm garbage collection deleting long unretrieved chunks (trie nodes), it would leave those trie nodes with a client that are closer to their overlay address. If there is enough nodes serving content with swarm to cover the address space, ie., there is a full node in every neighbourhood, such historical blocks stay retrievable without upload costs. https://github.com/dryajov/ethereum-sync/blob/master/fast-prefix-sync.md https://www.wealdtech.com/articles/understanding-sparse-merkle-multiproofs/