Skip to content

Commit

Permalink
Merge pull request #71 from dusk-network/fetchnote-height
Browse files Browse the repository at this point in the history
Change `fetch_notes`
  • Loading branch information
herr-seppia authored Jan 5, 2023
2 parents 66bda1d + 1812cf3 commit 6d67f2b
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 19 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "dusk-wallet-core"
version = "0.14.1-rc.1"
version = "0.15.0-rc.0"
edition = "2021"
description = "The core functionality of the Dusk wallet"
license = "MPL-2.0"
Expand Down
28 changes: 19 additions & 9 deletions src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ use rusk_abi::ContractId;

use crate::tx::UnprovenTransaction;
use crate::{
BalanceInfo, Error, ProverClient, StakeInfo, StateClient, Store,
Transaction, Wallet, POSEIDON_TREE_DEPTH,
BalanceInfo, EnrichedNote, Error, ProverClient, StakeInfo, StateClient,
Store, Transaction, Wallet, POSEIDON_TREE_DEPTH,
};

extern "C" {
Expand All @@ -44,9 +44,12 @@ extern "C" {
/// Asks the node to finds the notes for a specific view key.
///
/// An implementor should allocate - see [`malloc`] - a buffer large enough
/// to contain the serialized notes and write them all in sequence. A
/// pointer to the first element of the buffer should then be written in
/// `notes`, while the number of bytes written should be put in `notes_len`.
/// to contain the serialized notes (and the corresponding block height) and
/// write them all in sequence. A pointer to the first element of the
/// buffer should then be written in `notes`, while the number of bytes
/// written should be put in `notes_len`.
///
/// E.g: note1, block_height, note2, block_height, etc...
fn fetch_notes(
vk: *const [u8; ViewKey::SIZE],
notes: *mut *mut u8,
Expand Down Expand Up @@ -347,7 +350,10 @@ struct FfiStateClient;
impl StateClient for FfiStateClient {
type Error = u8;

fn fetch_notes(&self, vk: &ViewKey) -> Result<Vec<Note>, Self::Error> {
fn fetch_notes(
&self,
vk: &ViewKey,
) -> Result<Vec<EnrichedNote>, Self::Error> {
let mut notes_ptr = ptr::null_mut();
let mut notes_len = 0;

Expand All @@ -367,14 +373,18 @@ impl StateClient for FfiStateClient {
)
};

let num_notes = notes_len as usize / Note::SIZE;
let num_notes = notes_len as usize / (Note::SIZE + u64::SIZE);
let mut notes = Vec::with_capacity(num_notes);

let mut buf = &notes_buf[..];
for _ in 0..num_notes {
notes.push(Note::from_reader(&mut buf).map_err(
let note = Note::from_reader(&mut buf).map_err(
Error::<FfiStore, FfiStateClient, FfiProverClient>::from,
)?);
)?;
let block_height = u64::from_reader(&mut buf).map_err(
Error::<FfiStore, FfiStateClient, FfiProverClient>::from,
)?;
notes.push((note, block_height));
}

Ok(notes)
Expand Down
4 changes: 2 additions & 2 deletions src/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ where
self.state.fetch_notes(&vk).map_err(Error::from_state_err)?;

let nullifiers: Vec<_> =
notes.iter().map(|n| n.gen_nullifier(ssk)).collect();
notes.iter().map(|(n, _)| n.gen_nullifier(ssk)).collect();

let existing_nullifiers = self
.state
Expand All @@ -216,7 +216,7 @@ where
.into_iter()
.zip(nullifiers.into_iter())
.filter(|(_, nullifier)| !existing_nullifiers.contains(nullifier))
.map(|(note, _)| note)
.map(|((note, _), _)| note)
.collect();

Ok(unspent_notes)
Expand Down
11 changes: 10 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,22 @@ pub trait ProverClient {
) -> Result<Proof, Self::Error>;
}

/// Block height representation
pub type BlockHeight = u64;

/// Tuple containing Note and Block height
pub type EnrichedNote = (Note, BlockHeight);

/// Types that are clients of the state API.
pub trait StateClient {
/// Error returned by the node client.
type Error;

/// Find notes for a view key.
fn fetch_notes(&self, vk: &ViewKey) -> Result<Vec<Note>, Self::Error>;
fn fetch_notes(
&self,
vk: &ViewKey,
) -> Result<Vec<EnrichedNote>, Self::Error>;

/// Fetch the current anchor of the state.
fn fetch_anchor(&self) -> Result<BlsScalar, Self::Error>;
Expand Down
15 changes: 9 additions & 6 deletions tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use dusk_plonk::prelude::Proof;
use dusk_poseidon::tree::PoseidonBranch;
use dusk_schnorr::Signature;
use dusk_wallet_core::{
ProverClient, StakeInfo, StateClient, Store, Transaction,
EnrichedNote, ProverClient, StakeInfo, StateClient, Store, Transaction,
UnprovenTransaction, Wallet, POSEIDON_TREE_DEPTH,
};
use phoenix_core::{Crossover, Fee, Note, NoteType};
Expand Down Expand Up @@ -90,12 +90,12 @@ fn new_notes<Rng: RngCore + CryptoRng>(
rng: &mut Rng,
psk: &PublicSpendKey,
note_values: &[u64],
) -> Vec<Note> {
) -> Vec<EnrichedNote> {
note_values
.iter()
.map(|val| {
let blinder = JubJubScalar::random(rng);
Note::new(rng, NoteType::Obfuscated, psk, *val, blinder)
(Note::new(rng, NoteType::Obfuscated, psk, *val, blinder), 0)
})
.collect()
}
Expand Down Expand Up @@ -126,15 +126,15 @@ impl Store for TestStore {
/// A state client that always returns the same notes, anchor, and opening.
#[derive(Debug, Clone)]
pub struct TestStateClient {
notes: Vec<Note>,
notes: Vec<EnrichedNote>,
anchor: BlsScalar,
opening: PoseidonBranch<POSEIDON_TREE_DEPTH>,
}

impl TestStateClient {
/// Create a new node given the notes, anchor, and opening we will return.
fn new(
notes: Vec<Note>,
notes: Vec<EnrichedNote>,
anchor: BlsScalar,
opening: PoseidonBranch<POSEIDON_TREE_DEPTH>,
) -> Self {
Expand All @@ -149,7 +149,10 @@ impl TestStateClient {
impl StateClient for TestStateClient {
type Error = ();

fn fetch_notes(&self, _: &ViewKey) -> Result<Vec<Note>, Self::Error> {
fn fetch_notes(
&self,
_: &ViewKey,
) -> Result<Vec<EnrichedNote>, Self::Error> {
Ok(self.notes.clone())
}

Expand Down

0 comments on commit 6d67f2b

Please sign in to comment.