Skip to content

Commit

Permalink
Merge pull request #2443 from AleoHQ/fix/restrict-bond-public-as-vali…
Browse files Browse the repository at this point in the history
…dator-to-user

[Fix] Restrict `bond_public` as validator to users only.
  • Loading branch information
howardwu authored Apr 29, 2024
2 parents eedf4c8 + b174c12 commit 1485bdd
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 8 deletions.
6 changes: 3 additions & 3 deletions parameters/src/mainnet/resources/bond_public.metadata
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"prover_checksum": "f22e621043e90a085cccff02496da7a4e61e565a910133a7f7ba164a38690ac4",
"prover_size": 29351562,
"verifier_checksum": "6cb877e752e5127f6e13e6e0804a5858366752b578a4dfde47edf24deebb846d",
"prover_checksum": "2f0d0703e3ce260286c40830015b1376c644f73dac5ca57cd7c67074e35ef32a",
"prover_size": 29353850,
"verifier_checksum": "f4d689b5252ef4243abd7ee8acea3e6e9d0fb137d85908b6a04661d58490d469",
"verifier_size": 665
}
Binary file modified parameters/src/mainnet/resources/bond_public.verifier
Binary file not shown.
6 changes: 3 additions & 3 deletions parameters/src/testnet/resources/bond_public.metadata
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"prover_checksum": "2398c8283c4fd286e3e506ea88732d2a99c728fb590ca19857f4a3cc47e6c929",
"prover_size": 29351562,
"verifier_checksum": "5137cf6ed3d651a8d31462e36b4a1e689080b024e741a573badfe7a112459efc",
"prover_checksum": "bd3bf4fbe066a1a749d9fbcabb0a324db4f9cc2d4cb9c42b5c4babd1a482d464",
"prover_size": 29353850,
"verifier_checksum": "198a9aa7d4ed09343dc54df66dcfc089f5548d9c3201849d1b7cece1ed5b2b47",
"verifier_size": 665
}
Binary file modified parameters/src/testnet/resources/bond_public.verifier
Binary file not shown.
12 changes: 10 additions & 2 deletions synthesizer/program/src/resources/credits.aleo
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,18 @@ function bond_public:
// Enforce the amount is at least one credit.
assert.eq r3 true;

// Determine if the caller is attempting to bond as a validator.
is.eq self.caller r0 into r4;
// Determine if the caller is a user account.
is.eq self.caller self.signer into r5;
// If the caller is attempting to bond as a validator, enforce the caller is a user account.
ternary r4 r5 true into r6;
assert.eq r6 true;

// Bond the specified amount of microcredits to the specified validator.
async bond_public self.caller r0 r1 r2 into r4;
async bond_public self.caller r0 r1 r2 into r7;
// Output the finalize future.
output r4 as credits.aleo/bond_public.future;
output r7 as credits.aleo/bond_public.future;

finalize bond_public:
// Input the staker's address.
Expand Down
150 changes: 150 additions & 0 deletions synthesizer/src/vm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2460,6 +2460,156 @@ finalize transfer_public_to_private:
vm.add_next_block(&block).unwrap();
}

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

// Initialize a genesis private key..
let genesis_private_key = sample_genesis_private_key(rng);

// Initialize a caller.
let caller_private_key = PrivateKey::new(rng).unwrap();
let caller_address = Address::try_from(&caller_private_key).unwrap();

// Initialize the genesis block.
let genesis = sample_genesis_block(rng);

// Initialize the VM.
let vm = sample_vm();

// Update the VM.
vm.add_next_block(&genesis).unwrap();

// Deploy a program that calls `bond_public`.
let program = Program::from_str(
r"
import credits.aleo;
program credits_wrapper.aleo;
function bond_public:
input r0 as address.public;
input r1 as address.public;
input r2 as u64.public;
call credits.aleo/transfer_public_as_signer credits_wrapper.aleo r2 into r3;
call credits.aleo/bond_public r0 r1 r2 into r4;
async bond_public r3 r4 into r5;
output r5 as credits_wrapper.aleo/bond_public.future;
finalize bond_public:
input r0 as credits.aleo/transfer_public_as_signer.future;
input r1 as credits.aleo/bond_public.future;
await r0;
await r1;
",
)
.unwrap();

// Get the address of the wrapper program.
let wrapper_program_id = ProgramID::<CurrentNetwork>::from_str("credits_wrapper.aleo").unwrap();

// Deploy the wrapper program.
let deployment = vm.deploy(&genesis_private_key, &program, None, 0, None, rng).unwrap();

// Transfer credits to the caller.
let transaction = vm
.execute(
&genesis_private_key,
("credits.aleo", "transfer_public_as_signer"),
vec![
Value::from_str(&format!("{}", caller_address)).unwrap(),
Value::from_str(&format!("{}u64", 3 * ledger_committee::MIN_VALIDATOR_STAKE)).unwrap(),
]
.iter(),
None,
0,
None,
rng,
)
.unwrap();

// Add the deployment to a block and update the VM.
let block = sample_next_block(&vm, &genesis_private_key, &[deployment, transaction], rng).unwrap();

// Check that both transactions were accepted.
assert_eq!(block.transactions().num_accepted(), 2);

// Update the VM.
vm.add_next_block(&block).unwrap();

// Call the wrapper program to bond as a validator.
let result = vm.execute(
&caller_private_key,
("credits_wrapper.aleo", "bond_public"),
vec![
Value::from_str(&format!("{}", wrapper_program_id.to_address().unwrap())).unwrap(),
Value::from_str(&format!("{}", wrapper_program_id.to_address().unwrap())).unwrap(),
Value::from_str(&format!("{}u64", ledger_committee::MIN_VALIDATOR_STAKE)).unwrap(),
]
.iter(),
None,
0,
None,
rng,
);

// Verify that the execution failed.
assert!(result.is_err());

// Check that the caller is not a validator.
let committee_mapping_name = Identifier::from_str("committee").unwrap();
let is_validator = vm
.finalize_store()
.get_value_confirmed(
ProgramID::from_str("credits.aleo").unwrap(),
committee_mapping_name,
&Plaintext::from(Literal::Address(caller_address)),
)
.unwrap()
.is_some();
assert!(!is_validator);

// Bond using the credits.aleo program.
let transaction = vm
.execute(
&caller_private_key,
("credits.aleo", "bond_public"),
vec![
Value::from_str(&format!("{caller_address}")).unwrap(),
Value::from_str(&format!("{caller_address}")).unwrap(),
Value::from_str(&format!("{}u64", ledger_committee::MIN_VALIDATOR_STAKE)).unwrap(),
]
.iter(),
None,
0,
None,
rng,
)
.unwrap();

// Verify the transaction.
vm.check_transaction(&transaction, None, rng).unwrap();

// Add the transaction to a block and update the VM.
let block = sample_next_block(&vm, &genesis_private_key, &[transaction], rng).unwrap();

// Update the VM.
vm.add_next_block(&block).unwrap();

// Check that the caller is now a validator.
let committee_mapping_name = Identifier::from_str("committee").unwrap();
let is_validator = vm
.finalize_store()
.get_value_confirmed(
ProgramID::from_str("credits.aleo").unwrap(),
committee_mapping_name,
&Plaintext::from(Literal::Address(caller_address)),
)
.unwrap()
.is_some();
assert!(is_validator);
}

#[test]
fn test_vm_puzzle() {
// Attention: This test is used to ensure that the VM has performed downcasting correctly for
Expand Down

0 comments on commit 1485bdd

Please sign in to comment.