Skip to content

Commit 15b6059

Browse files
authored
Merge pull request #3720 from anoma/grarco/batch-reveal-pk
Batch `reveal_pk`
2 parents f92adcf + 3f8c058 commit 15b6059

File tree

2 files changed

+133
-81
lines changed

2 files changed

+133
-81
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
- If an additional `reveal_pk` transaction is required, the client now groups
2+
it with the actual transaction into a single batch instead of submitting it
3+
separately. ([\#3720](https://github.com/anoma/namada/pull/3720))

crates/apps_lib/src/client/tx.rs

+130-81
Original file line numberDiff line numberDiff line change
@@ -195,11 +195,11 @@ pub async fn sign<N: Namada>(
195195
// Build a transaction to reveal the signer of the given transaction.
196196
pub async fn submit_reveal_aux(
197197
context: &impl Namada,
198-
args: args::Tx,
198+
args: &args::Tx,
199199
address: &Address,
200-
) -> Result<(), error::Error> {
200+
) -> Result<Option<(Tx, SigningTxData)>, error::Error> {
201201
if args.dump_tx {
202-
return Ok(());
202+
return Ok(None);
203203
}
204204

205205
if let Address::Implicit(ImplicitAddress(pkh)) = address {
@@ -213,35 +213,62 @@ pub async fn submit_reveal_aux(
213213
display_line!(
214214
context.io(),
215215
"Submitting a tx to reveal the public key for address \
216-
{address}..."
216+
{address}"
217217
);
218-
let (mut tx, signing_data) =
219-
tx::build_reveal_pk(context, &args, &public_key).await?;
218+
return Ok(Some(
219+
tx::build_reveal_pk(context, args, &public_key).await?,
220+
));
221+
}
222+
}
223+
224+
Ok(None)
225+
}
220226

221-
sign(context, &mut tx, &args, signing_data).await?;
227+
async fn batch_opt_reveal_pk_and_submit<N: Namada>(
228+
namada: &N,
229+
args: &args::Tx,
230+
owners: &[&Address],
231+
tx_data: (Tx, SigningTxData),
232+
) -> Result<ProcessTxResponse, error::Error>
233+
where
234+
<N::Client as namada_sdk::queries::Client>::Error: std::fmt::Display,
235+
{
236+
let mut batched_tx_data = vec![];
222237

223-
context.submit(tx, &args).await?;
238+
for owner in owners {
239+
if let Some(reveal_pk_tx_data) =
240+
submit_reveal_aux(namada, args, owner).await?
241+
{
242+
batched_tx_data.push(reveal_pk_tx_data);
224243
}
225244
}
245+
batched_tx_data.push(tx_data);
226246

227-
Ok(())
247+
let (mut batched_tx, batched_signing_data) =
248+
namada_sdk::tx::build_batch(batched_tx_data)?;
249+
for sig_data in batched_signing_data {
250+
sign(namada, &mut batched_tx, args, sig_data).await?;
251+
}
252+
253+
namada.submit(batched_tx, args).await
228254
}
229255

230256
pub async fn submit_bridge_pool_tx<N: Namada>(
231257
namada: &N,
232258
args: args::EthereumBridgePool,
233259
) -> Result<(), error::Error> {
234-
let tx_args = args.tx.clone();
235-
let (mut tx, signing_data) = args.clone().build(namada).await?;
260+
let bridge_pool_tx_data = args.clone().build(namada).await?;
236261

237262
if args.tx.dump_tx {
238-
tx::dump_tx(namada.io(), &args.tx, tx);
263+
tx::dump_tx(namada.io(), &args.tx, bridge_pool_tx_data.0);
239264
} else {
240-
submit_reveal_aux(namada, tx_args.clone(), &args.sender).await?;
241-
242-
sign(namada, &mut tx, &tx_args, signing_data).await?;
243-
244-
namada.submit(tx, &tx_args).await?;
265+
batch_opt_reveal_pk_and_submit(
266+
namada,
267+
&args.tx,
268+
&[&args.sender],
269+
bridge_pool_tx_data,
270+
)
271+
.await?;
245272
}
246273

247274
Ok(())
@@ -254,16 +281,18 @@ pub async fn submit_custom<N: Namada>(
254281
where
255282
<N::Client as namada_sdk::queries::Client>::Error: std::fmt::Display,
256283
{
257-
submit_reveal_aux(namada, args.tx.clone(), &args.owner).await?;
258-
259-
let (mut tx, signing_data) = args.build(namada).await?;
284+
let custom_tx_data = args.build(namada).await?;
260285

261286
if args.tx.dump_tx {
262-
tx::dump_tx(namada.io(), &args.tx, tx);
287+
tx::dump_tx(namada.io(), &args.tx, custom_tx_data.0);
263288
} else {
264-
sign(namada, &mut tx, &args.tx, signing_data).await?;
265-
266-
namada.submit(tx, &args.tx).await?;
289+
batch_opt_reveal_pk_and_submit(
290+
namada,
291+
&args.tx,
292+
&[&args.owner],
293+
custom_tx_data,
294+
)
295+
.await?;
267296
}
268297

269298
Ok(())
@@ -768,17 +797,20 @@ pub async fn submit_transparent_transfer(
768797
));
769798
}
770799

771-
for datum in args.data.iter() {
772-
submit_reveal_aux(namada, args.tx.clone(), &datum.source).await?;
773-
}
774-
775-
let (mut tx, signing_data) = args.clone().build(namada).await?;
800+
let transfer_data = args.clone().build(namada).await?;
776801

777802
if args.tx.dump_tx {
778-
tx::dump_tx(namada.io(), &args.tx, tx);
803+
tx::dump_tx(namada.io(), &args.tx, transfer_data.0);
779804
} else {
780-
sign(namada, &mut tx, &args.tx, signing_data).await?;
781-
namada.submit(tx, &args.tx).await?;
805+
let reveal_pks: Vec<_> =
806+
args.data.iter().map(|datum| &datum.source).collect();
807+
batch_opt_reveal_pk_and_submit(
808+
namada,
809+
&args.tx,
810+
&reveal_pks,
811+
transfer_data,
812+
)
813+
.await?;
782814
}
783815

784816
Ok(())
@@ -803,24 +835,29 @@ pub async fn submit_shielding_transfer(
803835
namada: &impl Namada,
804836
args: args::TxShieldingTransfer,
805837
) -> Result<(), error::Error> {
806-
for datum in args.data.iter() {
807-
submit_reveal_aux(namada, args.tx.clone(), &datum.source).await?;
808-
}
809-
810838
// Repeat once if the tx fails on a crossover of an epoch
811839
for _ in 0..2 {
812-
let (mut tx, signing_data, tx_epoch) =
813-
args.clone().build(namada).await?;
840+
let (tx, signing_data, tx_epoch) = args.clone().build(namada).await?;
814841

815842
if args.tx.dump_tx {
816843
tx::dump_tx(namada.io(), &args.tx, tx);
817844
break;
818-
} else {
819-
sign(namada, &mut tx, &args.tx, signing_data).await?;
820-
let cmt_hash = tx.first_commitments().unwrap().get_hash();
821-
let wrapper_hash = tx.wrapper_hash();
822-
let result = namada.submit(tx, &args.tx).await?;
823-
match result {
845+
}
846+
847+
let cmt_hash = tx.commitments().last().unwrap().get_hash();
848+
let wrapper_hash = tx.wrapper_hash();
849+
850+
let reveal_pks: Vec<_> =
851+
args.data.iter().map(|datum| &datum.source).collect();
852+
let result = batch_opt_reveal_pk_and_submit(
853+
namada,
854+
&args.tx,
855+
&reveal_pks,
856+
(tx, signing_data),
857+
)
858+
.await?;
859+
860+
match result {
824861
ProcessTxResponse::Applied(resp) if
825862
// If a transaction is rejected by a VP
826863
matches!(
@@ -846,7 +883,6 @@ pub async fn submit_shielding_transfer(
846883
// benefit from resubmission
847884
_ => break,
848885
}
849-
}
850886
}
851887
Ok(())
852888
}
@@ -873,20 +909,18 @@ pub async fn submit_ibc_transfer<N: Namada>(
873909
where
874910
<N::Client as namada_sdk::queries::Client>::Error: std::fmt::Display,
875911
{
876-
submit_reveal_aux(
877-
namada,
878-
args.tx.clone(),
879-
&args.source.effective_address(),
880-
)
881-
.await?;
882-
let (mut tx, signing_data, _) = args.build(namada).await?;
912+
let (tx, signing_data, _) = args.build(namada).await?;
883913

884914
if args.tx.dump_tx {
885915
tx::dump_tx(namada.io(), &args.tx, tx);
886916
} else {
887-
sign(namada, &mut tx, &args.tx, signing_data).await?;
888-
889-
namada.submit(tx, &args.tx).await?;
917+
batch_opt_reveal_pk_and_submit(
918+
namada,
919+
&args.tx,
920+
&[&args.source.effective_address()],
921+
(tx, signing_data),
922+
)
923+
.await?;
890924
}
891925
// NOTE that the tx could fail when its submission epoch doesn't match
892926
// construction epoch
@@ -904,7 +938,7 @@ where
904938
let current_epoch = rpc::query_and_print_epoch(namada).await;
905939
let governance_parameters =
906940
rpc::query_governance_parameters(namada.client()).await;
907-
let (mut tx_builder, signing_data) = if args.is_pgf_funding {
941+
let (proposal_tx_data, proposal_author) = if args.is_pgf_funding {
908942
let proposal =
909943
PgfFundingProposal::try_from(args.proposal_data.as_ref())
910944
.map_err(|e| {
@@ -916,11 +950,12 @@ where
916950
.map_err(|e| {
917951
error::TxSubmitError::InvalidProposal(e.to_string())
918952
})?;
953+
let proposal_author = proposal.proposal.author.clone();
919954

920-
submit_reveal_aux(namada, args.tx.clone(), &proposal.proposal.author)
921-
.await?;
922-
923-
tx::build_pgf_funding_proposal(namada, &args, proposal).await?
955+
(
956+
tx::build_pgf_funding_proposal(namada, &args, proposal).await?,
957+
proposal_author,
958+
)
924959
} else if args.is_pgf_stewards {
925960
let proposal = PgfStewardProposal::try_from(
926961
args.proposal_data.as_ref(),
@@ -947,11 +982,12 @@ where
947982
.map_err(|e| {
948983
error::TxSubmitError::InvalidProposal(e.to_string())
949984
})?;
985+
let proposal_author = proposal.proposal.author.clone();
950986

951-
submit_reveal_aux(namada, args.tx.clone(), &proposal.proposal.author)
952-
.await?;
953-
954-
tx::build_pgf_stewards_proposal(namada, &args, proposal).await?
987+
(
988+
tx::build_pgf_stewards_proposal(namada, &args, proposal).await?,
989+
proposal_author,
990+
)
955991
} else {
956992
let proposal = DefaultProposal::try_from(args.proposal_data.as_ref())
957993
.map_err(|e| {
@@ -976,19 +1012,24 @@ where
9761012
.map_err(|e| {
9771013
error::TxSubmitError::InvalidProposal(e.to_string())
9781014
})?;
1015+
let proposal_author = proposal.proposal.author.clone();
9791016

980-
submit_reveal_aux(namada, args.tx.clone(), &proposal.proposal.author)
981-
.await?;
982-
983-
tx::build_default_proposal(namada, &args, proposal).await?
1017+
(
1018+
tx::build_default_proposal(namada, &args, proposal).await?,
1019+
proposal_author,
1020+
)
9841021
};
9851022

9861023
if args.tx.dump_tx {
987-
tx::dump_tx(namada.io(), &args.tx, tx_builder);
1024+
tx::dump_tx(namada.io(), &args.tx, proposal_tx_data.0);
9881025
} else {
989-
sign(namada, &mut tx_builder, &args.tx, signing_data).await?;
990-
991-
namada.submit(tx_builder, &args.tx).await?;
1026+
batch_opt_reveal_pk_and_submit(
1027+
namada,
1028+
&args.tx,
1029+
&[&proposal_author],
1030+
proposal_tx_data,
1031+
)
1032+
.await?;
9921033
}
9931034

9941035
Ok(())
@@ -1096,7 +1137,13 @@ pub async fn submit_reveal_pk<N: Namada>(
10961137
where
10971138
<N::Client as namada_sdk::queries::Client>::Error: std::fmt::Display,
10981139
{
1099-
submit_reveal_aux(namada, args.tx, &(&args.public_key).into()).await?;
1140+
let tx_data =
1141+
submit_reveal_aux(namada, &args.tx, &(&args.public_key).into()).await?;
1142+
1143+
if let Some((mut tx, signing_data)) = tx_data {
1144+
sign(namada, &mut tx, &args.tx, signing_data).await?;
1145+
namada.submit(tx, &args.tx).await?;
1146+
}
11001147

11011148
Ok(())
11021149
}
@@ -1108,17 +1155,19 @@ pub async fn submit_bond<N: Namada>(
11081155
where
11091156
<N::Client as namada_sdk::queries::Client>::Error: std::fmt::Display,
11101157
{
1111-
let default_address = args.source.clone().unwrap_or(args.validator.clone());
1112-
submit_reveal_aux(namada, args.tx.clone(), &default_address).await?;
1113-
1114-
let (mut tx, signing_data) = args.build(namada).await?;
1158+
let submit_bond_tx_data = args.build(namada).await?;
11151159

11161160
if args.tx.dump_tx {
1117-
tx::dump_tx(namada.io(), &args.tx, tx);
1161+
tx::dump_tx(namada.io(), &args.tx, submit_bond_tx_data.0);
11181162
} else {
1119-
sign(namada, &mut tx, &args.tx, signing_data).await?;
1120-
1121-
namada.submit(tx, &args.tx).await?;
1163+
let default_address = args.source.as_ref().unwrap_or(&args.validator);
1164+
batch_opt_reveal_pk_and_submit(
1165+
namada,
1166+
&args.tx,
1167+
&[default_address],
1168+
submit_bond_tx_data,
1169+
)
1170+
.await?;
11221171
}
11231172

11241173
Ok(())

0 commit comments

Comments
 (0)