-
Notifications
You must be signed in to change notification settings - Fork 11.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Run module initializers during genesis #542
Conversation
ContextTo support running module initializer in genesis, I can think of two approaches:
The disadvantage of the first approach is that there're a lot more refactoring needed(see investigation below). The disadvantage of the second approach is that the approach does not work for the Sui and Move framework lib as these two are the prerequisite for move vm(correct me if this is a false assumption). We could continue treating these two libs specially and write them directly to DB , but we have to take Approach 1 if we decide to add an Investigation for approach 1:To execute the the module initializer, we cannot simply insert objects to the DB like what we did for storing modules. Instead, we need to run the vm with a AuthorityTemporaryStore The input objects can be constructed in this way After we obtain the side effects from the VM, we need to call The To conclude, the tricky part of approach 1 is that we need to construct a My questions
cc @sblackshear @lxfind @awelc Your suggestions are very appreciated here |
My initial idea/suggestion was along the lines of solution #1. It seems like an easier and less invasive add-on than doing "full" publishing for the genesis code. At the same time, I believe that "publishing" has two components:
At this point, I am not sure how the second part is done for the genesis code if we don't do full publishing but it seems like genesis code IS (somehow) available for subsequent Move call after genesis runs. Consequently, it should be possible to simply call into initializers of all modules that are available during genesis construction in the |
Yeah there's no question of calling into initializers. But this is the tricky part I was trying to understand if storing the certificates is a hard requirement or not and what's the best way of constructing them. |
I think you can iterate over objects in temporary store and insert them to the database one by one using |
@awelc thanks for the good suggestion! It looks like we don't need to store the And extract the following logic into a function to reuse for Genesis so that we can also handle the delete/updated cases(although delete will rarely happen in init(), but it's good to handle them so that developers are not surprised) |
I think the problem you're running into is a deep one: genesis is fundamentally a bootstrapping process. Everything must start from either a set of intial objects, or a transaction. But every Sui object knows the hash of the transaction that created it, and every Sui transaction has >0 input objects. We have to break that circularity somehow, and I think (1)/(2) roughly correspond to "start with objects" and "start with a tx" (respectively). I think "objects first" is probably the best way to go, since there's no easy way to get the user or authority signatures on a
Now, to answer some other questions:
Genesis is a one-time event at the beginning of the network. The logic to generate the genesis state should be hardcoded in the validator
There is already an init function in the Sui Framework here, and I expect that we will add more over time. So that's more motivation for approach 1. |
All sounds good to me! |
Yes what Adam suggested is along the right direction. |
c914e34
to
79b33da
Compare
79b33da
to
64558e8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you! Wouldn't mind a second pair of eyes from @awelc on the adapter publishing refactoring.
@@ -484,7 +495,8 @@ impl AuthorityState { | |||
name: AuthorityName, | |||
secret: StableSyncAuthoritySigner, | |||
store: Arc<AuthorityStore>, | |||
genesis_modules: Vec<Object>, | |||
genesis_packages: Vec<Vec<CompiledModule>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did we change the parameter from Vec<Object>
to Vec<Vec<CompiledModule>>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason is that we need to access the CompiledModule
instead of Object
for module initialization
sui_core/src/authority.rs
Outdated
temporary_store.ensure_active_inputs_mutated(); | ||
let unwrapped_object_ids = self.get_unwrapped_object_ids(temporary_store.written())?; | ||
temporary_store.patch_unwrapped_object_version(unwrapped_object_ids); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are not necessary for the genesis case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done. But could you explain why the unwrap case is not necessary for the genesis case? I think in theory developers can unwrap objects in init
?
8d4d439
to
904e51f
Compare
56c41f6
to
daeddb7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
daeddb7
to
618f0a9
Compare
This commit extracts module initialization from adapter::publish into a new function so that it can be reused in Genesis.
…in Genesis To address comment in #542
618f0a9
to
8745bac
Compare
…in Genesis To address comment in #542
#503
Note to reviewers: This revision passes all the tests but is not very polished yet. Just wanted to get some early feedback on the approach and improvement areas.
The first four commits are simple refactoring, and the core changes are in the fifth commit.