-
Notifications
You must be signed in to change notification settings - Fork 1.5k
avoid tx root derivation #2942
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
base: staging
Are you sure you want to change the base?
avoid tx root derivation #2942
Changes from all commits
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 |
|---|---|---|
|
|
@@ -19,7 +19,9 @@ mod bytes; | |
| mod serialize; | ||
| mod string; | ||
|
|
||
| use crate::Transaction; | ||
| use std::sync::OnceLock; | ||
|
|
||
| use crate::{Transaction, transaction::DeploymentID}; | ||
| use console::{ | ||
| network::prelude::*, | ||
| program::{Address, Identifier, ProgramID}, | ||
|
|
@@ -30,6 +32,8 @@ use snarkvm_synthesizer_snark::{Certificate, VerifyingKey}; | |
|
|
||
| #[derive(Clone)] | ||
| pub struct Deployment<N: Network> { | ||
| /// The deployment id | ||
| id: OnceLock<DeploymentID<N>>, | ||
|
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. Would a design be possible where this is just an
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. That would require mutable constructs to deployment all over the code base as when we call |
||
| /// The edition. | ||
| edition: u16, | ||
| /// The program. | ||
|
|
@@ -59,14 +63,20 @@ impl<N: Network> Eq for Deployment<N> {} | |
| impl<N: Network> Deployment<N> { | ||
| /// Initializes a new deployment. | ||
| pub fn new( | ||
| deployment_id: Option<DeploymentID<N>>, | ||
| edition: u16, | ||
| program: Program<N>, | ||
| verifying_keys: Vec<(Identifier<N>, (VerifyingKey<N>, Certificate<N>))>, | ||
| program_checksum: Option<[U8<N>; 32]>, | ||
| program_owner: Option<Address<N>>, | ||
| ) -> Result<Self> { | ||
| // Set the deployment id. | ||
| let id = OnceLock::new(); | ||
| if let Some(inner_id) = deployment_id { | ||
| let _ = id.set(inner_id); | ||
| } | ||
| // Construct the deployment. | ||
| let deployment = Self { edition, program, verifying_keys, program_checksum, program_owner }; | ||
| let deployment = Self { id, edition, program, verifying_keys, program_checksum, program_owner }; | ||
| // Ensure the deployment is ordered. | ||
| deployment.check_is_ordered()?; | ||
| // Return the deployment. | ||
|
|
@@ -206,7 +216,14 @@ impl<N: Network> Deployment<N> { | |
|
|
||
| /// Returns the deployment ID. | ||
| pub fn to_deployment_id(&self) -> Result<Field<N>> { | ||
| Ok(*Transaction::deployment_tree(self)?.root()) | ||
| if let Some(id) = self.id.get() { | ||
| return Ok(*id); | ||
| } | ||
|
|
||
| let id = *Transaction::deployment_tree(self)?.root(); | ||
| let _ = self.id.set(id); | ||
|
|
||
| Ok(id) | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -296,6 +313,7 @@ function compute: | |
| // Create a new deployment with the desired edition. | ||
| // Note the only valid editions for V1 deployments are 0 and 1. | ||
| Deployment::<CurrentNetwork>::new( | ||
| None, | ||
| edition % 2, | ||
| deployment.program().clone(), | ||
| deployment.verifying_keys().clone(), | ||
|
|
@@ -340,6 +358,7 @@ function compute: | |
| .clone(); | ||
| // Create a new deployment with the desired edition. | ||
| Deployment::<CurrentNetwork>::new( | ||
| None, | ||
| edition, | ||
| deployment.program().clone(), | ||
| deployment.verifying_keys().clone(), | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,7 +25,11 @@ impl<N: Network> Serialize for Deployment<N> { | |
| DeploymentVersion::V1 => 3, | ||
| DeploymentVersion::V2 => 5, | ||
| }; | ||
| let mut deployment = serializer.serialize_struct("Deployment", len)?; | ||
| let mut deployment = | ||
| serializer.serialize_struct("Deployment", len + self.id.get().is_some() as usize)?; | ||
| if let Some(id) = self.id.get() { | ||
| deployment.serialize_field("id", id)?; | ||
|
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. Not backwards compatible. |
||
| } | ||
| deployment.serialize_field("edition", &self.edition)?; | ||
| deployment.serialize_field("program", &self.program)?; | ||
| deployment.serialize_field("verifying_keys", &self.verifying_keys)?; | ||
|
|
@@ -52,6 +56,8 @@ impl<'de, N: Network> Deserialize<'de> for Deployment<N> { | |
|
|
||
| // Recover the deployment. | ||
| let deployment = Self::new( | ||
| serde_json::from_value(deployment.get_mut("id").unwrap_or(&mut serde_json::Value::Null).take()) | ||
| .map_err(de::Error::custom)?, | ||
| // Retrieve the edition. | ||
| DeserializeExt::take_from_value::<D>(&mut deployment, "edition")?, | ||
| // Retrieve the program. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,14 +17,18 @@ mod bytes; | |
| mod serialize; | ||
| mod string; | ||
|
|
||
| use crate::{Transaction, Transition}; | ||
| use std::sync::OnceLock; | ||
|
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. please move down to line 26 so external dependencies are in the same place |
||
|
|
||
| use crate::{Transaction, Transition, transaction::ExecutionID}; | ||
| use console::{account::Field, network::prelude::*, program::ProgramID}; | ||
| use snarkvm_synthesizer_snark::Proof; | ||
|
|
||
| use indexmap::IndexMap; | ||
|
|
||
| #[derive(Clone, Default, PartialEq, Eq)] | ||
| pub struct Execution<N: Network> { | ||
| /// The execution id | ||
| id: OnceLock<ExecutionID<N>>, | ||
| /// The transitions. | ||
| transitions: IndexMap<N::TransitionID, Transition<N>>, | ||
| /// The global state root. | ||
|
|
@@ -36,17 +40,28 @@ pub struct Execution<N: Network> { | |
| impl<N: Network> Execution<N> { | ||
| /// Initialize a new `Execution` instance. | ||
| pub fn new() -> Self { | ||
| Self { transitions: Default::default(), global_state_root: Default::default(), proof: None } | ||
| Self { | ||
| id: Default::default(), | ||
| transitions: Default::default(), | ||
| global_state_root: Default::default(), | ||
| proof: None, | ||
| } | ||
| } | ||
|
|
||
| /// Initializes a new `Execution` instance with the given transitions. | ||
| pub fn from( | ||
| excution_id: Option<ExecutionID<N>>, | ||
| transitions: impl Iterator<Item = Transition<N>>, | ||
| global_state_root: N::StateRoot, | ||
| proof: Option<Proof<N>>, | ||
| ) -> Result<Self> { | ||
| let id = OnceLock::new(); | ||
| if let Some(inner_id) = excution_id { | ||
| let _ = id.set(inner_id); | ||
| } | ||
|
|
||
| // Construct the execution. | ||
| let execution = Self { transitions: transitions.map(|t| (*t.id(), t)).collect(), global_state_root, proof }; | ||
| let execution = Self { id, transitions: transitions.map(|t| (*t.id(), t)).collect(), global_state_root, proof }; | ||
| // Ensure the transitions are not empty. | ||
| ensure!(!execution.transitions.is_empty(), "Execution cannot initialize from empty list of transitions"); | ||
| // Return the new `Execution` instance. | ||
|
|
@@ -70,7 +85,14 @@ impl<N: Network> Execution<N> { | |
|
|
||
| /// Returns the execution ID. | ||
| pub fn to_execution_id(&self) -> Result<Field<N>> { | ||
| Ok(*Transaction::execution_tree(self)?.root()) | ||
| if let Some(id) = self.id.get() { | ||
| return Ok(*id); | ||
| } | ||
|
|
||
| let id = *Transaction::execution_tree(self)?.root(); | ||
| let _ = self.id.set(id); | ||
|
|
||
| Ok(id) | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -157,7 +179,7 @@ pub mod test_helpers { | |
| // Retrieve a transaction. | ||
| let transaction = block.transactions().iter().nth(index).unwrap().deref().clone(); | ||
| // Retrieve the execution. | ||
| if let Transaction::Execute(_, _, execution, _) = transaction { | ||
| if let Transaction::Execute(_, execution, _) = transaction { | ||
| *execution | ||
| } else { | ||
| panic!("Index {index} exceeded the number of executions in the genesis block") | ||
|
|
||
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.
Can this be made backwards compatible?