Skip to content

Commit

Permalink
chore: upgrade to fedimint 0.3
Browse files Browse the repository at this point in the history
  • Loading branch information
harsh-ps-2003 committed Apr 24, 2024
1 parent 2a7a670 commit 9a092a2
Show file tree
Hide file tree
Showing 22 changed files with 1,823 additions and 1,476 deletions.
2,435 changes: 1,323 additions & 1,112 deletions Cargo.lock

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ license-file = "LICENSE"
keywords = ["bitcoin", "lightning", "chaumian", "e-cash", "federated"]

[workspace.dependencies]
fedimintd = { git = "https://github.com/fedimint/fedimint", tag = "v0.2.1" }
fedimint-cli = { git = "https://github.com/fedimint/fedimint", tag = "v0.2.1" }
fedimint-core = { git = "https://github.com/fedimint/fedimint", tag = "v0.2.1" }
fedimint-client = { git = "https://github.com/fedimint/fedimint", tag = "v0.2.1" }
fedimint-logging = { git = "https://github.com/fedimint/fedimint", tag = "v0.2.1" }
fedimint-server = { git = "https://github.com/fedimint/fedimint", tag = "v0.2.1" }
fedimint-testing = { git = "https://github.com/fedimint/fedimint", tag = "v0.2.1" }
devimint = { git = "https://github.com/fedimint/fedimint", tag = "v0.2.1" }
aead = { git = "https://github.com/fedimint/fedimint", tag = "v0.2.1" }
fedimintd = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0" }
fedimint-cli = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0" }
fedimint-core = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0" }
fedimint-client = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0" }
fedimint-logging = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0" }
fedimint-server = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0" }
fedimint-testing = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0" }
devimint = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0" }
aead = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0" }
threshold_crypto = { git = "https://github.com/fedimint/threshold_crypto" }
tbs = { git = "https://github.com/fedimint/fedimint", tag = "v0.2.1" }
tbs = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0" }

# Comment above lines and uncomment these to work with local fedimint dependencies
# fedimintd = { path = "../fedimint/fedimintd" }
Expand Down Expand Up @@ -61,4 +61,4 @@ zeroize = { opt-level = 3 }
bls12_381 = { opt-level = 3 }
subtle = { opt-level = 3 }
ring = { opt-level = 3 }
threshold_crypto = { opt-level = 3 }
threshold_crypto = { opt-level = 3 }
6 changes: 5 additions & 1 deletion fedimint-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "fedimint-cli-custom"
version = "0.2.1"
version = "0.3.0"
authors = ["The Fedimint Developers"]
edition = "2021"
description = "fedimint-cli with custom module set"
Expand All @@ -13,4 +13,8 @@ path = "src/main.rs"
anyhow = "1.0.66"
fedimint-cli = { workspace = true }
fedimint-dummy-client = { path = "../fedimint-dummy-client" }
fedimint-core = { workspace = true }
tokio = { version = "1.25.0", features = ["full", "tracing"] }

[build-dependencies]
fedimint-build = { git = "https://github.com/fedimint/fedimint" }
3 changes: 3 additions & 0 deletions fedimint-cli/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
fedimint_build::set_code_version();
}
3 changes: 2 additions & 1 deletion fedimint-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use fedimint_cli::FedimintCli;
use fedimint_core::fedimint_build_code_version_env;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
FedimintCli::new()?
FedimintCli::new(fedimint_build_code_version_env!())?
.with_default_modules()
.with_module(fedimint_dummy_client::DummyClientInit)
.run()
Expand Down
9 changes: 6 additions & 3 deletions fedimint-dummy-client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "fedimint-dummy-client"
version = "0.2.1"
version = "0.3.0"
authors = ["The Fedimint Developers"]
edition = "2021"
description = "fedimint-dummy is a dummy example fedimint module."
Expand All @@ -16,8 +16,8 @@ anyhow = "1.0.66"
fedimint-dummy-common ={ path = "../fedimint-dummy-common" }
fedimint-client = { workspace = true }
fedimint-core ={ workspace = true }
futures = "0.3"
erased-serde = "0.3"
futures = "0.3.30"
erased-serde = "0.4"
rand = "0.8.5"
secp256k1 = "0.24.2"
serde = {version = "1.0.149", features = [ "derive" ] }
Expand All @@ -26,3 +26,6 @@ strum_macros = "0.24"
tracing = "0.1.37"
thiserror = "1.0.39"
threshold_crypto = { workspace = true }

[build-dependencies]
fedimint-build = { git = "https://github.com/fedimint/fedimint" }
3 changes: 3 additions & 0 deletions fedimint-dummy-client/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
fedimint_build::set_code_version();
}
136 changes: 136 additions & 0 deletions fedimint-dummy-client/src/db.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
use fedimint_client::sm::DynState;
use fedimint_core::core::{IntoDynInstance, ModuleInstanceId, OperationId};
use fedimint_core::db::{DatabaseTransaction, DatabaseValue, IDatabaseTransactionOpsCoreTyped};
use fedimint_core::encoding::{Decodable, Encodable};
use fedimint_core::module::registry::ModuleDecoderRegistry;
use fedimint_core::{impl_db_record, Amount};
use strum_macros::EnumIter;
use tracing::warn;

use crate::states::DummyStateMachine;

#[repr(u8)]
#[derive(Clone, Debug, EnumIter)]
pub enum DbKeyPrefix {
ClientFunds = 0x04,
// Used to verify that 0x50 key can be written to, which used to conflict with
// `DatabaseVersionKeyV0`
ClientName = 0x50,
}

impl std::fmt::Display for DbKeyPrefix {
Expand All @@ -19,6 +29,132 @@ pub struct DummyClientFundsKeyV0;

impl_db_record!(
key = DummyClientFundsKeyV0,
value = (),
db_prefix = DbKeyPrefix::ClientFunds,
);

#[derive(Debug, Clone, Encodable, Decodable, Eq, PartialEq, Hash)]
pub struct DummyClientFundsKeyV1;

impl_db_record!(
key = DummyClientFundsKeyV1,
value = Amount,
db_prefix = DbKeyPrefix::ClientFunds,
);

#[derive(Debug, Clone, Encodable, Decodable, Eq, PartialEq, Hash)]
pub struct DummyClientNameKey;

impl_db_record!(
key = DummyClientNameKey,
value = String,
db_prefix = DbKeyPrefix::ClientName,
);

/// Migrates the database from version 0 to version 1 by
/// removing `DummyClientFundsKeyV0` and inserting `DummyClientFundsKeyV1`.
/// The new key/value pair has an `Amount` as the value.
pub async fn migrate_to_v1(
dbtx: &mut DatabaseTransaction<'_>,
) -> anyhow::Result<Option<(Vec<DynState>, Vec<DynState>)>> {
if dbtx.remove_entry(&DummyClientFundsKeyV0).await.is_some() {
// Since this is a dummy migration, we can insert any value for the client
// funds. Real modules should handle the funds properly.

dbtx.insert_new_entry(&DummyClientFundsKeyV1, &Amount::from_sats(1000))
.await;
} else {
warn!("Dummy client did not have client funds, skipping database migration");
}

Ok(None)
}

/// Migrates the database from version 1 to version 2. Maps all `Unreachable`
/// states in the state machine to `InputDone`.
pub async fn migrate_to_v2(
module_instance_id: ModuleInstanceId,
active_states: Vec<(Vec<u8>, OperationId)>,
inactive_states: Vec<(Vec<u8>, OperationId)>,
decoders: ModuleDecoderRegistry,
) -> anyhow::Result<Option<(Vec<DynState>, Vec<DynState>)>> {
let mut new_active_states = Vec::new();
for (active_state, _) in active_states {
// Try to decode the bytes as a `DynState`
let dynstate = DynState::from_bytes(active_state.as_slice(), &decoders)?;
let typed_state = dynstate
.as_any()
.downcast_ref::<DummyStateMachine>()
.expect("Unexpected DynState suppilied to migration function");

match typed_state {
DummyStateMachine::Unreachable(_, _) => {
// Try to parse the bytes as the `Unreachable` struct to simulate a deleted
// state. In a real migration, `DynState::from_bytes` will
// fail since `DummyStateMachine::Unreachable` will not exist.
if let Ok(unreachable) =
Unreachable::consensus_decode_vec(active_state.clone(), &decoders)
{
new_active_states.push(
DummyStateMachine::OutputDone(unreachable.amount, unreachable.operation_id)
.into_dyn(module_instance_id),
);
}
}
state => new_active_states.push(state.clone().into_dyn(module_instance_id)),
}
}

let mut new_inactive_states = Vec::new();
for (inactive_state, _) in inactive_states {
// Try to decode the bytes as a `DynState`
let dynstate = DynState::from_bytes(inactive_state.as_slice(), &decoders)?;
let typed_state = dynstate
.as_any()
.downcast_ref::<DummyStateMachine>()
.expect("Unexpected DynState suppilied to migration function");

match typed_state {
DummyStateMachine::Unreachable(_, _) => {
// Try to parse the bytes as the `Unreachable` struct to simulate a deleted
// state. In a real migration, `DynState::from_bytes` will
// fail since `DummyStateMachine::Unreachable` will not exist.
if let Ok(unreachable) =
Unreachable::consensus_decode_vec(inactive_state.clone(), &decoders)
{
new_inactive_states.push(
DummyStateMachine::OutputDone(unreachable.amount, unreachable.operation_id)
.into_dyn(module_instance_id),
);
}
}
state => new_inactive_states.push(state.clone().into_dyn(module_instance_id)),
}
}

Ok(Some((new_active_states, new_inactive_states)))
}

#[derive(Debug)]
struct Unreachable {
_module_instance_id: ModuleInstanceId,
operation_id: OperationId,
amount: Amount,
}

impl Decodable for Unreachable {
fn consensus_decode<R: std::io::Read>(
reader: &mut R,
modules: &ModuleDecoderRegistry,
) -> Result<Self, fedimint_core::encoding::DecodeError> {
let module_instance_id = ModuleInstanceId::consensus_decode(reader, modules)?;
let operation_id = OperationId::consensus_decode(reader, modules)?;
let amount = Amount::consensus_decode(reader, modules)?;

Ok(Unreachable {
_module_instance_id: module_instance_id,
operation_id,
amount,
})
}
}
47 changes: 33 additions & 14 deletions fedimint-dummy-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ use std::time::Duration;

use anyhow::{anyhow, format_err, Context as _};
use common::broken_fed_key_pair;
use db::DbKeyPrefix;
use db::{migrate_to_v1, migrate_to_v2, DbKeyPrefix, DummyClientFundsKeyV1, DummyClientNameKey};
use fedimint_client::db::ClientMigrationFn;
use fedimint_client::module::init::{ClientModuleInit, ClientModuleInitArgs};
use fedimint_client::module::recovery::NoModuleBackup;
use fedimint_client::module::{ClientContext, ClientModule, IClientModule};
use fedimint_client::sm::{Context, ModuleNotifier};
use fedimint_client::transaction::{ClientInput, ClientOutput, TransactionBuilder};
use fedimint_client::DynGlobalClientContext;
use fedimint_core::api::GlobalFederationApi;
use fedimint_core::core::{Decoder, KeyPair, OperationId};
use fedimint_core::db::{Database, DatabaseTransaction, IDatabaseTransactionOpsCoreTyped};
use fedimint_core::db::{
Database, DatabaseTransaction, DatabaseVersion, IDatabaseTransactionOpsCoreTyped,
};
use fedimint_core::module::{
ApiVersion, CommonModuleInit, ModuleCommon, ModuleInit, MultiApiVersion, TransactionItemAmount,
};
Expand All @@ -25,22 +26,20 @@ use fedimint_dummy_common::{
fed_key_pair, DummyCommonInit, DummyInput, DummyModuleTypes, DummyOutput, DummyOutputOutcome,
KIND,
};
use futures::{pin_mut, StreamExt};
use futures::{pin_mut, FutureExt, StreamExt};
use secp256k1::{PublicKey, Secp256k1};
use states::DummyStateMachine;
use strum::IntoEnumIterator;

use crate::db::DummyClientFundsKeyV0;

pub mod api;
mod db;
pub mod db;
pub mod states;

#[derive(Debug)]
pub struct DummyClientModule {
cfg: DummyClientConfig,
key: KeyPair,
notifier: ModuleNotifier<DynGlobalClientContext, DummyStateMachine>,
notifier: ModuleNotifier<DummyStateMachine>,
client_ctx: ClientContext<Self>,
db: Database,
}
Expand Down Expand Up @@ -106,7 +105,7 @@ impl ClientModule for DummyClientModule {
return Err(format_err!("Insufficient funds"));
}
let updated = funds - amount;
dbtx.insert_entry(&DummyClientFundsKeyV0, &updated).await;
dbtx.insert_entry(&DummyClientFundsKeyV1, &updated).await;

// Construct input and state machine to track the tx
Ok(vec![ClientInput {
Expand Down Expand Up @@ -296,7 +295,7 @@ impl DummyClientModule {
return Err(format_err!("Wrong account id"));
}

dbtx.insert_entry(&DummyClientFundsKeyV0, &new_balance)
dbtx.insert_entry(&DummyClientFundsKeyV1, &new_balance)
.await;
dbtx.commit_tx().await;
Ok(())
Expand All @@ -309,7 +308,7 @@ impl DummyClientModule {
}

async fn get_funds(dbtx: &mut DatabaseTransaction<'_>) -> Amount {
let funds = dbtx.get_value(&DummyClientFundsKeyV0).await;
let funds = dbtx.get_value(&DummyClientFundsKeyV1).await;
funds.unwrap_or(Amount::ZERO)
}

Expand All @@ -320,6 +319,7 @@ pub struct DummyClientInit;
#[apply(async_trait_maybe_send!)]
impl ModuleInit for DummyClientInit {
type Common = DummyCommonInit;
const DATABASE_VERSION: DatabaseVersion = DatabaseVersion(2);

async fn dump_database(
&self,
Expand All @@ -334,13 +334,17 @@ impl ModuleInit for DummyClientInit {
for table in filtered_prefixes {
match table {
DbKeyPrefix::ClientFunds => {
if let Some(funds) = dbtx.get_value(&DummyClientFundsKeyV0).await {
if let Some(funds) = dbtx.get_value(&DummyClientFundsKeyV1).await {
items.insert("Dummy Funds".to_string(), Box::new(funds));
}
}
DbKeyPrefix::ClientName => {
if let Some(name) = dbtx.get_value(&DummyClientNameKey).await {
items.insert("Dummy Name".to_string(), Box::new(name));
}
}
}
}

Box::new(items.into_iter())
}
}
Expand All @@ -367,4 +371,19 @@ impl ClientModuleInit for DummyClientInit {
db: args.db().clone(),
})
}

fn get_database_migrations(&self) -> BTreeMap<DatabaseVersion, ClientMigrationFn> {
let mut migrations: BTreeMap<DatabaseVersion, ClientMigrationFn> = BTreeMap::new();
migrations.insert(DatabaseVersion(0), move |dbtx, _, _, _, _| {
migrate_to_v1(dbtx).boxed()
});

migrations.insert(
DatabaseVersion(1),
move |_, module_instance_id, active_states, inactive_states, decoders| {
migrate_to_v2(module_instance_id, active_states, inactive_states, decoders).boxed()
},
);
migrations
}
}
Loading

0 comments on commit 9a092a2

Please sign in to comment.