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

MASP vp multiple txs #2689

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- Reworked the sdk to support the new speculative state of the
`ShieldedContext`:\n-`ShieldedContext` now has an extra field to determin its
state\n-When calling `gen_shielded_transfer` the context now invalidates the
spent notes (if any)\n-The fee unshielding `Transaction` is now built before
the actual transaction\n-`find_viewing_key` only requires a shared reference
now ([\#2534](https://github.com/anoma/namada/pull/2534))
2 changes: 2 additions & 0 deletions .changelog/unreleased/bug-fixes/2621-fix-nullifier-check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Fixed a bug in the masp vp that allowed a shielding transaction to reveal
nullifiers. ([\#2621](https://github.com/anoma/namada/pull/2621))
2 changes: 2 additions & 0 deletions .changelog/unreleased/improvements/2458-masp-scanning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Simplified the transaction fetching algorithm to enable it to be saved to
storage more frequently. ([\#2458](https://github.com/anoma/namada/pull/2458))
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- The client, when generating a shielded transfer, invalidates the
masp notes that have been spent without the need to sync with a node.
([\#2534](https://github.com/anoma/namada/pull/2534))
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ test-integration-save-proofs:
# Run integration tests without specifying any pre-built MASP proofs option
test-integration-slow:
RUST_BACKTRACE=$(RUST_BACKTRACE) \
$(cargo) +$(nightly) test integration::$(TEST_FILTER) --features integration \
$(cargo) +$(nightly) test $(jobs) integration::$(TEST_FILTER) --features integration \
-Z unstable-options \
-- \
--test-threads=1 \
Expand Down
50 changes: 40 additions & 10 deletions crates/apps/src/lib/bench_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
use namada::vm::wasm::run;
use namada::{proof_of_stake, tendermint};
use namada_sdk::masp::{
self, ShieldedContext, ShieldedTransfer, ShieldedUtils,
self, ContextSyncStatus, ShieldedContext, ShieldedTransfer, ShieldedUtils,
};
pub use namada_sdk::tx::{
TX_BECOME_VALIDATOR_WASM, TX_BOND_WASM, TX_BRIDGE_POOL_WASM,
Expand Down Expand Up @@ -117,6 +117,8 @@

const FILE_NAME: &str = "shielded.dat";
const TMP_FILE_NAME: &str = "shielded.tmp";
const SPECULATIVE_FILE_NAME: &str = "speculative_shielded.dat";
const SPECULATIVE_TMP_FILE_NAME: &str = "speculative_shielded.tmp";

/// For `tracing_subscriber`, which fails if called more than once in the same
/// process
Expand Down Expand Up @@ -654,10 +656,19 @@
async fn load<U: ShieldedUtils>(
&self,
ctx: &mut ShieldedContext<U>,
force_confirmed: bool,

Check warning on line 659 in crates/apps/src/lib/bench_utils.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/bench_utils.rs#L659

Added line #L659 was not covered by tests
) -> std::io::Result<()> {
// Try to load shielded context from file
let file_name = if force_confirmed {
FILE_NAME

Check warning on line 663 in crates/apps/src/lib/bench_utils.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/bench_utils.rs#L662-L663

Added lines #L662 - L663 were not covered by tests
} else {
match ctx.sync_status {
ContextSyncStatus::Confirmed => FILE_NAME,
ContextSyncStatus::Speculative => SPECULATIVE_FILE_NAME,

Check warning on line 667 in crates/apps/src/lib/bench_utils.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/bench_utils.rs#L665-L667

Added lines #L665 - L667 were not covered by tests
}
};
let mut ctx_file = File::open(
self.context_dir.0.path().to_path_buf().join(FILE_NAME),
self.context_dir.0.path().to_path_buf().join(file_name),

Check warning on line 671 in crates/apps/src/lib/bench_utils.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/bench_utils.rs#L671

Added line #L671 was not covered by tests
)?;
let mut bytes = Vec::new();
ctx_file.read_to_end(&mut bytes)?;
Expand All @@ -674,8 +685,14 @@
&self,
ctx: &ShieldedContext<U>,
) -> std::io::Result<()> {
let (tmp_file_name, file_name) = match ctx.sync_status {
ContextSyncStatus::Confirmed => (TMP_FILE_NAME, FILE_NAME),

Check warning on line 689 in crates/apps/src/lib/bench_utils.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/bench_utils.rs#L688-L689

Added lines #L688 - L689 were not covered by tests
ContextSyncStatus::Speculative => {
(SPECULATIVE_TMP_FILE_NAME, SPECULATIVE_FILE_NAME)

Check warning on line 691 in crates/apps/src/lib/bench_utils.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/bench_utils.rs#L691

Added line #L691 was not covered by tests
}
};
let tmp_path =
self.context_dir.0.path().to_path_buf().join(TMP_FILE_NAME);
self.context_dir.0.path().to_path_buf().join(tmp_file_name);

Check warning on line 695 in crates/apps/src/lib/bench_utils.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/bench_utils.rs#L695

Added line #L695 was not covered by tests
{
// First serialize the shielded context into a temporary file.
// Inability to create this file implies a simultaneuous write is in
Expand All @@ -695,12 +712,21 @@
// Atomicity is required to prevent other client instances from reading
// corrupt data.
std::fs::rename(
tmp_path.clone(),
self.context_dir.0.path().to_path_buf().join(FILE_NAME),
tmp_path,
self.context_dir.0.path().to_path_buf().join(file_name),

Check warning on line 716 in crates/apps/src/lib/bench_utils.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/bench_utils.rs#L715-L716

Added lines #L715 - L716 were not covered by tests
)?;
// Finally, remove our temporary file to allow future saving of shielded
// contexts.
std::fs::remove_file(tmp_path)?;

// Remove the speculative file if present since it's state is
// overwritten by the confirmed one we just saved
if let ContextSyncStatus::Confirmed = ctx.sync_status {
let _ = std::fs::remove_file(
self.context_dir
.0
.path()
.to_path_buf()
.join(SPECULATIVE_FILE_NAME),
);
}

Check warning on line 729 in crates/apps/src/lib/bench_utils.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/bench_utils.rs#L721-L729

Added lines #L721 - L729 were not covered by tests
Ok(())
}
}
Expand Down Expand Up @@ -983,9 +1009,13 @@
.wallet
.find_spending_key(ALBERT_SPENDING_KEY, None)
.unwrap();
async_runtime
.block_on(self.shielded.fetch(
self.shielded = async_runtime
.block_on(crate::client::masp::syncing(
self.shielded,

Check warning on line 1014 in crates/apps/src/lib/bench_utils.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/bench_utils.rs#L1012-L1014

Added lines #L1012 - L1014 were not covered by tests
&self.shell,
&StdIo,
1,
None,

Check warning on line 1018 in crates/apps/src/lib/bench_utils.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/bench_utils.rs#L1016-L1018

Added lines #L1016 - L1018 were not covered by tests
&[spending_key.into()],
&[],
))
Expand Down
91 changes: 91 additions & 0 deletions crates/apps/src/lib/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@
.subcommand(QueryMetaData::def().display_order(5))
// Actions
.subcommand(SignTx::def().display_order(6))
.subcommand(ShieldedSync::def().display_order(6))

Check warning on line 271 in crates/apps/src/lib/cli.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/cli.rs#L271

Added line #L271 was not covered by tests
.subcommand(GenIbcShieldedTransafer::def().display_order(6))
// Utils
.subcommand(Utils::def().display_order(7))
Expand Down Expand Up @@ -348,6 +349,7 @@
let add_to_eth_bridge_pool =
Self::parse_with_ctx(matches, AddToEthBridgePool);
let sign_tx = Self::parse_with_ctx(matches, SignTx);
let shielded_sync = Self::parse_with_ctx(matches, ShieldedSync);

Check warning on line 352 in crates/apps/src/lib/cli.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/cli.rs#L352

Added line #L352 was not covered by tests
let gen_ibc_shielded =
Self::parse_with_ctx(matches, GenIbcShieldedTransafer);
let utils = SubCmd::parse(matches).map(Self::WithoutContext);
Expand Down Expand Up @@ -400,6 +402,7 @@
.or(query_metadata)
.or(query_account)
.or(sign_tx)
.or(shielded_sync)

Check warning on line 405 in crates/apps/src/lib/cli.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/cli.rs#L405

Added line #L405 was not covered by tests
.or(gen_ibc_shielded)
.or(utils)
}
Expand Down Expand Up @@ -487,6 +490,7 @@
QueryValidatorState(QueryValidatorState),
QueryRewards(QueryRewards),
SignTx(SignTx),
ShieldedSync(ShieldedSync),
GenIbcShieldedTransafer(GenIbcShieldedTransafer),
}

Expand Down Expand Up @@ -1348,6 +1352,29 @@
}
}

#[derive(Clone, Debug)]

Check warning on line 1355 in crates/apps/src/lib/cli.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/cli.rs#L1355

Added line #L1355 was not covered by tests
pub struct ShieldedSync(pub args::ShieldedSync<args::CliTypes>);

impl SubCmd for ShieldedSync {
const CMD: &'static str = "shielded-sync";

fn parse(matches: &ArgMatches) -> Option<Self> {
matches
.subcommand_matches(Self::CMD)
.map(|matches| ShieldedSync(args::ShieldedSync::parse(matches)))
}

Check warning on line 1365 in crates/apps/src/lib/cli.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/cli.rs#L1361-L1365

Added lines #L1361 - L1365 were not covered by tests

fn def() -> App {
App::new(Self::CMD)
.about(
"Sync the local shielded context with MASP notes owned by \
the provided viewing / spending keys up to an optional \
specified block height.",
)
.add_args::<args::ShieldedSync<args::CliTypes>>()
}

Check warning on line 1375 in crates/apps/src/lib/cli.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/cli.rs#L1367-L1375

Added lines #L1367 - L1375 were not covered by tests
}

#[derive(Clone, Debug)]
pub struct Bond(pub args::Bond<args::CliTypes>);

Expand Down Expand Up @@ -2901,6 +2928,8 @@
Err(_) => config::get_default_namada_folder(),
}),
);
pub const BATCH_SIZE_OPT: ArgDefault<u64> =
arg_default("batch-size", DefaultFn(|| 1));

Check warning on line 2932 in crates/apps/src/lib/cli.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/cli.rs#L2932

Added line #L2932 was not covered by tests
pub const BLOCK_HEIGHT: Arg<BlockHeight> = arg("block-height");
pub const BLOCK_HEIGHT_OPT: ArgOpt<BlockHeight> = arg_opt("height");
pub const BRIDGE_POOL_GAS_AMOUNT: ArgDefault<token::DenominatedAmount> =
Expand Down Expand Up @@ -3084,6 +3113,8 @@
pub const SIGNATURES: ArgMulti<PathBuf, GlobStar> = arg_multi("signatures");
pub const SOURCE: Arg<WalletAddress> = arg("source");
pub const SOURCE_OPT: ArgOpt<WalletAddress> = SOURCE.opt();
pub const SPENDING_KEYS: ArgMulti<WalletSpendingKey, GlobStar> =
arg_multi("spending-keys");
pub const STEWARD: Arg<WalletAddress> = arg("steward");
pub const SOURCE_VALIDATOR: Arg<WalletAddress> = arg("source-validator");
pub const STORAGE_KEY: Arg<storage::Key> = arg("storage-key");
Expand Down Expand Up @@ -3120,6 +3151,8 @@
pub const VALUE: Arg<String> = arg("value");
pub const VOTER_OPT: ArgOpt<WalletAddress> = arg_opt("voter");
pub const VIEWING_KEY: Arg<WalletViewingKey> = arg("key");
pub const VIEWING_KEYS: ArgMulti<WalletViewingKey, GlobStar> =
arg_multi("viewing-keys");
pub const VP: ArgOpt<String> = arg_opt("vp");
pub const WALLET_ALIAS_FORCE: ArgFlag = flag("wallet-alias-force");
pub const WASM_CHECKSUMS_PATH: Arg<PathBuf> = arg("wasm-checksums-path");
Expand Down Expand Up @@ -5631,6 +5664,63 @@
}
}

impl Args for ShieldedSync<CliTypes> {
fn parse(matches: &ArgMatches) -> Self {
let ledger_address = LEDGER_ADDRESS.parse(matches);
let batch_size = BATCH_SIZE_OPT.parse(matches);
let last_query_height = BLOCK_HEIGHT_OPT.parse(matches);
let spending_keys = SPENDING_KEYS.parse(matches);
let viewing_keys = VIEWING_KEYS.parse(matches);
Self {
ledger_address,
batch_size,
last_query_height,
spending_keys,
viewing_keys,
}
}

Check warning on line 5681 in crates/apps/src/lib/cli.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/cli.rs#L5668-L5681

Added lines #L5668 - L5681 were not covered by tests

fn def(app: App) -> App {
app.arg(LEDGER_ADDRESS.def().help(LEDGER_ADDRESS_ABOUT))
.arg(BATCH_SIZE_OPT.def().help(
"Optional batch size which determines how many txs to \
fetch before caching locally. Default is 1.",
))
.arg(BLOCK_HEIGHT_OPT.def().help(
"Option block height to sync up to. Default is latest.",
))
.arg(SPENDING_KEYS.def().help(
"List of new spending keys with which to check note \
ownership. These will be added to the shielded context.",
))
.arg(VIEWING_KEYS.def().help(
"List of new viewing keys with which to check note \
ownership. These will be added to the shielded context.",
))
}

Check warning on line 5700 in crates/apps/src/lib/cli.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/cli.rs#L5683-L5700

Added lines #L5683 - L5700 were not covered by tests
}

impl CliToSdk<ShieldedSync<SdkTypes>> for ShieldedSync<CliTypes> {
fn to_sdk(self, ctx: &mut Context) -> ShieldedSync<SdkTypes> {
let chain_ctx = ctx.borrow_mut_chain_or_exit();
ShieldedSync {
ledger_address: self.ledger_address,
batch_size: self.batch_size,
last_query_height: self.last_query_height,
spending_keys: self
.spending_keys
.iter()
.map(|sk| chain_ctx.get_cached(sk))
.collect(),
viewing_keys: self
.viewing_keys
.iter()
.map(|vk| chain_ctx.get_cached(vk))
.collect(),
}
}

Check warning on line 5721 in crates/apps/src/lib/cli.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/cli.rs#L5704-L5721

Added lines #L5704 - L5721 were not covered by tests
}

impl CliToSdk<GenIbcShieldedTransafer<SdkTypes>>
for GenIbcShieldedTransafer<CliTypes>
{
Expand Down Expand Up @@ -5915,6 +6005,7 @@
type EthereumAddress = String;
type Keypair = WalletKeypair;
type PublicKey = WalletPublicKey;
type SpendingKey = WalletSpendingKey;
type TendermintAddress = tendermint_config::net::Address;
type TransferSource = WalletTransferSource;
type TransferTarget = WalletTransferTarget;
Expand Down
34 changes: 34 additions & 0 deletions crates/apps/src/lib/cli/client.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use color_eyre::eyre::Result;
use masp_primitives::zip32::ExtendedFullViewingKey;
use namada::types::io::Io;
use namada_sdk::{Namada, NamadaImpl};

Expand Down Expand Up @@ -315,6 +316,39 @@
tx::submit_validator_metadata_change(&namada, args)
.await?;
}
Sub::ShieldedSync(ShieldedSync(args)) => {
let client = client.unwrap_or_else(|| {
C::from_tendermint_address(&args.ledger_address)
});
client.wait_until_node_is_synced(&io).await?;
let args = args.to_sdk(&mut ctx);
let chain_ctx = ctx.take_chain_or_exit();
let vks = chain_ctx
.wallet
.get_viewing_keys()
.values()
.copied()
.map(|vk| ExtendedFullViewingKey::from(vk).fvk.vk)
.chain(args.viewing_keys.into_iter().map(|vk| {
ExtendedFullViewingKey::from(vk).fvk.vk
}))
.collect::<Vec<_>>();
let sks = args
.spending_keys
.into_iter()
.map(|sk| sk.into())
.collect::<Vec<_>>();
crate::client::masp::syncing(
chain_ctx.shielded,
&client,
&io,
args.batch_size,
args.last_query_height,
&sks,
&vks,
)
.await?;

Check warning on line 350 in crates/apps/src/lib/cli/client.rs

View check run for this annotation

Codecov / codecov/patch

crates/apps/src/lib/cli/client.rs#L319-L350

Added lines #L319 - L350 were not covered by tests
}
// Eth bridge
Sub::AddToEthBridgePool(args) => {
let args = args.0;
Expand Down
Loading
Loading