Skip to content

Commit

Permalink
Merge pull request #2402 from AleoHQ/feat/transfer_public_as_signer
Browse files Browse the repository at this point in the history
[Feature] Add `transfer_public_as_signer` to `credits.aleo`
  • Loading branch information
howardwu authored Mar 22, 2024
2 parents 78d449b + 761d493 commit b924170
Show file tree
Hide file tree
Showing 8 changed files with 805 additions and 4 deletions.
5 changes: 5 additions & 0 deletions parameters/src/mainnet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ impl_local!(TransferPrivateVerifier, "resources/", "transfer_private", "verifier
// TransferPublic
impl_remote!(TransferPublicProver, REMOTE_URL, "resources/", "transfer_public", "prover");
impl_local!(TransferPublicVerifier, "resources/", "transfer_public", "verifier");
// TransferPublicAsSigner
impl_remote!(TransferPublicAsSignerProver, REMOTE_URL, "resources/", "transfer_public_as_signer", "prover");
impl_local!(TransferPublicAsSignerVerifier, "resources/", "transfer_public_as_signer", "verifier");
// TransferPrivateToPublic
impl_remote!(TransferPrivateToPublicProver, REMOTE_URL, "resources/", "transfer_private_to_public", "prover");
impl_local!(TransferPrivateToPublicVerifier, "resources/", "transfer_private_to_public", "verifier");
Expand Down Expand Up @@ -122,6 +125,7 @@ macro_rules! insert_credit_keys {
$crate::insert_key!($map, string, $type<$network>, ("set_validator_state", $crate::mainnet::[<SetValidatorState $variant>]::load_bytes()));
$crate::insert_key!($map, string, $type<$network>, ("transfer_private", $crate::mainnet::[<TransferPrivate $variant>]::load_bytes()));
$crate::insert_key!($map, string, $type<$network>, ("transfer_public", $crate::mainnet::[<TransferPublic $variant>]::load_bytes()));
$crate::insert_key!($map, string, $type<$network>, ("transfer_public_as_signer", $crate::mainnet::[<TransferPublicAsSigner $variant>]::load_bytes()));
$crate::insert_key!($map, string, $type<$network>, ("transfer_private_to_public", $crate::mainnet::[<TransferPrivateToPublic $variant>]::load_bytes()));
$crate::insert_key!($map, string, $type<$network>, ("transfer_public_to_private", $crate::mainnet::[<TransferPublicToPrivate $variant>]::load_bytes()));
$crate::insert_key!($map, string, $type<$network>, ("join", $crate::mainnet::[<Join $variant>]::load_bytes()));
Expand Down Expand Up @@ -179,6 +183,7 @@ mod tests {
SetValidatorStateVerifier::load_bytes().expect("Failed to load set_validator_state verifier");
TransferPrivateVerifier::load_bytes().expect("Failed to load transfer_private verifier");
TransferPublicVerifier::load_bytes().expect("Failed to load transfer_public verifier");
TransferPublicAsSignerVerifier::load_bytes().expect("Failed to load transfer_public_as_signer verifier");
TransferPrivateToPublicVerifier::load_bytes().expect("Failed to load transfer_private_to_public verifier");
TransferPublicToPrivateVerifier::load_bytes().expect("Failed to load transfer_public_to_private verifier");
FeePrivateProver::load_bytes().expect("Failed to load fee_private prover");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"prover_checksum": "7cfc669dd92593e052a8a37d6b3a7c40d09f191c754b41230f69e19e9d0f9c76",
"prover_size": 28915282,
"verifier_checksum": "18e99de56f2098b27318dc9b92eee1743792837c27a4a7001ef19a42c7dbb798",
"verifier_size": 665
}
Binary file not shown.
28 changes: 28 additions & 0 deletions synthesizer/process/src/tests/test_credits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2088,6 +2088,34 @@ mod sanity_checks {
assert_eq!((28243, 38006, 16679), assignment.num_nonzeros());
}

#[test]
fn test_sanity_check_transfer_public_as_signer() {
let rng = &mut TestRng::default();

// Initialize a new signer account.
let private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let signer = Address::try_from(&private_key).unwrap();

// Construct a new process.
let process = Process::load().unwrap();
// Retrieve the stack.
let stack = process.get_stack(ProgramID::from_str("credits.aleo").unwrap()).unwrap();

// Declare the function name.
let function_name = Identifier::from_str("transfer_public_as_signer").unwrap();

// Declare the inputs.
let r0 = Value::<CurrentNetwork>::from_str(&format!("{signer}")).unwrap();
let r1 = Value::<CurrentNetwork>::from_str("1_500_000_000_000_000_u64").unwrap();

// Compute the assignment.
let assignment = get_assignment::<_, CurrentAleo>(stack, &private_key, function_name, &[r0, r1], rng);
assert_eq!(11, assignment.num_public());
assert_eq!(12323, assignment.num_private());
assert_eq!(12330, assignment.num_constraints());
assert_eq!((28257, 38029, 16684), assignment.num_nonzeros());
}

#[test]
fn test_sanity_check_fee_private() {
let rng = &mut TestRng::default();
Expand Down
2 changes: 1 addition & 1 deletion synthesizer/process/src/tests/test_execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ output r1 as token.record;",
}

#[test]
fn test_process_execute_transfer_public() {
fn test_process_execute_transfer_public_to_private() {
// Initialize a new program.
let program = Program::<CurrentNetwork>::credits().unwrap();

Expand Down
37 changes: 35 additions & 2 deletions synthesizer/program/src/resources/credits.aleo
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ finalize set_validator_state:
/**********************************************************************************************************************/

// The `transfer_public` function sends the specified amount
// from the sender's `account` to the receiver's `account`.
// from the caller's `account` to the receiver's `account`.
function transfer_public:
// Input the receiver.
input r0 as address.public;
Expand All @@ -725,7 +725,7 @@ function transfer_public:
output r2 as credits.aleo/transfer_public.future;

finalize transfer_public:
// Input the sender.
// Input the caller.
input r0 as address.public;
// Input the receiver.
input r1 as address.public;
Expand All @@ -745,6 +745,39 @@ finalize transfer_public:

/**********************************************************************************************************************/

// The `transfer_public_as_signer` function sends the specified amount
// from the signer's `account` to the receiver's `account`.
function transfer_public_as_signer:
// Input the receiver.
input r0 as address.public;
// Input the amount.
input r1 as u64.public;
// Transfer the credits publicly.
async transfer_public_as_signer self.signer r0 r1 into r2;
// Output the finalize future.
output r2 as credits.aleo/transfer_public_as_signer.future;

finalize transfer_public_as_signer:
// Input the signer.
input r0 as address.public;
// Input the receiver.
input r1 as address.public;
// Input the amount.
input r2 as u64.public;
// Decrements `account[r0]` by `r2`.
// If `account[r0] - r2` underflows, `transfer_public_as_signer` is reverted.
get account[r0] into r3;
sub r3 r2 into r4;
set r4 into account[r0];
// Increments `account[r1]` by `r2`.
// If `account[r1]` does not exist, 0u64 is used.
// If `account[r1] + r2` overflows, `transfer_public_as_signer` is reverted.
get.or_use account[r1] 0u64 into r5;
add r5 r2 into r6;
set r6 into account[r1];

/**********************************************************************************************************************/

// The `transfer_private` function sends the specified amount
// from the sender's record to the receiver in a record.
function transfer_private:
Expand Down
34 changes: 34 additions & 0 deletions synthesizer/src/vm/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,40 @@ mod tests {
}
}

#[test]
fn test_transfer_public_as_signer_transaction_size() {
let rng = &mut TestRng::default();

// Initialize a new signer.
let signer = crate::vm::test_helpers::sample_genesis_private_key(rng);
let address = Address::try_from(&signer).unwrap();

// Prepare the VM and records.
let (vm, _) = prepare_vm(rng).unwrap();

// Prepare the inputs.
let inputs = [
Value::<CurrentNetwork>::from_str(&address.to_string()).unwrap(),
Value::<CurrentNetwork>::from_str("1u64").unwrap(),
]
.into_iter();

// Execute.
let transaction =
vm.execute(&signer, ("credits.aleo", "transfer_public_as_signer"), inputs, None, 0, None, rng).unwrap();

// Assert the size of the transaction.
let transaction_size_in_bytes = transaction.to_bytes_le().unwrap().len();
assert_eq!(2891, transaction_size_in_bytes, "Update me if serialization has changed");

// Assert the size of the execution.
assert!(matches!(transaction, Transaction::Execute(_, _, _)));
if let Transaction::Execute(_, execution, _) = &transaction {
let execution_size_in_bytes = execution.to_bytes_le().unwrap().len();
assert_eq!(1440, execution_size_in_bytes, "Update me if serialization has changed");
}
}

#[test]
fn test_join_transaction_size() {
let rng = &mut TestRng::default();
Expand Down
Loading

0 comments on commit b924170

Please sign in to comment.