Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Murisi/masp for namadillo #4127

Merged
merged 18 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
44c5f03
Implemented MASP signing using the hardware wallet.
murisi Sep 23, 2024
5fd0281
Factored out the logic for MASP hardware wallet signing.
murisi Sep 23, 2024
b78d8bf
Expand MASP hardware wallet support to other transaction types.
murisi Sep 24, 2024
9e7c974
Separate the storage of shielded keys from their birthdays.
murisi Sep 26, 2024
381531b
Never use the hardware wallet to sign the fee header alone. Always en…
murisi Sep 27, 2024
0ef7b66
Moved the shielded keys used in the integration tests into the localn…
murisi Sep 27, 2024
2d8c41c
Dont do a dry run if using a device in the MASP integration tests.
murisi Sep 29, 2024
3e72fe1
Always sign MASP Transactions before dumping because randomness param…
murisi Sep 30, 2024
fd48de2
test/e2e/masp: add support for testing with HW wallet
tzemanovic Oct 3, 2024
bdd8e9f
Sometimes use literals instead of aliases in the IBC tests.
murisi Oct 29, 2024
706a143
Make shielded balance checking more robust for IBC tests.
murisi Oct 30, 2024
e59aaf6
Adjust integration tests to work with both hardware and localnet gene…
murisi Nov 20, 2024
2105731
Make the the software wallet support the old Store format.
murisi Dec 1, 2024
79106c5
Test that the transfer source now displays as a viewing key.
murisi Dec 2, 2024
bec57d6
Downgraded the ledger-namada-rs branch. Now print error messages when…
murisi Dec 2, 2024
42b0ac3
Hide modified ZIP 32 behind a CLI flag.
murisi Dec 2, 2024
35b42d6
Change the Hermes branch used by the CI.
murisi Dec 2, 2024
49a4a5d
Added a changelog entry.
murisi Dec 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .changelog/unreleased/SDK/4127-masp-for-namadillo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Allow MASP transaction building without knowledge of the spend authorization
key. ([\#4127](https://github.com/anoma/namada/pull/4127))
2 changes: 1 addition & 1 deletion .github/workflows/scripts/hermes.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.10.4-namada-beta17-rc2
1.10.4-namada-beta18-test
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,15 @@ konst = { version = "0.3.8", default-features = false }
lazy_static = "1.4.0"
# TODO: upstreamed in https://github.com/ledger-community/rust-ledger/pull/9
ledger-lib = { git = "https://github.com/heliaxdev/rust-ledger", rev = "f96f4559b3237d09218f7583df01acf36034ea79", default-features = false, features = ["transport_tcp"] }
ledger-namada-rs = { git = "https://github.com/Zondax/ledger-namada", tag = "v0.0.24" }
ledger-namada-rs = { git = "https://github.com/Zondax/ledger-namada", tag = "v1.0.5" }
ledger-transport = "0.10.0"
ledger-transport-hid = "0.10.0"
libc = "0.2.97"
libloading = "0.7.2"
linkme = "0.3.24"
# branch = "tomas/arbitrary"
masp_primitives = { git = "https://github.com/anoma/masp", rev = "12ed8b060b295c06502a2ff8468e4a941cb7cca4" }
masp_proofs = { git = "https://github.com/anoma/masp", rev = "12ed8b060b295c06502a2ff8468e4a941cb7cca4", default-features = false, features = ["local-prover"] }
masp_primitives = { git = "https://github.com/anoma/masp", rev = "0d0da3507a6f9ad135f00fd8201dc54c2f1d9efe" }
masp_proofs = { git = "https://github.com/anoma/masp", rev = "0d0da3507a6f9ad135f00fd8201dc54c2f1d9efe", default-features = false, features = ["local-prover"] }
num256 = "0.3.5"
num_cpus = "1.13.0"
num-derive = "0.4"
Expand Down
14 changes: 12 additions & 2 deletions crates/apps_lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3550,6 +3550,7 @@ pub mod args {
let raw = "http://127.0.0.1:26657";
Url::from_str(raw).unwrap()
}));
pub const LEDGER_ZIP32: ArgFlag = flag("ledger-zip32");
pub const LIST_FIND_ADDRESSES_ONLY: ArgFlag = flag("addr");
pub const LIST_FIND_KEYS_ONLY: ArgFlag = flag("keys");
pub const LOCALHOST: ArgFlag = flag("localhost");
Expand Down Expand Up @@ -7766,8 +7767,7 @@ pub mod args {
find_viewing_key(&mut wallet)
} else {
find_viewing_key(&mut ctx.borrow_mut_chain_or_exit().wallet)
}
.key;
};

Ok(PayAddressGen::<SdkTypes> {
alias: self.alias,
Expand Down Expand Up @@ -7815,12 +7815,14 @@ pub mod args {
HD_PROMPT_BIP39_PASSPHRASE.parse(matches);
let use_device = USE_DEVICE.parse(matches);
let device_transport = DEVICE_TRANSPORT.parse(matches);
let ledger_zip32 = LEDGER_ZIP32.parse(matches);
Self {
scheme,
shielded,
alias,
alias_force,
unsafe_dont_encrypt,
ledger_zip32,
derivation_path,
allow_non_compliant,
prompt_bip39_passphrase,
Expand Down Expand Up @@ -7891,6 +7893,14 @@ pub mod args {
.arg(HD_PROMPT_BIP39_PASSPHRASE.def().help(wrap!(
"Use an additional passphrase for HD-key generation."
)))
.arg(
LEDGER_ZIP32.def().requires(SHIELDED.name).help(wrap!(
"Use the modified ZIP 32 algorithm supported by Ledger \
devices. This flag is necessary if importing the \
generated mnemonic code onto the Ledger device at some \
future time is a requirement."
)),
)
}
}

Expand Down
13 changes: 11 additions & 2 deletions crates/apps_lib/src/cli/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::io::Read;
use color_eyre::eyre::Result;
use namada_sdk::io::{display_line, Io, NamadaIo};
use namada_sdk::masp::ShieldedContext;
use namada_sdk::wallet::DatedViewingKey;
use namada_sdk::{Namada, NamadaImpl};

use crate::cli;
Expand Down Expand Up @@ -349,8 +350,16 @@ impl CliApi {
chain_ctx
.wallet
.get_viewing_keys()
.values()
.copied(),
.into_iter()
.map(|(k, v)| {
DatedViewingKey::new(
v,
chain_ctx
.wallet
.find_birthday(k)
.copied(),
)
}),
);

crate::client::masp::syncing(
Expand Down
78 changes: 68 additions & 10 deletions crates/apps_lib/src/cli/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ use std::path::{Path, PathBuf};
use std::str::FromStr;

use color_eyre::eyre::Result;
use masp_primitives::zip32::sapling::PseudoExtendedKey;
use masp_primitives::zip32::{
ExtendedFullViewingKey as MaspExtendedViewingKey,
ExtendedSpendingKey as MaspExtendedSpendingKey,
};
use namada_core::masp::{
BalanceOwner, ExtendedSpendingKey, ExtendedViewingKey, PaymentAddress,
TransferSource, TransferTarget,
Expand Down Expand Up @@ -47,7 +52,7 @@ pub type WalletAddrOrNativeToken = FromContext<AddrOrNativeToken>;

/// A raw extended spending key (bech32m encoding) or an alias of an extended
/// spending key in the wallet
pub type WalletSpendingKey = FromContext<ExtendedSpendingKey>;
pub type WalletSpendingKey = FromContext<PseudoExtendedKey>;

/// A raw dated extended spending key (bech32m encoding) or an alias of an
/// extended spending key in the wallet
Expand Down Expand Up @@ -583,12 +588,51 @@ impl ArgFromMutContext for ExtendedSpendingKey {
// Or it is a stored alias of one
ctx.wallet
.find_spending_key(raw, None)
.map(|k| k.key)
.map_err(|_find_err| format!("Unknown spending key {}", raw))
})
}
}

impl ArgFromMutContext for PseudoExtendedKey {
fn arg_from_mut_ctx(
ctx: &mut ChainContext,
raw: impl AsRef<str>,
) -> Result<Self, String> {
let raw = raw.as_ref();
// Either the string is a raw extended spending key
ExtendedSpendingKey::from_str(raw)
.map(|x| PseudoExtendedKey::from(MaspExtendedSpendingKey::from(x)))
.or_else(|_parse_err| {
ExtendedViewingKey::from_str(raw).map(|x| {
PseudoExtendedKey::from(MaspExtendedViewingKey::from(x))
})
})
.or_else(|_parse_err| {
// Or it is a stored alias of one
ctx.wallet
.find_spending_key(raw, None)
.map(|k| {
PseudoExtendedKey::from(MaspExtendedSpendingKey::from(
k,
))
})
.map_err(|_find_err| {
format!("Unknown spending key {}", raw)
})
})
.or_else(|_parse_err| {
// Or it is a stored alias of one
ctx.wallet
.find_viewing_key(raw)
.copied()
.map(|k| {
PseudoExtendedKey::from(MaspExtendedViewingKey::from(k))
})
.map_err(|_find_err| format!("Unknown viewing key {}", raw))
})
}
}

impl ArgFromMutContext for DatedSpendingKey {
fn arg_from_mut_ctx(
ctx: &mut ChainContext,
Expand All @@ -598,9 +642,12 @@ impl ArgFromMutContext for DatedSpendingKey {
// Either the string is a raw extended spending key
FromStr::from_str(raw).or_else(|_parse_err| {
// Or it is a stored alias of one
ctx.wallet
let sk = ctx
.wallet
.find_spending_key(raw, None)
.map_err(|_find_err| format!("Unknown spending key {}", raw))
.map_err(|_find_err| format!("Unknown spending key {}", raw))?;
let birthday = ctx.wallet.find_birthday(raw);
Ok(DatedSpendingKey::new(sk, birthday.copied()))
})
}
}
Expand All @@ -617,7 +664,6 @@ impl ArgFromMutContext for ExtendedViewingKey {
ctx.wallet
.find_viewing_key(raw)
.copied()
.map(|k| k.key)
.map_err(|_find_err| format!("Unknown viewing key {}", raw))
})
}
Expand All @@ -632,10 +678,12 @@ impl ArgFromMutContext for DatedViewingKey {
// Either the string is a raw full viewing key
FromStr::from_str(raw).or_else(|_parse_err| {
// Or it is a stored alias of one
ctx.wallet
let vk = ctx
.wallet
.find_viewing_key(raw)
.copied()
.map_err(|_find_err| format!("Unknown viewing key {}", raw))
.map_err(|_find_err| format!("Unknown viewing key {}", raw))?;
let birthday = ctx.wallet.find_birthday(raw);
Ok(DatedViewingKey::new(*vk, birthday.copied()))
})
}
}
Expand Down Expand Up @@ -667,8 +715,18 @@ impl ArgFromMutContext for TransferSource {
Address::arg_from_ctx(ctx, raw)
.map(Self::Address)
.or_else(|_| {
ExtendedSpendingKey::arg_from_mut_ctx(ctx, raw)
.map(Self::ExtendedSpendingKey)
ExtendedSpendingKey::arg_from_mut_ctx(ctx, raw).map(|x| {
Self::ExtendedKey(PseudoExtendedKey::from(
MaspExtendedSpendingKey::from(x),
))
})
})
.or_else(|_| {
ExtendedViewingKey::arg_from_mut_ctx(ctx, raw).map(|x| {
Self::ExtendedKey(PseudoExtendedKey::from(
MaspExtendedViewingKey::from(x),
))
})
})
}
}
Expand Down
19 changes: 15 additions & 4 deletions crates/apps_lib/src/cli/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,14 @@ fn payment_addresses_list(
}

/// Derives a masp spending key from the mnemonic code in the wallet.
fn shielded_key_derive(
async fn shielded_key_derive(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why did this become async?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's taken from #3797 without shielded keys support in HW wallet - we unfortunately already have some blocking calls mixed in the client already (e.g. wallet load) but I think we should just go with it and convert the blocking stuff to async

ctx: Context,
io: &impl Io,
args::KeyDerive {
alias,
alias_force,
unsafe_dont_encrypt,
ledger_zip32,
derivation_path,
allow_non_compliant,
prompt_bip39_passphrase,
Expand Down Expand Up @@ -220,6 +221,7 @@ fn shielded_key_derive(
alias,
alias_force,
birthday,
ledger_zip32,
derivation_path,
None,
prompt_bip39_passphrase,
Expand All @@ -232,7 +234,10 @@ fn shielded_key_derive(
})
.0
} else {
display_line!(io, "Not implemented.");
display_line!(
io,
"Shielded key derivation using hardware wallet not implemented."
);
display_line!(io, "No changes are persisted. Exiting.");
cli::safe_exit(1)
};
Expand Down Expand Up @@ -367,7 +372,13 @@ fn shielded_key_address_add(
let (alias, typ) = match masp_value {
MaspValue::FullViewingKey(viewing_key) => {
let alias = wallet
.insert_viewing_key(alias, viewing_key, birthday, alias_force)
.insert_viewing_key(
alias,
viewing_key,
birthday,
alias_force,
None,
)
.unwrap_or_else(|| {
edisplay_line!(io, "Viewing key not added");
cli::safe_exit(1);
Expand Down Expand Up @@ -638,7 +649,7 @@ async fn key_derive(
if !args_key_derive.shielded {
transparent_key_and_address_derive(ctx, io, args_key_derive).await
} else {
shielded_key_derive(ctx, io, args_key_derive)
shielded_key_derive(ctx, io, args_key_derive).await
}
}

Expand Down
Loading
Loading