-
Notifications
You must be signed in to change notification settings - Fork 1.6k
[Feature] Introduce constructor, Operand::Checksum and Operand::Edition
#2653
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
Changes from 13 commits
9b92e7c
de65282
341078d
0f19c3a
5906dfe
8f97617
0710e19
091f43f
b28c317
9f2e8e0
1277470
d032476
2ca3f04
e2c4f75
5da640e
9646b02
60784ef
b2dcf99
8179ffb
2f35cf9
ede2b81
f4aa8a2
542adb7
cb1ea9f
83b319e
56f27ad
e0d0882
fd173bc
3e0b08c
01e228e
c4e8c3b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -66,8 +66,17 @@ impl<N: Network> Process<N> { | |
| // Initialize the mapping. | ||
| finalize_operations.push(store.initialize_mapping(*program_id, *mapping.name())?); | ||
| } | ||
| finish!(timer, "Initialize the program mappings"); | ||
| lap!(timer, "Initialize the program mappings"); | ||
|
|
||
| // If the program has a constructor, execute it and extend the finalize operations. | ||
|
d0cd marked this conversation as resolved.
|
||
| // This must happen after the mappings are initialized as the constructor may depend on them. | ||
| if deployment.program().contains_constructor() { | ||
| let operations = finalize_constructor(state, store, &stack, *fee.transition_id())?; | ||
| finalize_operations.extend(operations); | ||
| lap!(timer, "Execute the constructor"); | ||
| } | ||
|
|
||
| finish!(timer, "Finished finalizing the deployment"); | ||
| // Return the stack and finalize operations. | ||
| Ok((stack, finalize_operations)) | ||
| }) | ||
|
|
@@ -183,6 +192,101 @@ fn finalize_fee_transition<N: Network, P: FinalizeStorage<N>>( | |
| } | ||
| } | ||
|
|
||
| /// Finalizes the constructor. | ||
| fn finalize_constructor<N: Network, P: FinalizeStorage<N>>( | ||
| state: FinalizeGlobalState, | ||
| store: &FinalizeStore<N, P>, | ||
| stack: &Stack<N>, | ||
| transition_id: N::TransitionID, | ||
| ) -> Result<Vec<FinalizeOperation<N>>> { | ||
| // Retrieve the program ID. | ||
| let program_id = stack.program_id(); | ||
| #[cfg(debug_assertions)] | ||
| println!("Finalizing constructor for {}...", stack.program_id()); | ||
|
|
||
| // Initialize a list for finalize operations. | ||
| let mut finalize_operations = Vec::new(); | ||
|
|
||
| // Initialize a nonce for the constructor registers. | ||
| // Currently, this nonce is set to zero for every constructor. | ||
| let nonce = 0; | ||
|
|
||
| // Get the constructor logic. If the program does not have a constructor, return early. | ||
| let Some(constructor) = stack.program().constructor() else { | ||
| return Ok(finalize_operations); | ||
| }; | ||
|
|
||
| // Get the constructor types. | ||
| let constructor_types = stack.get_constructor_types()?.clone(); | ||
|
|
||
| // Initialize the finalize registers. | ||
| let mut registers = FinalizeRegisters::new(state, transition_id, *program_id.name(), constructor_types, nonce); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Auditors: The parameters used to initialize the FinalizeRegisters here should be reviewed for correctness and soundness.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @d0cd make sure to go over all unresolved comments and copy them over in the new PR you're making.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gonna keep this PR, but I think we're all resolved in this one no? |
||
|
|
||
| // Initialize a counter for the commands. | ||
| let mut counter = 0; | ||
|
|
||
| // Evaluate the commands. | ||
| while counter < constructor.commands().len() { | ||
|
raychu86 marked this conversation as resolved.
|
||
| // Retrieve the command. | ||
| let command = &constructor.commands()[counter]; | ||
| // Finalize the command. | ||
| match &command { | ||
| Command::BranchEq(branch_eq) => { | ||
| let result = | ||
| try_vm_runtime!(|| branch_to(counter, branch_eq, constructor.positions(), stack, ®isters)); | ||
| match result { | ||
| Ok(Ok(new_counter)) => { | ||
| counter = new_counter; | ||
| } | ||
| // If the evaluation fails, bail and return the error. | ||
| Ok(Err(error)) => bail!("'constructor' failed to evaluate command ({command}): {error}"), | ||
| // If the evaluation fails, bail and return the error. | ||
| Err(_) => bail!("'constructor' failed to evaluate command ({command})"), | ||
| } | ||
| } | ||
| Command::BranchNeq(branch_neq) => { | ||
| let result = | ||
| try_vm_runtime!(|| branch_to(counter, branch_neq, constructor.positions(), stack, ®isters)); | ||
| match result { | ||
| Ok(Ok(new_counter)) => { | ||
| counter = new_counter; | ||
| } | ||
| // If the evaluation fails, bail and return the error. | ||
| Ok(Err(error)) => bail!("'constructor' failed to evaluate command ({command}): {error}"), | ||
| // If the evaluation fails, bail and return the error. | ||
| Err(_) => bail!("'constructor' failed to evaluate command ({command})"), | ||
| } | ||
| } | ||
| Command::Await(_) => { | ||
| bail!("Cannot `await` a Future in a constructor") | ||
| } | ||
| _ => { | ||
| let result = try_vm_runtime!(|| command.finalize(stack, store, &mut registers)); | ||
| match result { | ||
| // If the evaluation succeeds with an operation, add it to the list. | ||
| Ok(Ok(Some(finalize_operation))) => finalize_operations.push(finalize_operation), | ||
| // If the evaluation succeeds with no operation, continue. | ||
| Ok(Ok(None)) => {} | ||
| // If the evaluation fails, bail and return the error. | ||
| Ok(Err(error)) => { | ||
| println!("'constructor' failed to evaluate command ({command}): {error}"); | ||
| bail!("'constructor' failed to evaluate command ({command}): {error}") | ||
| } | ||
| // If the evaluation fails, bail and return the error. | ||
| Err(_) => { | ||
| println!("'constructor' failed to evaluate command ({command})"); | ||
| bail!("'constructor' failed to evaluate command ({command})") | ||
| } | ||
| } | ||
| counter += 1; | ||
| } | ||
| }; | ||
| } | ||
|
|
||
| // Return the finalize operations. | ||
| Ok(finalize_operations) | ||
| } | ||
|
|
||
| /// Finalizes the given transition. | ||
| fn finalize_transition<N: Network, P: FinalizeStorage<N>>( | ||
| state: FinalizeGlobalState, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.