-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4c14484
commit 1876644
Showing
8 changed files
with
1,450 additions
and
1,373 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use std::collections::HashSet; | ||
|
||
use tracing::instrument; | ||
|
||
use crate::Error; | ||
|
||
use super::{CheckStateRequest, CheckStateResponse, Mint, ProofState, PublicKey, State}; | ||
|
||
impl Mint { | ||
/// Check state | ||
#[instrument(skip_all)] | ||
pub async fn check_state( | ||
&self, | ||
check_state: &CheckStateRequest, | ||
) -> Result<CheckStateResponse, Error> { | ||
let states = self.localstore.get_proofs_states(&check_state.ys).await?; | ||
|
||
let states = states | ||
.iter() | ||
.zip(&check_state.ys) | ||
.map(|(state, y)| { | ||
let state = match state { | ||
Some(state) => *state, | ||
None => State::Unspent, | ||
}; | ||
|
||
ProofState { | ||
y: *y, | ||
state, | ||
witness: None, | ||
} | ||
}) | ||
.collect(); | ||
|
||
Ok(CheckStateResponse { states }) | ||
} | ||
|
||
/// Check Tokens are not spent or pending | ||
#[instrument(skip_all)] | ||
pub async fn check_ys_spendable( | ||
&self, | ||
ys: &[PublicKey], | ||
proof_state: State, | ||
) -> Result<(), Error> { | ||
let proofs_state = self | ||
.localstore | ||
.update_proofs_states(ys, proof_state) | ||
.await?; | ||
|
||
let proofs_state = proofs_state.iter().flatten().collect::<HashSet<&State>>(); | ||
|
||
if proofs_state.contains(&State::Pending) { | ||
return Err(Error::TokenPending); | ||
} | ||
|
||
if proofs_state.contains(&State::Spent) { | ||
return Err(Error::TokenAlreadySpent); | ||
} | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
use tracing::instrument; | ||
|
||
use crate::mint_url::MintUrl; | ||
|
||
use super::{Mint, MintInfo}; | ||
|
||
impl Mint { | ||
/// Set Mint Url | ||
#[instrument(skip_all)] | ||
pub fn set_mint_url(&mut self, mint_url: MintUrl) { | ||
self.mint_url = mint_url; | ||
} | ||
|
||
/// Get Mint Url | ||
#[instrument(skip_all)] | ||
pub fn get_mint_url(&self) -> &MintUrl { | ||
&self.mint_url | ||
} | ||
|
||
/// Set Mint Info | ||
#[instrument(skip_all)] | ||
pub fn set_mint_info(&mut self, mint_info: MintInfo) { | ||
self.mint_info = mint_info; | ||
} | ||
|
||
/// Get Mint Info | ||
#[instrument(skip_all)] | ||
pub fn mint_info(&self) -> &MintInfo { | ||
&self.mint_info | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
use std::collections::HashSet; | ||
|
||
use tracing::instrument; | ||
|
||
use crate::Error; | ||
|
||
use super::{ | ||
create_new_keyset, derivation_path_from_unit, CurrencyUnit, Id, KeySet, KeySetInfo, | ||
KeysResponse, KeysetResponse, Mint, MintKeySet, MintKeySetInfo, | ||
}; | ||
|
||
impl Mint { | ||
/// Retrieve the public keys of the active keyset for distribution to wallet | ||
/// clients | ||
#[instrument(skip(self))] | ||
pub async fn keyset_pubkeys(&self, keyset_id: &Id) -> Result<KeysResponse, Error> { | ||
self.ensure_keyset_loaded(keyset_id).await?; | ||
let keysets = self.keysets.read().await; | ||
let keyset = keysets.get(keyset_id).ok_or(Error::UnknownKeySet)?.clone(); | ||
Ok(KeysResponse { | ||
keysets: vec![keyset.into()], | ||
}) | ||
} | ||
|
||
/// Retrieve the public keys of the active keyset for distribution to wallet | ||
/// clients | ||
#[instrument(skip_all)] | ||
pub async fn pubkeys(&self) -> Result<KeysResponse, Error> { | ||
let active_keysets = self.localstore.get_active_keysets().await?; | ||
|
||
let active_keysets: HashSet<&Id> = active_keysets.values().collect(); | ||
|
||
for id in active_keysets.iter() { | ||
self.ensure_keyset_loaded(id).await?; | ||
} | ||
|
||
let keysets = self.keysets.read().await; | ||
Ok(KeysResponse { | ||
keysets: keysets | ||
.values() | ||
.filter_map(|k| match active_keysets.contains(&k.id) { | ||
true => Some(k.clone().into()), | ||
false => None, | ||
}) | ||
.collect(), | ||
}) | ||
} | ||
|
||
/// Return a list of all supported keysets | ||
#[instrument(skip_all)] | ||
pub async fn keysets(&self) -> Result<KeysetResponse, Error> { | ||
let keysets = self.localstore.get_keyset_infos().await?; | ||
let active_keysets: HashSet<Id> = self | ||
.localstore | ||
.get_active_keysets() | ||
.await? | ||
.values() | ||
.cloned() | ||
.collect(); | ||
|
||
let keysets = keysets | ||
.into_iter() | ||
.map(|k| KeySetInfo { | ||
id: k.id, | ||
unit: k.unit, | ||
active: active_keysets.contains(&k.id), | ||
input_fee_ppk: k.input_fee_ppk, | ||
}) | ||
.collect(); | ||
|
||
Ok(KeysetResponse { keysets }) | ||
} | ||
|
||
/// Get keysets | ||
#[instrument(skip(self))] | ||
pub async fn keyset(&self, id: &Id) -> Result<Option<KeySet>, Error> { | ||
self.ensure_keyset_loaded(id).await?; | ||
let keysets = self.keysets.read().await; | ||
let keyset = keysets.get(id).map(|k| k.clone().into()); | ||
Ok(keyset) | ||
} | ||
|
||
/// Add current keyset to inactive keysets | ||
/// Generate new keyset | ||
#[instrument(skip(self))] | ||
pub async fn rotate_keyset( | ||
&self, | ||
unit: CurrencyUnit, | ||
derivation_path_index: u32, | ||
max_order: u8, | ||
input_fee_ppk: u64, | ||
) -> Result<(), Error> { | ||
let derivation_path = derivation_path_from_unit(unit, derivation_path_index); | ||
let (keyset, keyset_info) = create_new_keyset( | ||
&self.secp_ctx, | ||
self.xpriv, | ||
derivation_path, | ||
Some(derivation_path_index), | ||
unit, | ||
max_order, | ||
input_fee_ppk, | ||
); | ||
let id = keyset_info.id; | ||
self.localstore.add_keyset_info(keyset_info).await?; | ||
self.localstore.set_active_keyset(unit, id).await?; | ||
|
||
let mut keysets = self.keysets.write().await; | ||
keysets.insert(id, keyset); | ||
|
||
Ok(()) | ||
} | ||
|
||
/// Ensure Keyset is loaded in mint | ||
#[instrument(skip(self))] | ||
pub async fn ensure_keyset_loaded(&self, id: &Id) -> Result<(), Error> { | ||
let keysets = self.keysets.read().await; | ||
if keysets.contains_key(id) { | ||
return Ok(()); | ||
} | ||
drop(keysets); | ||
|
||
let keyset_info = self | ||
.localstore | ||
.get_keyset_info(id) | ||
.await? | ||
.ok_or(Error::UnknownKeySet)?; | ||
let id = keyset_info.id; | ||
let mut keysets = self.keysets.write().await; | ||
keysets.insert(id, self.generate_keyset(keyset_info)); | ||
Ok(()) | ||
} | ||
|
||
/// Generate [`MintKeySet`] from [`MintKeySetInfo`] | ||
#[instrument(skip_all)] | ||
pub fn generate_keyset(&self, keyset_info: MintKeySetInfo) -> MintKeySet { | ||
MintKeySet::generate_from_xpriv( | ||
&self.secp_ctx, | ||
self.xpriv, | ||
keyset_info.max_order, | ||
keyset_info.unit, | ||
keyset_info.derivation_path, | ||
) | ||
} | ||
} |
Oops, something went wrong.