Approaches to upgrading blockchain state #190
Replies: 3 comments 5 replies
-
I want to mention that today archival nodes already have to maintain all versions indefinitely. |
Beta Was this translation helpful? Give feedback.
-
I think we can use approach 3 to do resharding as well:
def account_id_to_shard_id(account_id, epoch_id):
protocol_version = self.get_epoch_protocol_version(epoch_id)
# do the old computation
shard_id = compute_shard_id(account_id)
if protocol_version > PROTOCOL_VERSION_TO_RESHARD and f(account_id) == 1:
return total_num_shards
return shard_id
|
Beta Was this translation helpful? Give feedback.
-
I haven't seen this approach discussed explicitly so wanted to ask what are problems with it? Approach 4: Split & MergeAt any epoch boundary a single shard can be split into two or two "adjacent" shards can be joined into one.
Adjacency of shards is defined by the ordering of the accounts in the Trie (or whatever storage we are using next). It would make sense to transition to use hash(account_id) as a key in the trie. Though as we saw grouping accounts close to each other is no very hard in the hash space as well. SplitLet's say that at epoch T the shard_i will be split into 2: shard_i and shard_{i + 1}. This decision is made at the end of T-2 epoch together with chunk producer assignment for these two shards. During T-1 these chunk producers of shard_i & shard_{i + 1} for T will be operating as chunk producers for shard_i before re-sharding. Meaning they are receiving chunks and applying them, maintaining full state of shard_i pre-split. This the logic we have now. It's important to track the full shard state because this same chunk producer can be chunk producer for this shard at T - 1. When last chunk of T - 1 applied in shard_i, the "split" logic gets executed on all nodes that are tracking the shard_i:
For non shard_i chunks at last chunk in T - 1: shift their ChunkResult by 1 if their id if after i. When producing and applying the first block of T, the chunk producers selected for shard_i & shard_{i + 1} start operating in the new sharding layout. They accept transactions for respective shards, produce a chunk and when applying will look up respective MergeLet's say we want to merge shard_i and shard_{i + 1} into shard_i starting epoch T. This decision is made at the end of epoch T - 2. Chunk producers are assigned for new shard_i in T. These chunk producers starting to track and catch up with shard_i and shard_{i + 1} in epoch T - 1. During application of the last chunk in T - 1, everyone who tracks shard_i and shard_{i + 1} -- and this should be everyone who will be chunk producing in the next chunk:
Other chunk producers shift down their Producing chunks in T then operates as normal. |
Beta Was this translation helpful? Give feedback.
-
This post, which was inspired by near/nearcore#4024, describes three different ways how blockchain state can be upgraded, together with their pros and cons.
What is a state upgrade?
State upgrade is an operation that changes how the state is represented. This usually involves changing the layout of some data structures, but it can be any change to the physical representation of the same logical state. This only includes the changes that have an effect on the consensus, therefore, for example, using a different (low-level) storage backend doesn't qualify.
Approach 1: lazy upgrade
Perhaps the most obvious approach is to have each state component, such as an account or storage entry, be individually versioned. After an upgrade starts, these components will be upgraded when they are accessed and/or modified. At each point, the state may include components of multiple different versions.
Pros:
Cons:
Approach 2: parallel construction
This approach uses the fact that the state is small enough to sync within an epoch. If it is small enough to sync, it must be small enough to upgrade as well. So, the nodes keep maintaining the old state while building an upgraded copy in parallel. At some point, they begin posting the new state root hash to the blockchain instead of the old one. After that, they can discard the old state and use the new one exclusively.
Pros:
Cons:
Approach 3: sequential upgrade
This approach also maintains two states: the old one and the new one. Unlike in approach 2, the new state begins empty. Each block, some number of components are moved from the old state to the new state (that is, removed from the old state and at the same time added to the new state), and all the necessary conversions are performed. During the upgrade, there are two state roots. After the old state becomes empty, it is discarded and the upgrade is finished.
Pros:
Cons:
I think that in the future we should be using approach 3 for state upgrades. This means that individual components of the state (such as accounts) should not be versioned, instead, their version is determined by the specific state they appear in.
Beta Was this translation helpful? Give feedback.
All reactions