Skip to content

Commit

Permalink
Add variable limit to testnet
Browse files Browse the repository at this point in the history
  • Loading branch information
vicsn committed Apr 15, 2024
1 parent 88b5ffb commit 1db96dd
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
37 changes: 37 additions & 0 deletions circuit/environment/src/testnet_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type Field = <console::TestnetV0 as console::Environment>::Field;

thread_local! {
static CONSTRAINT_LIMIT: Cell<Option<u64>> = Cell::new(None);
static VARIABLE_LIMIT: Cell<Option<u64>> = Cell::new(None);
pub(super) static TESTNET_CIRCUIT: RefCell<R1CS<Field>> = RefCell::new(R1CS::new());
static IN_WITNESS: Cell<bool> = Cell::new(false);
static ZERO: LinearCombination<Field> = LinearCombination::zero();
Expand Down Expand Up @@ -53,6 +54,16 @@ impl Environment for TestnetCircuit {
IN_WITNESS.with(|in_witness| {
// Ensure we are not in witness mode.
if !in_witness.get() {
// Ensure that we do not surpass the variable limit for the circuit.
VARIABLE_LIMIT.with(|variable_limit| {
if let Some(limit) = variable_limit.get() {
// NOTE: we can use this function because circuits only have a single scope.
// Once we have nested scopes, we will need to track the number of variables in each scope.
if Self::num_variables_in_scope() > limit {
Self::halt(format!("Surpassed the variable limit ({limit})"))
}
}
});
TESTNET_CIRCUIT.with(|circuit| match mode {
Mode::Constant => circuit.borrow_mut().new_constant(value),
Mode::Public => circuit.borrow_mut().new_public(value),
Expand Down Expand Up @@ -202,6 +213,11 @@ impl Environment for TestnetCircuit {
TESTNET_CIRCUIT.with(|circuit| circuit.borrow().num_nonzeros())
}

/// Returns the number of variables for the current scope.
fn num_variables_in_scope() -> u64 {
TESTNET_CIRCUIT.with(|circuit| circuit.borrow().num_variables_in_scope())
}

/// Returns the number of constants for the current scope.
fn num_constants_in_scope() -> u64 {
TESTNET_CIRCUIT.with(|circuit| circuit.borrow().num_constants_in_scope())
Expand Down Expand Up @@ -244,20 +260,32 @@ impl Environment for TestnetCircuit {
CONSTRAINT_LIMIT.with(|current_limit| current_limit.replace(limit));
}

/// Returns the variable limit for the circuit, if one exists.
fn get_variable_limit() -> Option<u64> {
VARIABLE_LIMIT.with(|current_limit| current_limit.get())
}

/// Sets the variable limit for the circuit.
fn set_variable_limit(limit: Option<u64>) {
VARIABLE_LIMIT.with(|current_limit| current_limit.replace(limit));
}

/// Returns the R1CS circuit, resetting the circuit.
fn inject_r1cs(r1cs: R1CS<Self::BaseField>) {
TESTNET_CIRCUIT.with(|circuit| {
// Ensure the circuit is empty before injecting.
assert_eq!(0, circuit.borrow().num_constants());
assert_eq!(1, circuit.borrow().num_public());
assert_eq!(0, circuit.borrow().num_private());
assert_eq!(0, circuit.borrow().num_variables_in_scope());
assert_eq!(0, circuit.borrow().num_constraints());
// Inject the R1CS instance.
let r1cs = circuit.replace(r1cs);
// Ensure the circuit that was replaced is empty.
assert_eq!(0, r1cs.num_constants());
assert_eq!(1, r1cs.num_public());
assert_eq!(0, r1cs.num_private());
assert_eq!(0, r1cs.num_variables_in_scope());
assert_eq!(0, r1cs.num_constraints());
})
}
Expand All @@ -269,12 +297,15 @@ impl Environment for TestnetCircuit {
IN_WITNESS.with(|in_witness| in_witness.replace(false));
// Reset the constraint limit.
Self::set_constraint_limit(None);
// Reset the variable limit.
Self::set_variable_limit(None);
// Eject the R1CS instance.
let r1cs = circuit.replace(R1CS::<<Self as Environment>::BaseField>::new());
// Ensure the circuit is now empty.
assert_eq!(0, circuit.borrow().num_constants());
assert_eq!(1, circuit.borrow().num_public());
assert_eq!(0, circuit.borrow().num_private());
assert_eq!(0, circuit.borrow().num_variables_in_scope());
assert_eq!(0, circuit.borrow().num_constraints());
// Return the R1CS instance.
r1cs
Expand All @@ -288,11 +319,14 @@ impl Environment for TestnetCircuit {
IN_WITNESS.with(|in_witness| in_witness.replace(false));
// Reset the constraint limit.
Self::set_constraint_limit(None);
// Reset the variable limit.
Self::set_variable_limit(None);
// Eject the R1CS instance.
let r1cs = circuit.replace(R1CS::<<Self as Environment>::BaseField>::new());
assert_eq!(0, circuit.borrow().num_constants());
assert_eq!(1, circuit.borrow().num_public());
assert_eq!(0, circuit.borrow().num_private());
assert_eq!(0, circuit.borrow().num_variables_in_scope());
assert_eq!(0, circuit.borrow().num_constraints());
// Convert the R1CS instance to an assignment.
Assignment::from(r1cs)
Expand All @@ -306,11 +340,14 @@ impl Environment for TestnetCircuit {
IN_WITNESS.with(|in_witness| in_witness.replace(false));
// Reset the constraint limit.
Self::set_constraint_limit(None);
// Reset the variable limit.
Self::set_variable_limit(None);
// Reset the circuit.
*circuit.borrow_mut() = R1CS::<<Self as Environment>::BaseField>::new();
assert_eq!(0, circuit.borrow().num_constants());
assert_eq!(1, circuit.borrow().num_public());
assert_eq!(0, circuit.borrow().num_private());
assert_eq!(0, circuit.borrow().num_variables_in_scope());
assert_eq!(0, circuit.borrow().num_constraints());
});
}
Expand Down
38 changes: 38 additions & 0 deletions circuit/network/src/testnet_v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,29 @@ thread_local! {
pub struct AleoTestnetV0;

impl Aleo for AleoTestnetV0 {
/// Initializes all of the constants for the Aleo environment.
fn init_constants() {
GENERATOR_G.with(|_| ());
ENCRYPTION_DOMAIN.with(|_| ());
GRAPH_KEY_DOMAIN.with(|_| ());
SERIAL_NUMBER_DOMAIN.with(|_| ());
BHP_256.with(|_| ());
BHP_512.with(|_| ());
BHP_768.with(|_| ());
BHP_1024.with(|_| ());
KECCAK_256.with(|_| ());
KECCAK_384.with(|_| ());
KECCAK_512.with(|_| ());
PEDERSEN_64.with(|_| ());
PEDERSEN_128.with(|_| ());
POSEIDON_2.with(|_| ());
POSEIDON_4.with(|_| ());
POSEIDON_8.with(|_| ());
SHA3_256.with(|_| ());
SHA3_384.with(|_| ());
SHA3_512.with(|_| ());
}

/// Returns the encryption domain as a constant field element.
fn encryption_domain() -> Field<Self> {
ENCRYPTION_DOMAIN.with(|domain| domain.clone())
Expand Down Expand Up @@ -436,6 +459,11 @@ impl Environment for AleoTestnetV0 {
E::num_nonzeros()
}

/// Returns the number of variables for the current scope.
fn num_variables_in_scope() -> u64 {
E::num_variables_in_scope()
}

/// Returns the number of constants for the current scope.
fn num_constants_in_scope() -> u64 {
E::num_constants_in_scope()
Expand Down Expand Up @@ -476,6 +504,16 @@ impl Environment for AleoTestnetV0 {
E::set_constraint_limit(limit)
}

/// Returns the variable limit for the circuit, if one exists.
fn get_variable_limit() -> Option<u64> {
E::get_variable_limit()
}

/// Sets the constraint limit for the circuit.
fn set_variable_limit(limit: Option<u64>) {
E::set_variable_limit(limit)
}

/// Returns the R1CS circuit, resetting the circuit.
fn inject_r1cs(r1cs: R1CS<Self::BaseField>) {
E::inject_r1cs(r1cs)
Expand Down

0 comments on commit 1db96dd

Please sign in to comment.