mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-05-18 05:59:33 +00:00
fix: remove export/import commands, rewrite test to use invite/join
This commit is contained in:
parent
cf699fde7c
commit
6e376900f7
@ -2,6 +2,10 @@
|
|||||||
clippy::tests_outside_test_module,
|
clippy::tests_outside_test_module,
|
||||||
reason = "Integration test file, not inside a #[cfg(test)] module"
|
reason = "Integration test file, not inside a #[cfg(test)] module"
|
||||||
)]
|
)]
|
||||||
|
#![expect(
|
||||||
|
clippy::shadow_unrelated,
|
||||||
|
reason = "Sequential wallet commands naturally reuse the `command` binding"
|
||||||
|
)]
|
||||||
|
|
||||||
//! Shared account integration tests.
|
//! Shared account integration tests.
|
||||||
//!
|
//!
|
||||||
@ -75,34 +79,48 @@ async fn group_create_and_shared_account_registration() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// GMS seal/unseal round-trip: export GMS, re-import under a new name, verify key agreement.
|
/// GMS seal/unseal round-trip via invite/join, verify key agreement.
|
||||||
#[test]
|
#[test]
|
||||||
async fn group_export_import_key_agreement() -> Result<()> {
|
async fn group_invite_join_key_agreement() -> Result<()> {
|
||||||
let mut ctx = TestContext::new().await?;
|
let mut ctx = TestContext::new().await?;
|
||||||
|
|
||||||
|
// Generate a sealing key
|
||||||
|
let command = Command::Group(GroupSubcommand::NewSealingKey);
|
||||||
|
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||||
|
|
||||||
// Create a group
|
// Create a group
|
||||||
let command = Command::Group(GroupSubcommand::New {
|
let command = Command::Group(GroupSubcommand::New {
|
||||||
name: "alice-group".into(),
|
name: "alice-group".into(),
|
||||||
});
|
});
|
||||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||||
|
|
||||||
// Export the GMS
|
// Seal GMS for ourselves (simulating invite to another wallet)
|
||||||
|
let sealing_sk = ctx
|
||||||
|
.wallet()
|
||||||
|
.storage()
|
||||||
|
.user_data
|
||||||
|
.sealing_secret_key
|
||||||
|
.context("Sealing key not found")?;
|
||||||
|
let sealing_pk =
|
||||||
|
nssa_core::encryption::shared_key_derivation::Secp256k1Point::from_scalar(sealing_sk);
|
||||||
|
|
||||||
let holder = ctx
|
let holder = ctx
|
||||||
.wallet()
|
.wallet()
|
||||||
.storage()
|
.storage()
|
||||||
.user_data
|
.user_data
|
||||||
.group_key_holder("alice-group")
|
.group_key_holder("alice-group")
|
||||||
.context("Group not found")?;
|
.context("Group not found")?;
|
||||||
let gms_hex = hex::encode(holder.dangerous_raw_gms());
|
let sealed = holder.seal_for(&sealing_pk);
|
||||||
|
let sealed_hex = hex::encode(&sealed);
|
||||||
|
|
||||||
// Import under a different name (simulating Bob receiving the GMS)
|
// Join under a different name (simulating Bob receiving the sealed GMS)
|
||||||
let command = Command::Group(GroupSubcommand::Import {
|
let command = Command::Group(GroupSubcommand::Join {
|
||||||
name: "bob-copy".into(),
|
name: "bob-copy".into(),
|
||||||
gms: gms_hex,
|
sealed: sealed_hex,
|
||||||
});
|
});
|
||||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||||
|
|
||||||
// Both derive the same keys for the same tag
|
// Both derive the same keys for the same derivation seed
|
||||||
let alice_holder = ctx
|
let alice_holder = ctx
|
||||||
.wallet()
|
.wallet()
|
||||||
.storage()
|
.storage()
|
||||||
@ -116,12 +134,12 @@ async fn group_export_import_key_agreement() -> Result<()> {
|
|||||||
.group_key_holder("bob-copy")
|
.group_key_holder("bob-copy")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let tag = [42_u8; 32];
|
let seed = [42_u8; 32];
|
||||||
let alice_npk = alice_holder
|
let alice_npk = alice_holder
|
||||||
.derive_keys_for_shared_account(&tag)
|
.derive_keys_for_shared_account(&seed)
|
||||||
.generate_nullifier_public_key();
|
.generate_nullifier_public_key();
|
||||||
let bob_npk = bob_holder
|
let bob_npk = bob_holder
|
||||||
.derive_keys_for_shared_account(&tag)
|
.derive_keys_for_shared_account(&seed)
|
||||||
.generate_nullifier_public_key();
|
.generate_nullifier_public_key();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -129,14 +147,14 @@ async fn group_export_import_key_agreement() -> Result<()> {
|
|||||||
"Key agreement: same GMS produces same keys"
|
"Key agreement: same GMS produces same keys"
|
||||||
);
|
);
|
||||||
|
|
||||||
info!("Key agreement verified");
|
info!("Key agreement verified via invite/join");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fund a shared account from a public account via auth-transfer, then sync.
|
/// Fund a shared account from a public account via auth-transfer, then sync.
|
||||||
/// TODO: Requires auth-transfer init to work with shared accounts (authorization flow).
|
/// TODO: Requires auth-transfer init to work with shared accounts (authorization flow).
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
#[ignore = "Requires auth-transfer init to work with shared accounts (authorization flow)"]
|
||||||
async fn fund_shared_account_from_public() -> Result<()> {
|
async fn fund_shared_account_from_public() -> Result<()> {
|
||||||
let mut ctx = TestContext::new().await?;
|
let mut ctx = TestContext::new().await?;
|
||||||
|
|
||||||
|
|||||||
@ -15,19 +15,6 @@ pub enum GroupSubcommand {
|
|||||||
/// Human-readable name for the group.
|
/// Human-readable name for the group.
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
/// Import a group from raw GMS bytes.
|
|
||||||
Import {
|
|
||||||
/// Human-readable name for the group.
|
|
||||||
name: String,
|
|
||||||
/// Raw GMS as 64-character hex string.
|
|
||||||
#[arg(long)]
|
|
||||||
gms: String,
|
|
||||||
},
|
|
||||||
/// Export the raw GMS hex for backup or manual distribution.
|
|
||||||
Export {
|
|
||||||
/// Group name.
|
|
||||||
name: String,
|
|
||||||
},
|
|
||||||
/// List all groups.
|
/// List all groups.
|
||||||
#[command(visible_alias = "ls")]
|
#[command(visible_alias = "ls")]
|
||||||
List,
|
List,
|
||||||
@ -82,43 +69,6 @@ impl WalletSubcommand for GroupSubcommand {
|
|||||||
Ok(SubcommandReturnValue::Empty)
|
Ok(SubcommandReturnValue::Empty)
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::Import { name, gms } => {
|
|
||||||
if wallet_core
|
|
||||||
.storage()
|
|
||||||
.user_data
|
|
||||||
.group_key_holder(&name)
|
|
||||||
.is_some()
|
|
||||||
{
|
|
||||||
anyhow::bail!("Group '{name}' already exists");
|
|
||||||
}
|
|
||||||
|
|
||||||
let gms_bytes: [u8; 32] = hex::decode(&gms)
|
|
||||||
.context("Invalid GMS hex")?
|
|
||||||
.try_into()
|
|
||||||
.map_err(|_err| anyhow::anyhow!("GMS must be exactly 32 bytes"))?;
|
|
||||||
|
|
||||||
let holder = GroupKeyHolder::from_gms(gms_bytes);
|
|
||||||
wallet_core.insert_group_key_holder(name.clone(), holder);
|
|
||||||
wallet_core.store_persistent_data().await?;
|
|
||||||
|
|
||||||
println!("Imported group '{name}'");
|
|
||||||
Ok(SubcommandReturnValue::Empty)
|
|
||||||
}
|
|
||||||
|
|
||||||
Self::Export { name } => {
|
|
||||||
let holder = wallet_core
|
|
||||||
.storage()
|
|
||||||
.user_data
|
|
||||||
.group_key_holder(&name)
|
|
||||||
.context(format!("Group '{name}' not found"))?;
|
|
||||||
|
|
||||||
let gms_hex = hex::encode(holder.dangerous_raw_gms());
|
|
||||||
|
|
||||||
println!("Group: {name}");
|
|
||||||
println!("GMS: {gms_hex}");
|
|
||||||
Ok(SubcommandReturnValue::Empty)
|
|
||||||
}
|
|
||||||
|
|
||||||
Self::List => {
|
Self::List => {
|
||||||
let holders = &wallet_core.storage().user_data.group_key_holders;
|
let holders = &wallet_core.storage().user_data.group_key_holders;
|
||||||
if holders.is_empty() {
|
if holders.is_empty() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user