What is an SSZ partial? What are its benefits and are there any existing similar concepts that would help in understanding it?
Some references:
What is an SSZ partial? What are its benefits and are there any existing similar concepts that would help in understanding it?
Some references:
The idea of a SSZ partial is that any SSZ type (see SSZ spec what SSZ is) is just used to provide a typed "view": you have type information for everything that could be there, but you may only need partial access to the actual value.
Additionally, since the goal of SSZ is to provide merkle-proofs for all types of data, a partial can also have a merkle-proof, but only proves the subset of data included in the partial.
To build these merkle proofs, every SSZ data type has a well defined way to represent it as a binary tree.
For small pieces of data it is more common to just represent it as the abstracted data-type in whatever programming language you are using to interact with the value. And then it only gets converted to a binary tree last-minute during merkleization of the value.
For large pieces of data, like the BeaconState
type, Eth2 beacon clients started caching parts of this tree, or fully represent it as tree. The intention here is to use a persistent-tree (the functional programming concept) to share subtrees that do not change between different states.
When you only need a small subset of a large piece of data, you can leave out the parts of the tree you do not need, while still being able to use it the same otherwise, this is why it is called a "partial".
Additionally, with your partial data you can keep the root node of irrelevant subtrees you prune away (called "helper" or "sibling" node). Then you are left with the part of the tree you do want to read, and the helper nodes that allow you to construct a merkle proof for the data you are interested in.
And ideally, a partial still has the same type information, so you do not have to think about merkle proofs or extracting values from your partial data. It just works as the full type, except you cannot access some of the values, since they are not part of the selected values.
A simple implementation of a partial could just raise an exception whenever you try to access some of the value subset that is not there. A better implementation may define which parts of the type are unavailable, while keeping the type compatible with the full version when the usage does not break the limits of the partial information.
Now you can have a hybrid between small and large data types: no need to provide the full BeaconState when you want to read just the latest_block_header
field and a little of the information of some validators (e.g. effective_balance
of validators[0]
, and slashed
of validators[23]
). Instead, you provide just the information you need, and some "helper" nodes to construct the merkle-proof of the bigger encapsulating type (the BeaconState).
The intention here is that light-clients can trustlessly interact with information from a much larger state, in a type-safe way, without thinking about the required merkle proof much at all.
TLDR: typed efficient arbitrary merkle proofs for light clients in Eth2
To understand the merkle-proof part better, I recommend searching the Eth2 spec issues for "multi proofs" (the type of merkle proof that covers multiple values), and for advanced usage you can also look for "SSZ type expansions" (an Eth2 header can be represented as a partial of a block).
I am also working on this draft for a new SSZ spec (fully compatible, no changes, just expand with more information) to cover these types of advanced SSZ features. The work-in-progress can be found here: https://github.com/protolambda/eth2.0-ssz