Skip to content

Commit

Permalink
stake-contract: benchmark for get_provisioners
Browse files Browse the repository at this point in the history
  • Loading branch information
miloszm committed Feb 23, 2024
1 parent 4024762 commit 1ccf0a9
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 0 deletions.
4 changes: 4 additions & 0 deletions contracts/stake/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Added

- Added benchmark for get_provisioners [#1447]

### Changed

- Improved performance of get_provisioners [#1447]
Expand Down
5 changes: 5 additions & 0 deletions contracts/stake/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,8 @@ hex = "0.4"
rand = "0.8"
poseidon-merkle = { version = "0.3", features = ["rkyv-impl"] }
ff = { version = "0.13", default-features = false }
criterion = "0.4"

[[bench]]
name = "get_provisioners"
harness = false
127 changes: 127 additions & 0 deletions contracts/stake/benches/get_provisioners.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use criterion::{criterion_group, criterion_main, Criterion};
use dusk_bls12_381_sign::{PublicKey, SecretKey};
use rand::rngs::StdRng;
use rand::{CryptoRng, RngCore, SeedableRng};
use rusk_abi::{
ContractData, Error, Session, STAKE_CONTRACT, TRANSFER_CONTRACT, VM,
};
use stake_contract_types::StakeData;
use std::sync::mpsc;

const SAMPLE_SIZE: usize = 10;
const NUM_STAKES: usize = 1000;

const OWNER: [u8; 32] = [0; 32];
const POINT_LIMIT: u64 = 0x100000000;
const TEST_STAKE: u64 = 500_000_000_000_000;

fn config() -> Criterion {
Criterion::default().sample_size(SAMPLE_SIZE)
}

fn update_root(session: &mut Session) -> Result<(), Error> {
session
.call(TRANSFER_CONTRACT, "update_root", &(), POINT_LIMIT)
.map(|r| r.data)
}

fn instantiate(vm: &VM) -> Session {
let transfer_bytecode = include_bytes!(
"../../../target/wasm64-unknown-unknown/release/transfer_contract.wasm"
);
let stake_bytecode = include_bytes!(
"../../../target/wasm32-unknown-unknown/release/stake_contract.wasm"
);

let mut session = rusk_abi::new_genesis_session(vm);

session
.deploy(
transfer_bytecode,
ContractData::builder(OWNER).contract_id(TRANSFER_CONTRACT),
POINT_LIMIT,
)
.expect("Deploying the transfer contract should succeed");

session
.deploy(
stake_bytecode,
ContractData::builder(OWNER).contract_id(STAKE_CONTRACT),
POINT_LIMIT,
)
.expect("Deploying the stake contract should succeed");

update_root(&mut session).expect("Updating the root should succeed");

let base = session.commit().expect("Committing should succeed");

rusk_abi::new_session(vm, base, 1)
.expect("Instantiating new session should succeed")
}

fn do_get_provisioners(
session: &mut Session,
) -> Result<impl Iterator<Item = (PublicKey, StakeData)>, Error> {
let (sender, receiver) = mpsc::channel();
session.feeder_call::<_, ()>(STAKE_CONTRACT, "stakes", &(), sender)?;
Ok(receiver.into_iter().map(|bytes| {
rkyv::from_bytes::<(PublicKey, StakeData)>(&bytes)
.expect("The contract should only return (pk, stake_data) tuples")
}))
}

fn do_insert_stake<Rng: RngCore + CryptoRng>(
rng: &mut Rng,
session: &mut Session,
) -> Result<(), Error> {
let stake_data = StakeData {
amount: Some((TEST_STAKE, 0)),
counter: 1,
reward: 0,
};
let sk = SecretKey::random(rng);
let pk = PublicKey::from(&sk);
session.call::<_, ()>(
STAKE_CONTRACT,
"insert_stake",
&(pk, stake_data),
POINT_LIMIT,
)?;
Ok(())
}

fn get_provisioners(c: &mut Criterion) {
let rng = &mut StdRng::seed_from_u64(0xfeeb);

let vm = &mut rusk_abi::new_ephemeral_vm()
.expect("Creating ephemeral VM should work");

let mut session = instantiate(vm);

for _ in 0..NUM_STAKES {
do_insert_stake(rng, &mut session)
.expect("inserting stake should succeed");
}

c.bench_function("get_provisioners", |b| {
b.iter(|| {
let _: Vec<(PublicKey, StakeData)> =
do_get_provisioners(&mut session)
.expect("getting provisioners should succeed")
.collect();
});
});
}

criterion_group!(
name = benches;
config = config();
targets = get_provisioners
);
criterion_main!(benches);

0 comments on commit 1ccf0a9

Please sign in to comment.