Skip to content

Commit 7325ecc

Browse files
committed
Merge branch 'tiago/masp-ss-phase-2' (#3456)
* origin/tiago/masp-ss-phase-2: Changelog for #3456 Remove `ThenAwait` abstraction Remove default methods from masp client trait Deserialize server err response from masp indexer client More misc masp indexer client fixes Fetch indexed txs in batches of the max req thres Inline caps in masp client Misc indexer client fixes Fetch masp pre-built data during shielded sync Integrate indexer client with the CLI Advance peek iterator at the top of loop Optionally trigger witness map update Implement a masp client backed by the `namada-masp-indexer` Decouple ledger rpc client from masp client Remove batch size arg Update `reqwest` Disable building ledger masp client on wasm targets Make masp client caps a default method Add new fetch methods to masp client trait Emit spin loop hint on masp txs receiver Always retry from the latest synced height during ss Use `BlockHeight` instead of `u64` in fetch args Define capabilities for masp rpc clients
2 parents 74b417c + 185cf27 commit 7325ecc

File tree

13 files changed

+1143
-113
lines changed

13 files changed

+1143
-113
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
- Implement the phase 2 masp shielded sync client. This client uses
2+
a [`namada-masp-indexer`](https://github.com/anoma/namada-masp-
3+
indexer) instance to query the state of the shielded context.
4+
([\#3456](https://github.com/anoma/namada/pull/3456))

Cargo.lock

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/apps_lib/src/cli.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3213,8 +3213,6 @@ pub mod args {
32133213
Err(_) => config::get_default_namada_folder(),
32143214
}),
32153215
);
3216-
pub const BATCH_SIZE_OPT: ArgDefault<u64> =
3217-
arg_default("batch-size", DefaultFn(|| 1));
32183216
pub const BLOCK_HEIGHT: Arg<BlockHeight> = arg("block-height");
32193217
pub const BLOCK_HEIGHT_OPT: ArgOpt<BlockHeight> = arg_opt("height");
32203218
pub const BLOCK_HEIGHT_FROM_OPT: ArgOpt<BlockHeight> =
@@ -3468,6 +3466,7 @@ pub mod args {
34683466
pub const WASM_CHECKSUMS_PATH: Arg<PathBuf> = arg("wasm-checksums-path");
34693467
pub const WASM_DIR: ArgOpt<PathBuf> = arg_opt("wasm-dir");
34703468
pub const WEBSITE_OPT: ArgOpt<String> = arg_opt("website");
3469+
pub const WITH_INDEXER: ArgOpt<String> = arg_opt("with-indexer");
34713470
pub const TX_PATH: Arg<PathBuf> = arg("tx-path");
34723471
pub const TX_PATH_OPT: ArgOpt<PathBuf> = TX_PATH.opt();
34733472

@@ -6575,27 +6574,23 @@ pub mod args {
65756574
impl Args for ShieldedSync<CliTypes> {
65766575
fn parse(matches: &ArgMatches) -> Self {
65776576
let ledger_address = CONFIG_RPC_LEDGER_ADDRESS.parse(matches);
6578-
let batch_size = BATCH_SIZE_OPT.parse(matches);
65796577
let start_query_height = BLOCK_HEIGHT_FROM_OPT.parse(matches);
65806578
let last_query_height = BLOCK_HEIGHT_TO_OPT.parse(matches);
65816579
let spending_keys = SPENDING_KEYS.parse(matches);
65826580
let viewing_keys = VIEWING_KEYS.parse(matches);
6581+
let with_indexer = WITH_INDEXER.parse(matches);
65836582
Self {
65846583
ledger_address,
6585-
batch_size,
65866584
start_query_height,
65876585
last_query_height,
65886586
spending_keys,
65896587
viewing_keys,
6588+
with_indexer,
65906589
}
65916590
}
65926591

65936592
fn def(app: App) -> App {
65946593
app.arg(CONFIG_RPC_LEDGER_ADDRESS.def().help(LEDGER_ADDRESS_ABOUT))
6595-
.arg(BATCH_SIZE_OPT.def().help(wrap!(
6596-
"Optional batch size which determines how many txs to \
6597-
fetch before caching locally. Default is 1."
6598-
)))
65996594
.arg(BLOCK_HEIGHT_TO_OPT.def().help(wrap!(
66006595
"Option block height to sync up to. Default is latest."
66016596
)))
@@ -6612,6 +6607,11 @@ pub mod args {
66126607
"List of new viewing keys with which to check note \
66136608
ownership. These will be added to the shielded context."
66146609
)))
6610+
.arg(WITH_INDEXER.def().help(wrap!(
6611+
"Address of a `namada-masp-indexer` live instance. If \
6612+
present, the shielded sync will be performed using data \
6613+
retrieved from the given indexer."
6614+
)))
66156615
}
66166616
}
66176617

@@ -6626,7 +6626,6 @@ pub mod args {
66266626

66276627
Ok(ShieldedSync {
66286628
ledger_address: chain_ctx.get(&self.ledger_address),
6629-
batch_size: self.batch_size,
66306629
start_query_height: self.start_query_height,
66316630
last_query_height: self.last_query_height,
66326631
spending_keys: self
@@ -6639,6 +6638,7 @@ pub mod args {
66396638
.iter()
66406639
.map(|vk| chain_ctx.get_cached(vk))
66416640
.collect(),
6641+
with_indexer: self.with_indexer.map(|_| ()),
66426642
})
66436643
}
66446644
}
@@ -6962,6 +6962,7 @@ pub mod args {
69626962
type Data = PathBuf;
69636963
type EthereumAddress = String;
69646964
type Keypair = WalletKeypair;
6965+
type MaspIndexerAddress = String;
69656966
type PaymentAddress = WalletPaymentAddr;
69666967
type PublicKey = WalletPublicKey;
69676968
type SpendingKey = WalletSpendingKey;

crates/apps_lib/src/cli/client.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,13 +336,16 @@ impl CliApi {
336336
tx::submit_validator_metadata_change(&namada, args)
337337
.await?;
338338
}
339-
Sub::ShieldedSync(ShieldedSync(args)) => {
339+
Sub::ShieldedSync(ShieldedSync(mut args)) => {
340+
let indexer_addr = args.with_indexer.take();
340341
let args = args.to_sdk(&mut ctx)?;
341342
let chain_ctx = ctx.take_chain_or_exit();
342343
let client = client.unwrap_or_else(|| {
343344
C::from_tendermint_address(&args.ledger_address)
344345
});
345-
client.wait_until_node_is_synced(&io).await?;
346+
if indexer_addr.is_none() {
347+
client.wait_until_node_is_synced(&io).await?;
348+
}
346349
let vks = chain_ctx
347350
.wallet
348351
.get_viewing_keys()
@@ -361,8 +364,8 @@ impl CliApi {
361364
crate::client::masp::syncing(
362365
chain_ctx.shielded,
363366
&client,
367+
indexer_addr.as_ref().map(|s| s.as_ref()),
364368
&io,
365-
args.batch_size,
366369
args.start_query_height,
367370
args.last_query_height,
368371
&sks,

crates/apps_lib/src/client/masp.rs

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
use std::fmt::Debug;
22
use std::sync::{Arc, Mutex};
3+
use std::time::Duration;
34

45
use color_eyre::owo_colors::OwoColorize;
56
use masp_primitives::sapling::ViewingKey;
67
use masp_primitives::zip32::ExtendedSpendingKey;
78
use namada_sdk::error::Error;
89
use namada_sdk::io::Io;
910
use namada_sdk::masp::utils::{
10-
LedgerMaspClient, PeekableIter, ProgressTracker, ProgressType,
11-
RetryStrategy,
11+
IndexerMaspClient, LedgerMaspClient, PeekableIter, ProgressTracker,
12+
ProgressType, RetryStrategy,
1213
};
1314
use namada_sdk::masp::{IndexedNoteEntry, ShieldedContext, ShieldedUtils};
1415
use namada_sdk::queries::Client;
@@ -23,30 +24,62 @@ pub async fn syncing<
2324
>(
2425
mut shielded: ShieldedContext<U>,
2526
client: &C,
27+
indexer_addr: Option<&str>,
2628
io: &IO,
27-
batch_size: u64,
2829
start_query_height: Option<BlockHeight>,
2930
last_query_height: Option<BlockHeight>,
3031
sks: &[ExtendedSpendingKey],
3132
fvks: &[ViewingKey],
3233
) -> Result<ShieldedContext<U>, Error> {
33-
display_line!(io, "{}", "==== Shielded sync started ====".on_white());
34+
if indexer_addr.is_some() {
35+
display_line!(
36+
io,
37+
"{}",
38+
"==== Shielded sync started using indexer client ====".bold()
39+
);
40+
} else {
41+
display_line!(
42+
io,
43+
"{}",
44+
"==== Shielded sync started using ledger client ====".bold()
45+
);
46+
}
3447
display_line!(io, "\n\n");
3548
let tracker = CliProgressTracker::new(io);
3649

37-
let shielded = shielded
38-
.fetch(
39-
LedgerMaspClient::new(client),
40-
&tracker,
41-
start_query_height,
42-
last_query_height,
43-
RetryStrategy::Forever,
44-
batch_size,
45-
sks,
46-
fvks,
47-
)
48-
.await
49-
.map(|_| shielded)?;
50+
macro_rules! dispatch_client {
51+
($client:expr) => {
52+
shielded
53+
.fetch(
54+
$client,
55+
&tracker,
56+
start_query_height,
57+
last_query_height,
58+
RetryStrategy::Forever,
59+
sks,
60+
fvks,
61+
)
62+
.await
63+
.map(|_| shielded)
64+
};
65+
}
66+
67+
let shielded = if let Some(endpoint) = indexer_addr {
68+
let client = reqwest::Client::builder()
69+
.connect_timeout(Duration::from_secs(60))
70+
.build()
71+
.map_err(|err| {
72+
Error::Other(format!("Failed to build http client: {err}"))
73+
})?;
74+
let url = endpoint.try_into().map_err(|err| {
75+
Error::Other(format!(
76+
"Failed to parse API endpoint {endpoint:?}: {err}"
77+
))
78+
})?;
79+
dispatch_client!(IndexerMaspClient::new(client, url))?
80+
} else {
81+
dispatch_client!(LedgerMaspClient::new(client))?
82+
};
5083

5184
display!(io, "Syncing finished\n");
5285
Ok(shielded)

crates/node/src/bench_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1070,8 +1070,8 @@ impl BenchShieldedCtx {
10701070
.block_on(namada_apps_lib::client::masp::syncing(
10711071
self.shielded,
10721072
&self.shell,
1073+
None,
10731074
&StdIo,
1074-
1,
10751075
None,
10761076
None,
10771077
&[spending_key.into()],

crates/sdk/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ tracing.workspace = true
135135
zeroize.workspace = true
136136

137137
[target.'cfg(not(target_family = "wasm"))'.dependencies]
138+
reqwest.workspace = true
138139
tokio = { workspace = true, features = ["full"] }
139140

140141
[target.'cfg(target_family = "wasm")'.dependencies]

crates/sdk/src/args.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ pub trait NamadaTypes: Clone + std::fmt::Debug {
7979
type Data: Clone + std::fmt::Debug;
8080
/// Bridge pool recommendations conversion rates table.
8181
type BpConversionTable: Clone + std::fmt::Debug;
82+
/// Address of a `namada-masp-indexer` live instance
83+
type MaspIndexerAddress: Clone + std::fmt::Debug;
8284
}
8385

8486
/// The concrete types being used in Namada SDK
@@ -105,6 +107,7 @@ impl NamadaTypes for SdkTypes {
105107
type Data = Vec<u8>;
106108
type EthereumAddress = ();
107109
type Keypair = namada_core::key::common::SecretKey;
110+
type MaspIndexerAddress = ();
108111
type PaymentAddress = namada_core::masp::PaymentAddress;
109112
type PublicKey = namada_core::key::common::PublicKey;
110113
type SpendingKey = namada_core::masp::ExtendedSpendingKey;
@@ -2082,8 +2085,6 @@ pub struct SignTx<C: NamadaTypes = SdkTypes> {
20822085
pub struct ShieldedSync<C: NamadaTypes = SdkTypes> {
20832086
/// The ledger address
20842087
pub ledger_address: C::ConfigRpcTendermintAddress,
2085-
/// The number of txs to fetch before caching
2086-
pub batch_size: u64,
20872088
/// Height to start syncing from. Defaults to the correct one.
20882089
pub start_query_height: Option<BlockHeight>,
20892090
/// Height to sync up to. Defaults to most recent
@@ -2092,6 +2093,11 @@ pub struct ShieldedSync<C: NamadaTypes = SdkTypes> {
20922093
pub spending_keys: Vec<C::SpendingKey>,
20932094
/// Viewing keys used to determine note ownership
20942095
pub viewing_keys: Vec<C::ViewingKey>,
2096+
/// Address of a `namada-masp-indexer` live instance
2097+
///
2098+
/// If present, the shielded sync will be performed
2099+
/// using data retrieved from the given indexer
2100+
pub with_indexer: Option<C::MaspIndexerAddress>,
20952101
}
20962102

20972103
/// Query PoS commission rate

0 commit comments

Comments
 (0)