Skip to content

Commit

Permalink
rusk: Replace test-wallet with rusk-wallet for testing
Browse files Browse the repository at this point in the history
  • Loading branch information
moCello committed Sep 6, 2024
1 parent 1c36e92 commit d914419
Show file tree
Hide file tree
Showing 11 changed files with 350 additions and 479 deletions.
2 changes: 1 addition & 1 deletion rusk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ rusk-recovery = { version = "0.6", path = "../rusk-recovery", optional = true }
futures = { version = "0.3", optional = true }

[dev-dependencies]
test-wallet = { version = "0.1.0", path = "../test-wallet" }
rusk-wallet = { version = "0.1.0", path = "../rusk-wallet" }
test-context = "0.1"
reqwest = "0.12"
rusk-recovery = { version = "0.6", path = "../rusk-recovery", features = ["state"] }
Expand Down
Binary file added rusk/tests/common/test_wallet.dat
Binary file not shown.
158 changes: 34 additions & 124 deletions rusk/tests/common/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,137 +4,47 @@
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use std::collections::HashMap;
use std::fmt::Debug;
use std::sync::{Arc, RwLock};

use crate::common::block::Block as BlockAwait;

use dusk_bytes::Serializable;
use execution_core::{
signatures::bls::PublicKey as BlsPublicKey,
stake::StakeData,
transfer::{
moonlight::AccountData,
phoenix::{Note, NoteOpening, ViewKey},
},
BlsScalar,
};
use futures::StreamExt;
use rusk::{Error, Result, Rusk};
use test_wallet::{self as wallet, Store};
use tracing::info;
use rusk::{Error, Result};
use rusk_wallet::{SecureWalletFile, Wallet, WalletPath};

#[derive(Debug, Clone)]
pub struct TestStore;

impl Store for TestStore {
type Error = ();

fn get_seed(&self) -> Result<[u8; 64], Self::Error> {
Ok([0; 64])
}
}

#[derive(Clone)]
pub struct TestStateClient {
pub rusk: Rusk,
pub cache: Arc<RwLock<HashMap<Vec<u8>, DummyCacheItem>>>,
#[allow(dead_code)]
pub struct WalletFile {
path: WalletPath,
pwd: Vec<u8>,
}

impl std::fmt::Debug for TestStateClient {
fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Ok(())
impl SecureWalletFile for WalletFile {
fn path(&self) -> &WalletPath {
&self.path
}
}

impl wallet::StateClient for TestStateClient {
type Error = Error;

/// Find notes for a view key, starting from the given block height.
fn fetch_notes(
&self,
vk: &ViewKey,
) -> Result<Vec<(Note, u64)>, Self::Error> {
let cache_read = self.cache.read().unwrap();
let mut vk_cache = if cache_read.contains_key(&vk.to_bytes().to_vec()) {
cache_read.get(&vk.to_bytes().to_vec()).unwrap().clone()
} else {
DummyCacheItem::default()
};

info!("Requesting notes from height {}", vk_cache.last_height);
let vk_bytes = vk.to_bytes();

let stream = self
.rusk
.get_notes(vk_bytes.as_ref(), vk_cache.last_height)
.wait()?;

let response_notes = stream.collect::<Vec<(Note, u64)>>().wait();

for (note, block_height) in response_notes {
// Filter out duplicated notes and update the last
vk_cache.add(note, block_height)
}
drop(cache_read);
self.cache
.write()
.unwrap()
.insert(vk.to_bytes().to_vec(), vk_cache.clone());

Ok(vk_cache.notes)
}

/// Fetch the current root of the state.
fn fetch_root(&self) -> Result<BlsScalar, Self::Error> {
self.rusk.tree_root()
}

fn fetch_existing_nullifiers(
&self,
nullifiers: &[BlsScalar],
) -> Result<Vec<BlsScalar>, Self::Error> {
self.rusk.existing_nullifiers(&nullifiers.to_vec())
}

/// Queries the node to find the opening for a specific note.
fn fetch_opening(&self, note: &Note) -> Result<NoteOpening, Self::Error> {
self.rusk
.tree_opening(*note.pos())?
.ok_or(Error::OpeningPositionNotFound(*note.pos()))
}

fn fetch_stake(&self, pk: &BlsPublicKey) -> Result<StakeData, Self::Error> {
let stake = self.rusk.provisioner(pk)?.unwrap_or(StakeData::EMPTY);
Ok(stake)
}

fn fetch_account(
&self,
pk: &BlsPublicKey,
) -> Result<AccountData, Self::Error> {
let account = self.rusk.account(pk)?;
Ok(account)
}

fn fetch_chain_id(&self) -> Result<u8, Self::Error> {
let chain_id = self.rusk.chain_id()?;
Ok(chain_id)
fn pwd(&self) -> &[u8] {
&self.pwd
}
}

#[derive(Default, Debug, Clone)]
pub struct DummyCacheItem {
notes: Vec<(Note, u64)>,
last_height: u64,
}

impl DummyCacheItem {
fn add(&mut self, note: Note, block_height: u64) {
if !self.notes.contains(&(note.clone(), block_height)) {
self.notes.push((note.clone(), block_height));
self.last_height = block_height;
}
}
#[allow(dead_code)]
pub fn test_wallet() -> Result<Wallet<WalletFile>, Error> {
// the file 'test_wallet.dat' needs to be stored in the current dir
let wallet_path = WalletPath::from(
std::env::current_dir()?
.as_path()
.join("tests")
.join("common")
.join("test_wallet.dat"),
);
let wallet_file = WalletFile {
path: wallet_path,
pwd: blake3::hash(b"mypassword").as_bytes().to_vec(),
};

// Load wallet from the wallet-file, which is a wallet with the seed of
// an array of `0u8`. Check 'rusk-wallet/tests/generate_test_wallet.rs'
// on how to generate such a wallet-file.
println!("the path is: {}", wallet_file.path);
let wallet =
Wallet::from_file(wallet_file).map_err(|_| Error::RestoreFailed)?;

Ok(wallet)
}
97 changes: 39 additions & 58 deletions rusk/tests/rusk-state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use std::sync::{mpsc, Arc};

use execution_core::{
transfer::{
data::TransactionData,
phoenix::{
Note, NoteLeaf, PublicKey as PhoenixPublicKey,
SecretKey as PhoenixSecretKey,
Expand All @@ -29,6 +30,7 @@ use rand::rngs::StdRng;
use rusk::node::{Rusk, RuskTip};
use rusk::Result;
use rusk_abi::VM;
use rusk_wallet::gas::Gas;
use tempfile::tempdir;
use tracing::info;

Expand Down Expand Up @@ -176,22 +178,11 @@ pub fn rusk_state_finalized() -> Result<()> {
#[allow(dead_code)]
// #[tokio::test(flavor = "multi_thread")]
async fn generate_phoenix_txs() -> Result<(), Box<dyn std::error::Error>> {
use common::wallet::{TestStateClient, TestStore};
use std::io::Write;

common::logger();

let tmp = tempdir()?;
let snapshot = toml::from_str(include_str!("./config/bench.toml"))
.expect("Cannot deserialize config");

let rusk = new_state(&tmp, &snapshot, 100_000_000_000)?;

let cache =
Arc::new(std::sync::RwLock::new(std::collections::HashMap::new()));

let wallet =
test_wallet::Wallet::new(TestStore, TestStateClient { rusk, cache });
let wallet = common::wallet::test_wallet()?;

const N_ADDRESSES: usize = 100;

Expand All @@ -204,25 +195,24 @@ async fn generate_phoenix_txs() -> Result<(), Box<dyn std::error::Error>> {

for sender_index in 0..N_ADDRESSES as u8 {
let wallet = wallet.clone();
let mut rng = StdRng::seed_from_u64(0xdead);

let receiver_index = (sender_index + 1) % N_ADDRESSES as u8;
let receiver = wallet.phoenix_public_key(receiver_index).unwrap();

let task = tokio::task::spawn_blocking(move || {
wallet
.phoenix_transfer(
&mut rng,
sender_index,
&receiver,
TRANSFER_VALUE,
GAS_LIMIT,
LUX,
)
.expect("Making a transfer TX should succeed")
});

let tx = task.await.expect("Joining should succeed");
let sender_addr = wallet.addresses()[sender_index as usize].clone();
let receiver_addr = wallet.addresses()[receiver_index as usize].clone();

let tx = wallet
.phoenix_transfer(
&sender_addr,
&receiver_addr,
TRANSFER_VALUE.into(),
rusk_wallet::gas::Gas {
limit: GAS_LIMIT,
price: LUX,
},
)
.await
.expect("Making a transfer TX should succeed");

txs_file.write(hex::encode(tx.to_var_bytes()).as_bytes())?;
txs_file.write(b"\n")?;
}
Expand All @@ -236,24 +226,13 @@ async fn generate_phoenix_txs() -> Result<(), Box<dyn std::error::Error>> {
// - run the test 'generate_moonlight_txs'
// - move the resulting "moonlight-txs" file under "benches/moonlight-txs"
#[allow(dead_code)]
// #[tokio::test(flavor = "multi_thread")]
async fn generate_moonlight_txs() -> Result<(), Box<dyn std::error::Error>> {
use common::wallet::{TestStateClient, TestStore};
// #[test]
fn generate_moonlight_txs() -> Result<(), Box<dyn std::error::Error>> {
use std::io::Write;

common::logger();

let tmp = tempdir()?;
let snapshot = toml::from_str(include_str!("./config/bench.toml"))
.expect("Cannot deserialize config");

let rusk = new_state(&tmp, &snapshot, 100_000_000_000)?;

let cache =
Arc::new(std::sync::RwLock::new(std::collections::HashMap::new()));

let wallet =
test_wallet::Wallet::new(TestStore, TestStateClient { rusk, cache });
let wallet = common::wallet::test_wallet()?;

const N_ADDRESSES: usize = 100;

Expand All @@ -266,23 +245,25 @@ async fn generate_moonlight_txs() -> Result<(), Box<dyn std::error::Error>> {

for sender_index in 0..N_ADDRESSES as u8 {
let wallet = wallet.clone();
let sender = &wallet.addresses()[sender_index as usize];

let receiver_index = (sender_index + 1) % N_ADDRESSES as u8;
let receiver = wallet.account_public_key(receiver_index).unwrap();

let task = tokio::task::spawn_blocking(move || {
wallet
.moonlight_transfer(
sender_index,
receiver,
TRANSFER_VALUE,
GAS_LIMIT,
LUX,
)
.expect("Making a transfer TX should succeed")
});

let tx = task.await.expect("Joining should succeed");
let receiver = wallet.bls_public_key(receiver_index);

let tx = wallet
.moonlight_transaction(
sender,
Some(receiver),
TRANSFER_VALUE.into(),
0.into(),
Gas {
limit: GAS_LIMIT,
price: LUX,
},
None::<TransactionData>,
)
.expect("Making a transfer TX should succeed");

txs_file.write(hex::encode(tx.to_var_bytes()).as_bytes())?;
txs_file.write(b"\n")?;
}
Expand Down
Loading

0 comments on commit d914419

Please sign in to comment.