Skip to content

Commit

Permalink
Add timer for stack operations
Browse files Browse the repository at this point in the history
  • Loading branch information
raychu86 committed Nov 17, 2022
1 parent cecdfdd commit d7b6fe3
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 0 deletions.
8 changes: 8 additions & 0 deletions synthesizer/src/process/stack/authorize.rs
Expand Up @@ -26,6 +26,8 @@ impl<N: Network> Stack<N> {
inputs: impl ExactSizeIterator<Item = impl TryInto<Value<N>>>,
rng: &mut R,
) -> Result<Authorization<N>> {
let timer = timer!("Stack::authorize");

// Ensure the program contains functions.
ensure!(!self.program.functions().is_empty(), "Program '{}' has no functions", self.program.id());

Expand All @@ -44,15 +46,21 @@ impl<N: Network> Stack<N> {
input_types.len()
)
}
lap!(timer, "Verify the number of inputs");

// Compute the request.
let request = Request::sign(private_key, *self.program.id(), function_name, inputs, &input_types, rng)?;
lap!(timer, "Compute the request");
// Initialize the authorization.
let authorization = Authorization::new(&[request.clone()]);
// Construct the call stack.
let call_stack = CallStack::Authorize(vec![request], *private_key, authorization.clone());
// Construct the authorization from the function.
let _response = self.execute_function::<A, R>(call_stack, rng)?;
lap!(timer, "Construct the authorization from the function");

finish!(timer);

// Return the authorization.
Ok(authorization)
}
Expand Down
17 changes: 17 additions & 0 deletions synthesizer/src/process/stack/deploy.rs
Expand Up @@ -20,6 +20,8 @@ impl<N: Network> Stack<N> {
/// Deploys the given program ID, if it does not exist.
#[inline]
pub fn deploy<A: circuit::Aleo<Network = N>, R: Rng + CryptoRng>(&self, rng: &mut R) -> Result<Deployment<N>> {
let timer = timer!("Stack::deploy");

// Ensure the program contains functions.
ensure!(!self.program.functions().is_empty(), "Program '{}' has no functions", self.program.id());

Expand All @@ -29,19 +31,24 @@ impl<N: Network> Stack<N> {
for function_name in self.program.functions().keys() {
// Synthesize the proving and verifying key.
self.synthesize_key::<A, R>(function_name, rng)?;
lap!(timer, "Synthesize key for {function_name}");

// Retrieve the proving key.
let proving_key = self.get_proving_key(function_name)?;
// Retrieve the verifying key.
let verifying_key = self.get_verifying_key(function_name)?;
lap!(timer, "Retrieve the keys for {function_name}");

// Certify the circuit.
let certificate = Certificate::certify(function_name, &proving_key, &verifying_key)?;
lap!(timer, "Certify the circuit");

// Add the verifying key and certificate to the bundle.
bundle.insert(*function_name, (verifying_key, certificate));
}

finish!(timer);

// Return the deployment.
Deployment::new(N::EDITION, self.program.clone(), bundle)
}
Expand All @@ -53,6 +60,8 @@ impl<N: Network> Stack<N> {
deployment: &Deployment<N>,
rng: &mut R,
) -> Result<()> {
let timer = timer!("Stack::verify_deployment");

// Retrieve the edition.
let edition = deployment.edition();
// Retrieve the program.
Expand Down Expand Up @@ -81,6 +90,7 @@ impl<N: Network> Stack<N> {
if verifying_keys.len() != program.functions().len() {
bail!("The number of verifying keys does not match the number of program functions");
}
lap!(timer, "Perform sanity checks");

// Ensure the program functions are in the same order as the verifying keys.
for ((function_name, function), candidate_name) in program.functions().iter().zip_eq(verifying_keys.keys()) {
Expand All @@ -93,6 +103,7 @@ impl<N: Network> Stack<N> {
bail!("The verifier key is '{candidate_name}', but the function name is '{}'", function.name())
}
}
lap!(timer, "Verify the function and verifying key ordering");

// Iterate through the program functions.
for (function, (verifying_key, certificate)) in program.functions().values().zip_eq(verifying_keys.values()) {
Expand All @@ -115,6 +126,7 @@ impl<N: Network> Stack<N> {
_ => self.sample_value(&burner_address, input_type, rng),
})
.collect::<Result<Vec<_>>>()?;
lap!(timer, "Sample the inputs");

// Compute the request, with a burner private key.
let request = Request::sign(
Expand All @@ -125,12 +137,14 @@ impl<N: Network> Stack<N> {
&input_types,
rng,
)?;
lap!(timer, "Compute the request for {}", function.name());
// Initialize the assignments.
let assignments = Assignments::<N>::default();
// Initialize the call stack.
let call_stack = CallStack::CheckDeployment(vec![request], burner_private_key, assignments.clone());
// Synthesize the circuit.
let _response = self.execute_function::<A, R>(call_stack, rng)?;
lap!(timer, "Synthesize the circuit");
// Check the certificate.
match assignments.read().last() {
None => bail!("The assignment for function '{}' is missing in '{program_id}'", function.name()),
Expand All @@ -139,10 +153,13 @@ impl<N: Network> Stack<N> {
if !certificate.verify(function.name(), assignment, verifying_key) {
bail!("The certificate for function '{}' is invalid in '{program_id}'", function.name())
}
lap!(timer, "Ensure the certificate is valid");
}
};
}

finish!(timer);

Ok(())
}
}
20 changes: 20 additions & 0 deletions synthesizer/src/process/stack/evaluate.rs
Expand Up @@ -30,6 +30,8 @@ impl<N: Network> Stack<N> {
caller: Address<N>,
tvk: Field<N>,
) -> Result<Vec<Value<N>>> {
let timer = timer!("Stack::evaluate_closure");

// Ensure the number of inputs matches the number of input statements.
if closure.inputs().len() != inputs.len() {
bail!("Expected {} inputs, found {}", closure.inputs().len(), inputs.len())
Expand All @@ -41,12 +43,14 @@ impl<N: Network> Stack<N> {
registers.set_caller(caller);
// Set the transition view key.
registers.set_tvk(tvk);
lap!(timer, "Initialize the registers");

// Store the inputs.
closure.inputs().iter().map(|i| i.register()).zip_eq(inputs).try_for_each(|(register, input)| {
// Assign the input value to the register.
registers.store(self, register, input.clone())
})?;
lap!(timer, "Store the inputs");

// Evaluate the instructions.
for instruction in closure.instructions() {
Expand All @@ -55,12 +59,16 @@ impl<N: Network> Stack<N> {
bail!("Failed to evaluate instruction ({instruction}): {error}");
}
}
lap!(timer, "Evaluate the instructions");

// Load the outputs.
let outputs = closure.outputs().iter().map(|output| {
// Retrieve the stack value from the register.
registers.load(self, &Operand::Register(output.register().clone()))
});
lap!(timer, "Load the outputs");

finish!(timer);

outputs.collect()
}
Expand All @@ -71,12 +79,15 @@ impl<N: Network> Stack<N> {
/// This method will halt if the given inputs are not the same length as the input statements.
#[inline]
pub fn evaluate_function<A: circuit::Aleo<Network = N>>(&self, call_stack: CallStack<N>) -> Result<Response<N>> {
let timer = timer!("Stack::evaluate_function");

// Retrieve the next request, based on the call stack mode.
let (request, call_stack) = match &call_stack {
CallStack::Evaluate(authorization) => (authorization.next()?, call_stack),
CallStack::Execute(authorization, ..) => (authorization.peek_next()?, call_stack.replicate()),
_ => bail!("Illegal operation: call stack must be `Evaluate` or `Execute` in `evaluate_function`."),
};
lap!(timer, "Retrieve the next request");

// Ensure the network ID matches.
ensure!(
Expand All @@ -102,22 +113,26 @@ impl<N: Network> Stack<N> {
inputs.len()
)
}
lap!(timer, "Perform input checks");

// Initialize the registers.
let mut registers = Registers::<N, A>::new(call_stack, self.get_register_types(function.name())?.clone());
// Set the transition caller.
registers.set_caller(caller);
// Set the transition view key.
registers.set_tvk(tvk);
lap!(timer, "Initialize the registers");

// Ensure the request is well-formed.
ensure!(request.verify(&function.input_types()), "Request is invalid");
lap!(timer, "Verify the request");

// Store the inputs.
function.inputs().iter().map(|i| i.register()).zip_eq(inputs).try_for_each(|(register, input)| {
// Assign the input value to the register.
registers.store(self, register, input.clone())
})?;
lap!(timer, "Store the inputs");

// Evaluate the instructions.
for instruction in function.instructions() {
Expand All @@ -126,9 +141,11 @@ impl<N: Network> Stack<N> {
bail!("Failed to evaluate instruction ({instruction}): {error}");
}
}
lap!(timer, "Evaluate the instructions");

// Retrieve the output registers.
let output_registers = &function.outputs().iter().map(|output| output.register().clone()).collect::<Vec<_>>();
lap!(timer, "Retrieve the output registers");

// Load the outputs.
let outputs = output_registers
Expand All @@ -138,6 +155,9 @@ impl<N: Network> Stack<N> {
registers.load(self, &Operand::Register(register.clone()))
})
.collect::<Result<Vec<_>>>()?;
lap!(timer, "Load the outputs");

finish!(timer);

// Compute the response.
Response::new(
Expand Down

0 comments on commit d7b6fe3

Please sign in to comment.