mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-26 09:05:09 +01:00
Merge pull request #573 from thesimplekid/fix_mint_start_up_keyset
Fix mint start up keyset
This commit is contained in:
15
.github/workflows/ci.yml
vendored
15
.github/workflows/ci.yml
vendored
@@ -180,6 +180,21 @@ jobs:
|
||||
run: nix develop -i -L .#stable --command cargo clippy ${{ matrix.build-args }} -- -D warnings
|
||||
- name: Test fake mint
|
||||
run: nix develop -i -L .#stable --command just fake-mint-itest ${{ matrix.database }}
|
||||
|
||||
pure-itest:
|
||||
name: "Integration fake wallet tests"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Nix
|
||||
uses: DeterminateSystems/nix-installer-action@v11
|
||||
- name: Nix Cache
|
||||
uses: DeterminateSystems/magic-nix-cache-action@v6
|
||||
- name: Rust Cache
|
||||
uses: Swatinem/rust-cache@v2
|
||||
- name: Test fake mint
|
||||
run: nix develop -i -L .#stable --command just test
|
||||
|
||||
msrv-build:
|
||||
name: "MSRV build"
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
* `Wallet::receive_raw` which receives raw binary tokens ([lollerfirst]).
|
||||
|
||||
### Fixed
|
||||
* Multimint unit check when wallet receiving token ([thesimplekid])
|
||||
* Multimint unit check when wallet receiving token ([thesimplekid]).
|
||||
* Mint start up with most recent keyset after a rotation ([thesimplekid]).
|
||||
|
||||
### Removed
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Mint tests
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -10,15 +10,16 @@ use cdk::amount::{Amount, SplitTarget};
|
||||
use cdk::cdk_database::mint_memory::MintMemoryDatabase;
|
||||
use cdk::cdk_database::MintDatabase;
|
||||
use cdk::dhke::construct_proofs;
|
||||
use cdk::mint::MintQuote;
|
||||
use cdk::mint::{FeeReserve, MintBuilder, MintMeltLimits, MintQuote};
|
||||
use cdk::nuts::nut00::ProofsMethods;
|
||||
use cdk::nuts::{
|
||||
CurrencyUnit, Id, MintBolt11Request, MintInfo, NotificationPayload, Nuts, PreMintSecrets,
|
||||
ProofState, Proofs, SecretKey, SpendingConditions, State, SwapRequest,
|
||||
CurrencyUnit, Id, MintBolt11Request, MintInfo, NotificationPayload, Nuts, PaymentMethod,
|
||||
PreMintSecrets, ProofState, Proofs, SecretKey, SpendingConditions, State, SwapRequest,
|
||||
};
|
||||
use cdk::subscription::{IndexableParams, Params};
|
||||
use cdk::util::unix_time;
|
||||
use cdk::Mint;
|
||||
use cdk_fake_wallet::FakeWallet;
|
||||
use tokio::sync::OnceCell;
|
||||
use tokio::time::sleep;
|
||||
|
||||
@@ -335,7 +336,7 @@ async fn test_swap_unbalanced() -> Result<()> {
|
||||
async fn test_swap_overpay_underpay_fee() -> Result<()> {
|
||||
let mint = new_mint(1).await;
|
||||
|
||||
mint.rotate_keyset(CurrencyUnit::Sat, 1, 32, 1, HashMap::new())
|
||||
mint.rotate_keyset(CurrencyUnit::Sat, 1, 32, 1, &HashMap::new())
|
||||
.await?;
|
||||
|
||||
let keys = mint.pubkeys().await?.keysets.first().unwrap().clone().keys;
|
||||
@@ -437,3 +438,69 @@ async fn test_mint_enforce_fee() -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||
async fn test_correct_keyset() -> Result<()> {
|
||||
let mnemonic = Mnemonic::generate(12)?;
|
||||
let fee_reserve = FeeReserve {
|
||||
min_fee_reserve: 1.into(),
|
||||
percent_fee_reserve: 1.0,
|
||||
};
|
||||
|
||||
let database = MintMemoryDatabase::default();
|
||||
|
||||
let fake_wallet = FakeWallet::new(fee_reserve, HashMap::default(), HashSet::default(), 0);
|
||||
|
||||
let mut mint_builder = MintBuilder::new();
|
||||
let localstore = Arc::new(database);
|
||||
mint_builder = mint_builder.with_localstore(localstore.clone());
|
||||
|
||||
mint_builder = mint_builder.add_ln_backend(
|
||||
CurrencyUnit::Sat,
|
||||
PaymentMethod::Bolt11,
|
||||
MintMeltLimits::new(1, 5_000),
|
||||
Arc::new(fake_wallet),
|
||||
);
|
||||
|
||||
mint_builder = mint_builder
|
||||
.with_name("regtest mint".to_string())
|
||||
.with_description("regtest mint".to_string())
|
||||
.with_quote_ttl(10000, 1000)
|
||||
.with_seed(mnemonic.to_seed_normalized("").to_vec());
|
||||
|
||||
let mint = mint_builder.build().await?;
|
||||
|
||||
mint.rotate_next_keyset(CurrencyUnit::Sat, 32, 0).await?;
|
||||
mint.rotate_next_keyset(CurrencyUnit::Sat, 32, 0).await?;
|
||||
|
||||
let active = mint.localstore.get_active_keysets().await?;
|
||||
|
||||
let active = active
|
||||
.get(&CurrencyUnit::Sat)
|
||||
.expect("There is a keyset for unit");
|
||||
|
||||
let keyset_info = mint
|
||||
.localstore
|
||||
.get_keyset_info(active)
|
||||
.await?
|
||||
.expect("There is keyset");
|
||||
|
||||
assert!(keyset_info.derivation_path_index == Some(2));
|
||||
|
||||
let mint = mint_builder.build().await?;
|
||||
|
||||
let active = mint.localstore.get_active_keysets().await?;
|
||||
|
||||
let active = active
|
||||
.get(&CurrencyUnit::Sat)
|
||||
.expect("There is a keyset for unit");
|
||||
|
||||
let keyset_info = mint
|
||||
.localstore
|
||||
.get_keyset_info(active)
|
||||
.await?
|
||||
.expect("There is keyset");
|
||||
|
||||
assert!(keyset_info.derivation_path_index == Some(2));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -96,8 +96,8 @@ impl Mint {
|
||||
derivation_path_index: u32,
|
||||
max_order: u8,
|
||||
input_fee_ppk: u64,
|
||||
custom_paths: HashMap<CurrencyUnit, DerivationPath>,
|
||||
) -> Result<(), Error> {
|
||||
custom_paths: &HashMap<CurrencyUnit, DerivationPath>,
|
||||
) -> Result<MintKeySetInfo, Error> {
|
||||
let derivation_path = match custom_paths.get(&unit) {
|
||||
Some(path) => path.clone(),
|
||||
None => derivation_path_from_unit(unit.clone(), derivation_path_index)
|
||||
@@ -114,13 +114,52 @@ impl Mint {
|
||||
input_fee_ppk,
|
||||
);
|
||||
let id = keyset_info.id;
|
||||
self.localstore.add_keyset_info(keyset_info).await?;
|
||||
self.localstore.add_keyset_info(keyset_info.clone()).await?;
|
||||
self.localstore.set_active_keyset(unit, id).await?;
|
||||
|
||||
let mut keysets = self.keysets.write().await;
|
||||
keysets.insert(id, keyset);
|
||||
|
||||
Ok(())
|
||||
Ok(keyset_info)
|
||||
}
|
||||
|
||||
/// Rotate to next keyset for unit
|
||||
#[instrument(skip(self))]
|
||||
pub async fn rotate_next_keyset(
|
||||
&self,
|
||||
unit: CurrencyUnit,
|
||||
max_order: u8,
|
||||
input_fee_ppk: u64,
|
||||
) -> Result<MintKeySetInfo, Error> {
|
||||
let current_keyset_id = self
|
||||
.localstore
|
||||
.get_active_keyset_id(&unit)
|
||||
.await?
|
||||
.ok_or(Error::UnsupportedUnit)?;
|
||||
|
||||
let keyset_info = self
|
||||
.localstore
|
||||
.get_keyset_info(¤t_keyset_id)
|
||||
.await?
|
||||
.ok_or(Error::UnknownKeySet)?;
|
||||
|
||||
tracing::debug!(
|
||||
"Current active keyset {} path index {:?}",
|
||||
keyset_info.id,
|
||||
keyset_info.derivation_path_index
|
||||
);
|
||||
|
||||
let keyset_info = self
|
||||
.rotate_keyset(
|
||||
unit,
|
||||
keyset_info.derivation_path_index.unwrap_or(1) + 1,
|
||||
max_order,
|
||||
input_fee_ppk,
|
||||
&self.custom_paths,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(keyset_info)
|
||||
}
|
||||
|
||||
/// Ensure Keyset is loaded in mint
|
||||
|
||||
@@ -48,6 +48,7 @@ pub struct Mint {
|
||||
secp_ctx: Secp256k1<secp256k1::All>,
|
||||
xpriv: Xpriv,
|
||||
keysets: Arc<RwLock<HashMap<Id, MintKeySet>>>,
|
||||
custom_paths: HashMap<CurrencyUnit, DerivationPath>,
|
||||
}
|
||||
|
||||
impl Mint {
|
||||
@@ -104,6 +105,7 @@ impl Mint {
|
||||
} else if &highest_index_keyset.input_fee_ppk == input_fee_ppk
|
||||
&& &highest_index_keyset.max_order == max_order
|
||||
{
|
||||
tracing::debug!("Current highest index keyset matches expect fee and max order. Setting active");
|
||||
let id = highest_index_keyset.id;
|
||||
let keyset = MintKeySet::generate_from_xpriv(
|
||||
&secp_ctx,
|
||||
@@ -116,6 +118,7 @@ impl Mint {
|
||||
let mut keyset_info = highest_index_keyset;
|
||||
keyset_info.active = true;
|
||||
localstore.add_keyset_info(keyset_info).await?;
|
||||
active_keyset_units.push(unit.clone());
|
||||
localstore.set_active_keyset(unit, id).await?;
|
||||
continue;
|
||||
} else {
|
||||
@@ -182,6 +185,7 @@ impl Mint {
|
||||
localstore,
|
||||
ln,
|
||||
keysets,
|
||||
custom_paths,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -743,7 +747,7 @@ mod tests {
|
||||
assert!(keysets.keysets.is_empty());
|
||||
|
||||
// generate the first keyset and set it to active
|
||||
mint.rotate_keyset(CurrencyUnit::default(), 0, 1, 1, HashMap::new())
|
||||
mint.rotate_keyset(CurrencyUnit::default(), 0, 1, 1, &HashMap::new())
|
||||
.await?;
|
||||
|
||||
let keysets = mint.keysets().await.unwrap();
|
||||
@@ -752,7 +756,7 @@ mod tests {
|
||||
let first_keyset_id = keysets.keysets[0].id;
|
||||
|
||||
// set the first keyset to inactive and generate a new keyset
|
||||
mint.rotate_keyset(CurrencyUnit::default(), 1, 1, 1, HashMap::new())
|
||||
mint.rotate_keyset(CurrencyUnit::default(), 1, 1, 1, &HashMap::new())
|
||||
.await?;
|
||||
|
||||
let keysets = mint.keysets().await.unwrap();
|
||||
@@ -784,7 +788,7 @@ mod tests {
|
||||
};
|
||||
let mint = create_mint(config).await?;
|
||||
|
||||
mint.rotate_keyset(CurrencyUnit::default(), 0, 32, 1, HashMap::new())
|
||||
mint.rotate_keyset(CurrencyUnit::default(), 0, 32, 1, &HashMap::new())
|
||||
.await?;
|
||||
|
||||
let keys = mint.keysets.read().await.clone();
|
||||
|
||||
Reference in New Issue
Block a user