-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Make the genesis block building more flexible #10360
Comments
Why do you need to add a digest in genesis? |
@nazar-pc Since you have a better big picture than me, perhaps you could help explain why we need this feature? :P |
Subspace blockchain has proof-of-archival-storage consensus. That means in order to participate in block production farmer needs to prove storing unique [partial] replica of the blockchain history, blockchain itself. Pieces of the blockchain are plotted by farmers as blocks are produced by filling a special buffer. There is a threshold we call Here is the problem: before we have the very first segment, farmers have nothing to plot and thus can't produce blocks. Chicken and egg kind of problem. We solved that previously with a workaround where we had "pre-genesis" seed data prepended to the history of the blockchain that allowed us to bootstrap the network, but it was ugly and awkward to maintain. In latest iteration we removed "pre-genesis" objects and decided to increase genesis block in size instead such that it alone exceeds RHSS, since genesis block is created unconditionally, will not be reverted, so farmers will be able to plot it right away. The way to achieve that was to create a custom It would be nice if there was another way to customize genesis block (including digest items), but the lines mentioned in the first comment are buried deep in dependencies and the only way I found to achieve the goal was to customize the |
Can you not just have a special case that ignores genesis? Aka doesn't require that the genesis block has this data? |
The issue is the opposite. It doesn't technically mean which data, but genesis block should contain some data that is at least RHSS in size or else farmers have nothing to plot and network can't bootstrap itself due to lack of the blockchain history. |
Not sure what "farmers" are, but why can they not do the following:
|
Farmer is a separate application, similar to miner in other protocols. It plots SCALE-encoded blocks from the Substrate-based node to disk, plot is then used to solve challenges in order to participate in block production. It should be possible to retrieve blocks from farmer's plot as is and SCALE-decode them back into correct block struct or else we are not archiving the blockchain itself. Blocks to farmers are opaque blobs, they don't look inside and don't have a direct way to interpret them. |
Okay, but they could use the logic I drafted above? |
We can probably hack something like that, but then the block you retrieve from the farmer network wouldn't be the same as from Substrate-based node. To fix that we'd have to pull Substrate types (or their approximation) into the farmer to parse and fix genesis block after the fact, which is a really ugly approach. Also there are potentially different pieces of software that can create or read that archival history and all of them will have to be aware of that weird exception that genesis block is. We already achieved what we wanted with custom |
What? Why? I really don't get your flow. Why do you want to modify the block? I'm speaking about a special casing in the one function that does the processing. Nothing more. |
Farmers archive blocks not for the sake of doing so, they do it so that the history of the blockchain can be recovered from plots, that is the point of the proof-of-archival-storage. Hence the blocks being plotted, including genesis blocks, should be identical in Substrate-based node and in the plot. Since we need the genesis block be at least RHSS in the plot, it must be the same size in the node. Node produces block -> block is archived and plotted by farmer -> block can be recovered by another node for sync process. Farmer network will replace archival nodes in our protocol. And hopefully not only in our network as we already archive Kusama and all parachains on our testnet too, so with adapter it will be possible to sync those from farmer network of Subspace too. |
@bkchr Happy to help if you have some ideas on implementing this generally nice-to-have feature. I can only come up with a kind of dirty way which is to extract the |
Sorry for the late answer. I'm going to hijack this issue now ;) We should add a new trait:
The client should then take this trait for building the genesis block. This also means that the following code should be moved into the implementation of this trait: substrate/client/service/src/client/client.rs Lines 335 to 339 in 1d8f7bf
So we will create some type like:
@nazar-pc @liuchengxu you will then be able to write your own implementation of I will assign this issue to someone in parity and it will be worked on in the next days/weeks. |
@bkchr Any update on this issue? I can help here if you want. |
Yeah you can take this @liuchengxu. Sorry for not yet having someone working on this. It fell under the radar. |
The background is that we want to inject a
DigestItem
into the header of the genesis block, I thought callingframe_system::deposit_log()
in genesis build should work, but it's not because right now only the genesis storage/state is taken care of and the genesisDigest
is hardcoded as the default value.substrate/client/service/src/client/genesis.rs
Line 34 in 1d8f7bf
Since we already have built the genesis storage, we could extract the
Digest
value from the state and extendconstruct_genesis_block(state_root, digest)
using it, so that people can useframe_system::deposit_log()
during the genesis build as normal.substrate/client/service/src/client/client.rs
Lines 335 to 339 in 1d8f7bf
By adding this feature, people can have full control of building the genesis block.
The text was updated successfully, but these errors were encountered: