From 8c060ac144a5cfd613188a7b6f0bb33025e62556 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Mon, 4 Dec 2023 11:58:53 -0800 Subject: [PATCH 01/20] defined initial action order --- crates/core/transaction/src/action.rs | 28 +++++++++++++++++++++++ crates/core/transaction/src/plan/build.rs | 14 +++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/crates/core/transaction/src/action.rs b/crates/core/transaction/src/action.rs index 3e4a81540b..6a390ebc63 100644 --- a/crates/core/transaction/src/action.rs +++ b/crates/core/transaction/src/action.rs @@ -85,6 +85,34 @@ impl Action { Action::DaoOutput(_) => tracing::info_span!("DaoOutput", ?idx), } } + + /// Canonical action ordering according to protobuf definitions + pub fn variant_index(&self) -> usize { + match self { + Action::Spend(_) => 1, + Action::Output(_) => 2, + Action::Swap(_) => 3, + Action::SwapClaim(_) => 4, + Action::ValidatorDefinition(_) => 16, + Action::IbcRelay(_) => 17, + Action::ProposalSubmit(_) => 18, + Action::ProposalWithdraw(_) => 19, + Action::ValidatorVote(_) => 20, + Action::DelegatorVote(_) => 21, + Action::ProposalDepositClaim(_) => 22, + Action::PositionOpen(_) => 30, + Action::PositionClose(_) => 31, + Action::PositionWithdraw(_) => 32, + Action::PositionRewardClaim(_) => 34, + Action::Delegate(_) => 40, + Action::Undelegate(_) => 41, + Action::UndelegateClaim(_) => 42, + Action::DaoSpend(_) => 50, + Action::DaoOutput(_) => 51, + Action::DaoDeposit(_) => 52, + Action::Ics20Withdrawal(_) => 200, + } + } } impl IsAction for Action { diff --git a/crates/core/transaction/src/plan/build.rs b/crates/core/transaction/src/plan/build.rs index b772ea5c31..3985041a0b 100644 --- a/crates/core/transaction/src/plan/build.rs +++ b/crates/core/transaction/src/plan/build.rs @@ -153,6 +153,9 @@ impl TransactionPlan { }) .collect::>>()?; + // 1.5. Order the actions. + let actions = TransactionPlan::order_actions(actions); + // 2. Pass in the prebuilt actions to the build method. let tx = self .clone() @@ -192,11 +195,12 @@ impl TransactionPlan { }) .collect::>(); - // 1.5. Collect all of the actions. + // 1.5. Collect and order all of the actions. let mut actions = Vec::new(); for handle in action_handles { actions.push(handle.await??); } + let actions = TransactionPlan::order_actions(actions); // 2. Pass in the prebuilt actions to the build method. let tx = self @@ -209,4 +213,12 @@ impl TransactionPlan { // 4. Return the completed transaction. Ok(tx) } + + pub fn order_actions( + mut actions: Vec + ) -> Vec { + actions.sort_by_key(|action| action.variant_index()); + + actions + } } From d9b0fc831442b756cdda394ee99d814934fa0903 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Mon, 4 Dec 2023 12:11:58 -0800 Subject: [PATCH 02/20] reduced duplication --- crates/core/transaction/src/plan/build.rs | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/crates/core/transaction/src/plan/build.rs b/crates/core/transaction/src/plan/build.rs index 3985041a0b..2cb8e17877 100644 --- a/crates/core/transaction/src/plan/build.rs +++ b/crates/core/transaction/src/plan/build.rs @@ -21,7 +21,7 @@ impl TransactionPlan { /// [`ActionPlan`]s in the TransactionPlan. pub fn build_unauth_with_actions( self, - actions: Vec, + mut actions: Vec, witness_data: &WitnessData, ) -> Result { // Add the memo if it is planned. @@ -42,6 +42,9 @@ impl TransactionPlan { Some(DetectionData { fmd_clues }) }; + // Order the actions to reduce client distinguishability. + actions.sort_by_key(|action: &Action| action.variant_index()); + let transaction_body = TransactionBody { actions, transaction_parameters: TransactionParameters { @@ -140,7 +143,7 @@ impl TransactionPlan { auth_data: &AuthorizationData, ) -> Result { // 1. Build each action. - let actions = self + let mut actions = self .actions .iter() .map(|action_plan| { @@ -153,9 +156,6 @@ impl TransactionPlan { }) .collect::>>()?; - // 1.5. Order the actions. - let actions = TransactionPlan::order_actions(actions); - // 2. Pass in the prebuilt actions to the build method. let tx = self .clone() @@ -195,12 +195,11 @@ impl TransactionPlan { }) .collect::>(); - // 1.5. Collect and order all of the actions. + // 1.5. Collect all of the actions. let mut actions = Vec::new(); for handle in action_handles { actions.push(handle.await??); } - let actions = TransactionPlan::order_actions(actions); // 2. Pass in the prebuilt actions to the build method. let tx = self @@ -213,12 +212,4 @@ impl TransactionPlan { // 4. Return the completed transaction. Ok(tx) } - - pub fn order_actions( - mut actions: Vec - ) -> Vec { - actions.sort_by_key(|action| action.variant_index()); - - actions - } } From c1442d35c19078d8822e7f6000b376e7cb0ec1e8 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Mon, 4 Dec 2023 12:40:50 -0800 Subject: [PATCH 03/20] defined action plan order --- crates/core/transaction/src/plan/action.rs | 28 ++++++++++++++++++++++ crates/core/transaction/src/plan/build.rs | 2 +- crates/view/src/planner.rs | 3 +++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/crates/core/transaction/src/plan/action.rs b/crates/core/transaction/src/plan/action.rs index d3fba43cee..f92248bf87 100644 --- a/crates/core/transaction/src/plan/action.rs +++ b/crates/core/transaction/src/plan/action.rs @@ -164,6 +164,34 @@ impl ActionPlan { }) } + /// Canonical action plan ordering according to protobuf definitions + pub fn variant_index(&self) -> usize { + match self { + ActionPlan::Spend(_) => 1, + ActionPlan::Output(_) => 2, + ActionPlan::Swap(_) => 3, + ActionPlan::SwapClaim(_) => 4, + ActionPlan::ValidatorDefinition(_) => 16, + ActionPlan::IbcAction(_) => 17, + ActionPlan::ProposalSubmit(_) => 18, + ActionPlan::ProposalWithdraw(_) => 19, + ActionPlan::ValidatorVote(_) => 20, + ActionPlan::DelegatorVote(_) => 21, + ActionPlan::ProposalDepositClaim(_) => 22, + ActionPlan::Withdrawal(_) => 23, + ActionPlan::PositionOpen(_) => 30, + ActionPlan::PositionClose(_) => 31, + ActionPlan::PositionWithdraw(_) => 32, + ActionPlan::PositionRewardClaim(_) => 34, + ActionPlan::Delegate(_) => 40, + ActionPlan::Undelegate(_) => 41, + ActionPlan::UndelegateClaim(_) => 42, + ActionPlan::DaoSpend(_) => 50, + ActionPlan::DaoOutput(_) => 51, + ActionPlan::DaoDeposit(_) => 52, + } + } + pub fn balance(&self) -> Balance { use ActionPlan::*; diff --git a/crates/core/transaction/src/plan/build.rs b/crates/core/transaction/src/plan/build.rs index 2cb8e17877..dfce79459b 100644 --- a/crates/core/transaction/src/plan/build.rs +++ b/crates/core/transaction/src/plan/build.rs @@ -143,7 +143,7 @@ impl TransactionPlan { auth_data: &AuthorizationData, ) -> Result { // 1. Build each action. - let mut actions = self + let actions = self .actions .iter() .map(|action_plan| { diff --git a/crates/view/src/planner.rs b/crates/view/src/planner.rs index e0f8234b16..00f97eb0e5 100644 --- a/crates/view/src/planner.rs +++ b/crates/view/src/planner.rs @@ -634,6 +634,9 @@ impl Planner { tracing::debug!(plan = ?self.plan, "finished balancing transaction"); + // Order the action plans to reduce client distinguishability. + self.plan.actions.sort_by_key(|action: &ActionPlan| action.variant_index()); + // Clear the planner and pull out the plan to return self.balance = Balance::zero(); self.vote_intents = BTreeMap::new(); From 13202bfd3cb6b56e95c369a8a5ea5267253fffd0 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Mon, 4 Dec 2023 12:41:22 -0800 Subject: [PATCH 04/20] renabled assertions in pcli smoke test --- crates/bin/pcli/tests/network_integration.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/crates/bin/pcli/tests/network_integration.rs b/crates/bin/pcli/tests/network_integration.rs index e60c26918f..6c64f035e0 100644 --- a/crates/bin/pcli/tests/network_integration.rs +++ b/crates/bin/pcli/tests/network_integration.rs @@ -109,7 +109,7 @@ fn get_validator(tmpdir: &TempDir) -> String { captures.unwrap()[0].to_string() } -#[ignore] +// #[ignore] #[test] fn transaction_send_from_addr_0_to_addr_1() { let tmpdir = load_wallet_into_tmpdir(); @@ -166,15 +166,12 @@ fn transaction_send_from_addr_0_to_addr_1() { let tvp: ProtoTransactionView = serde_json::value::from_value(view_json).unwrap(); let tv: TransactionView = tvp.try_into().unwrap(); - // TODO: the first may no longer be a spend because of ordering changes. - // Let's not try to fix this at the moment. Later we can put a "canonical ordering" into the planner. - /* - // There will be a lot of ActionViews in the body... let's just check that one is a Spend. + println!("action_views is: {:?}", tv.body_view.action_views); + assert!(matches!( &tv.body_view.action_views[0], penumbra_transaction::ActionView::Spend(_) )); - */ // Inspect the TransactionView and ensure that we can read the memo text. let mv = tv From 370e7a96e79bbadbfd0184d83d1376ee90b9e3cc Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Mon, 4 Dec 2023 12:50:36 -0800 Subject: [PATCH 05/20] enable #ignore attribute in plci --- crates/bin/pcli/tests/network_integration.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/bin/pcli/tests/network_integration.rs b/crates/bin/pcli/tests/network_integration.rs index 6c64f035e0..ffd3eb15ed 100644 --- a/crates/bin/pcli/tests/network_integration.rs +++ b/crates/bin/pcli/tests/network_integration.rs @@ -109,7 +109,7 @@ fn get_validator(tmpdir: &TempDir) -> String { captures.unwrap()[0].to_string() } -// #[ignore] +#[ignore] #[test] fn transaction_send_from_addr_0_to_addr_1() { let tmpdir = load_wallet_into_tmpdir(); @@ -166,7 +166,6 @@ fn transaction_send_from_addr_0_to_addr_1() { let tvp: ProtoTransactionView = serde_json::value::from_value(view_json).unwrap(); let tv: TransactionView = tvp.try_into().unwrap(); - println!("action_views is: {:?}", tv.body_view.action_views); assert!(matches!( &tv.body_view.action_views[0], From 54ac73b5abb5375b09f3b91f808779652f112755 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Fri, 22 Mar 2024 13:19:03 -0700 Subject: [PATCH 06/20] add sort_actions --- crates/core/transaction/src/plan.rs | 6 ++++++ crates/core/transaction/src/plan/build.rs | 4 ++-- crates/view/src/planner.rs | 6 ++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/crates/core/transaction/src/plan.rs b/crates/core/transaction/src/plan.rs index 822a7888bf..9ad37ef65f 100644 --- a/crates/core/transaction/src/plan.rs +++ b/crates/core/transaction/src/plan.rs @@ -1,6 +1,7 @@ //! Declarative transaction plans, used for transaction authorization and //! creation. +use crate::action::Action; use anyhow::Result; use penumbra_dao::{DaoDeposit, DaoOutput, DaoSpend}; use penumbra_dex::{ @@ -46,6 +47,11 @@ pub struct TransactionPlan { } impl TransactionPlan { + pub fn sort_actions(mut actions: Vec) -> Vec { + actions.sort_by_key(|action: &Action| action.variant_index()); + actions + } + pub fn spend_plans(&self) -> impl Iterator { self.actions.iter().filter_map(|action| { if let ActionPlan::Spend(s) = action { diff --git a/crates/core/transaction/src/plan/build.rs b/crates/core/transaction/src/plan/build.rs index dfce79459b..a22e0db194 100644 --- a/crates/core/transaction/src/plan/build.rs +++ b/crates/core/transaction/src/plan/build.rs @@ -42,8 +42,8 @@ impl TransactionPlan { Some(DetectionData { fmd_clues }) }; - // Order the actions to reduce client distinguishability. - actions.sort_by_key(|action: &Action| action.variant_index()); + // Implement canonical ordering to the actions to reduce client distinguishability. + actions = TransactionPlan::sort_actions(actions); let transaction_body = TransactionBody { actions, diff --git a/crates/view/src/planner.rs b/crates/view/src/planner.rs index 00f97eb0e5..326d15d38a 100644 --- a/crates/view/src/planner.rs +++ b/crates/view/src/planner.rs @@ -634,8 +634,10 @@ impl Planner { tracing::debug!(plan = ?self.plan, "finished balancing transaction"); - // Order the action plans to reduce client distinguishability. - self.plan.actions.sort_by_key(|action: &ActionPlan| action.variant_index()); + // Implement canonical ordering to the action plans to reduce client distinguishability. + self.plan + .actions + .sort_by_key(|action: &ActionPlan| action.variant_index()); // Clear the planner and pull out the plan to return self.balance = Balance::zero(); From 59870a2dc9e98e2637c2ebd421bef9dbaebb620b Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Fri, 22 Mar 2024 13:25:36 -0700 Subject: [PATCH 07/20] function description --- crates/core/transaction/src/plan.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/core/transaction/src/plan.rs b/crates/core/transaction/src/plan.rs index 85343fcee2..b05959b0e6 100644 --- a/crates/core/transaction/src/plan.rs +++ b/crates/core/transaction/src/plan.rs @@ -49,6 +49,7 @@ pub struct TransactionPlan { } impl TransactionPlan { + /// Sort the actions by type, using the protobuf field number in the [`Action`]. pub fn sort_actions(mut actions: Vec) -> Vec { actions.sort_by_key(|action: &Action| action.variant_index()); actions From fa0433fd1e0b48f7a510c0988448fe64ae3919db Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Fri, 22 Mar 2024 13:33:09 -0700 Subject: [PATCH 08/20] cargo fmt --- crates/core/transaction/src/plan.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/transaction/src/plan.rs b/crates/core/transaction/src/plan.rs index b05959b0e6..53147032a7 100644 --- a/crates/core/transaction/src/plan.rs +++ b/crates/core/transaction/src/plan.rs @@ -49,7 +49,7 @@ pub struct TransactionPlan { } impl TransactionPlan { - /// Sort the actions by type, using the protobuf field number in the [`Action`]. + /// Sort the actions by type, using the protobuf field number in the [`Action`]. pub fn sort_actions(mut actions: Vec) -> Vec { actions.sort_by_key(|action: &Action| action.variant_index()); actions From f7de3ab9eb6058d07aea02307d5709e1f7078d04 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Fri, 22 Mar 2024 13:50:57 -0700 Subject: [PATCH 09/20] update protos --- crates/core/transaction/src/action.rs | 7 +++---- crates/core/transaction/src/plan/action.rs | 9 ++++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/crates/core/transaction/src/action.rs b/crates/core/transaction/src/action.rs index 8a1c841c71..c61e23cffb 100644 --- a/crates/core/transaction/src/action.rs +++ b/crates/core/transaction/src/action.rs @@ -128,13 +128,12 @@ impl Action { Action::PositionOpen(_) => 30, Action::PositionClose(_) => 31, Action::PositionWithdraw(_) => 32, - Action::PositionRewardClaim(_) => 34, Action::Delegate(_) => 40, Action::Undelegate(_) => 41, Action::UndelegateClaim(_) => 42, - Action::DaoSpend(_) => 50, - Action::DaoOutput(_) => 51, - Action::DaoDeposit(_) => 52, + Action::CommunityPoolSpend(_) => 50, + Action::CommunityPoolOutput(_) => 51, + Action::CommunityPoolDeposit(_) => 52, Action::Ics20Withdrawal(_) => 200, } } diff --git a/crates/core/transaction/src/plan/action.rs b/crates/core/transaction/src/plan/action.rs index b43059bf9e..1f6adcd67e 100644 --- a/crates/core/transaction/src/plan/action.rs +++ b/crates/core/transaction/src/plan/action.rs @@ -171,17 +171,16 @@ impl ActionPlan { ActionPlan::ValidatorVote(_) => 20, ActionPlan::DelegatorVote(_) => 21, ActionPlan::ProposalDepositClaim(_) => 22, - ActionPlan::Withdrawal(_) => 23, ActionPlan::PositionOpen(_) => 30, ActionPlan::PositionClose(_) => 31, ActionPlan::PositionWithdraw(_) => 32, - ActionPlan::PositionRewardClaim(_) => 34, ActionPlan::Delegate(_) => 40, ActionPlan::Undelegate(_) => 41, ActionPlan::UndelegateClaim(_) => 42, - ActionPlan::DaoSpend(_) => 50, - ActionPlan::DaoOutput(_) => 51, - ActionPlan::DaoDeposit(_) => 52, + ActionPlan::CommunityPoolSpend(_) => 50, + ActionPlan::CommunityPoolOutput(_) => 51, + ActionPlan::CommunityPoolDeposit(_) => 52, + ActionPlan::Ics20Withdrawal(_) => 200, } } From 25aaa855143a29d9b1d2c36f43d54991945f2864 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Fri, 22 Mar 2024 14:17:40 -0700 Subject: [PATCH 10/20] pass unit test --- crates/core/transaction/src/plan.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/core/transaction/src/plan.rs b/crates/core/transaction/src/plan.rs index 53147032a7..bfeafec1cc 100644 --- a/crates/core/transaction/src/plan.rs +++ b/crates/core/transaction/src/plan.rs @@ -438,7 +438,7 @@ mod tests { use crate::{ memo::MemoPlaintext, plan::{CluePlan, DetectionDataPlan, MemoPlan, TransactionPlan}, - TransactionParameters, WitnessData, + ActionPlan, TransactionParameters, WitnessData, }; /// This isn't an exhaustive test, but we don't currently have a @@ -505,7 +505,7 @@ mod tests { let mut rng = OsRng; let memo_plaintext = MemoPlaintext::new(Address::dummy(&mut rng), "".to_string()).unwrap(); - let plan = TransactionPlan { + let mut plan: TransactionPlan = TransactionPlan { // Put outputs first to check that the auth hash // computation is not affected by plan ordering. actions: vec![ @@ -533,6 +533,10 @@ mod tests { memo: Some(MemoPlan::new(&mut OsRng, memo_plaintext.clone()).unwrap()), }; + // Implement canonical ordering to the action plans to reduce client distinguishability. + plan.actions + .sort_by_key(|action: &ActionPlan| action.variant_index()); + println!("{}", serde_json::to_string_pretty(&plan).unwrap()); let plan_effect_hash = plan.effect_hash(fvk).unwrap(); From 165ce6bd14263df36c861aa9a16bcf5c836f4698 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Fri, 3 May 2024 13:55:27 -0700 Subject: [PATCH 11/20] cargo fmt --- crates/view/src/planner.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/view/src/planner.rs b/crates/view/src/planner.rs index 8e537629a6..fa593d9f0d 100644 --- a/crates/view/src/planner.rs +++ b/crates/view/src/planner.rs @@ -842,4 +842,4 @@ impl Planner { Ok(()) } -} \ No newline at end of file +} From 4595ae87019b9be238a43addc5a4547785bb69a1 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Fri, 3 May 2024 14:25:02 -0700 Subject: [PATCH 12/20] add auction to ordering --- crates/core/transaction/src/action.rs | 3 +++ crates/core/transaction/src/plan/action.rs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/crates/core/transaction/src/action.rs b/crates/core/transaction/src/action.rs index 7063570606..0ce196f431 100644 --- a/crates/core/transaction/src/action.rs +++ b/crates/core/transaction/src/action.rs @@ -152,6 +152,9 @@ impl Action { Action::CommunityPoolOutput(_) => 51, Action::CommunityPoolDeposit(_) => 52, Action::Ics20Withdrawal(_) => 200, + Action::ActionDutchAuctionSchedule(_) => 53, + Action::ActionDutchAuctionEnd(_) => 54, + Action::ActionDutchAuctionWithdraw(_) => 55, } } } diff --git a/crates/core/transaction/src/plan/action.rs b/crates/core/transaction/src/plan/action.rs index 528352018a..a02e07c300 100644 --- a/crates/core/transaction/src/plan/action.rs +++ b/crates/core/transaction/src/plan/action.rs @@ -192,6 +192,9 @@ impl ActionPlan { ActionPlan::CommunityPoolOutput(_) => 51, ActionPlan::CommunityPoolDeposit(_) => 52, ActionPlan::Ics20Withdrawal(_) => 200, + ActionPlan::ActionDutchAuctionSchedule(_) => 53, + ActionPlan::ActionDutchAuctionEnd(_) => 54, + ActionPlan::ActionDutchAuctionWithdraw(_) => 55, } } From 395e725125fc8f3f8b5fe5aa52d050cb9b707ff2 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Sat, 4 May 2024 02:52:00 -0700 Subject: [PATCH 13/20] add action plan ordering --- crates/core/transaction/src/plan.rs | 10 +++++++++- crates/core/transaction/src/plan/build.rs | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/core/transaction/src/plan.rs b/crates/core/transaction/src/plan.rs index 4d6a940fa5..4134c309eb 100644 --- a/crates/core/transaction/src/plan.rs +++ b/crates/core/transaction/src/plan.rs @@ -50,11 +50,19 @@ pub struct TransactionPlan { impl TransactionPlan { /// Sort the actions by type, using the protobuf field number in the [`Action`]. - pub fn sort_actions(mut actions: Vec) -> Vec { + pub fn sort_actions(&self, mut actions: Vec) -> Vec { actions.sort_by_key(|action: &Action| action.variant_index()); + actions } + /// Sort the action plans by type, using the protobuf field number in the [`ActionPlan`]. + pub fn sort_action_plans(&self, mut actions_plans: Vec) -> Vec { + actions_plans.sort_by_key(|action: &ActionPlan| action.variant_index()); + + actions_plans + } + /// Computes the [`EffectHash`] for the [`Transaction`] described by this /// [`TransactionPlan`]. /// diff --git a/crates/core/transaction/src/plan/build.rs b/crates/core/transaction/src/plan/build.rs index 88e14105e0..bbe725e25c 100644 --- a/crates/core/transaction/src/plan/build.rs +++ b/crates/core/transaction/src/plan/build.rs @@ -28,7 +28,7 @@ impl TransactionPlan { let detection_data = self.detection_data.as_ref().map(|x| x.detection_data()); // Implement canonical ordering to the actions to reduce client distinguishability. - actions = TransactionPlan::sort_actions(actions); + actions = self.sort_actions(actions); let transaction_body = TransactionBody { actions, From bba9b84ae048a8649fdc163aa5ebdd56c7831844 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Sun, 5 May 2024 14:06:48 -0700 Subject: [PATCH 14/20] add ordering to planner --- crates/core/transaction/src/plan.rs | 17 ++++------------- crates/core/transaction/src/plan/build.rs | 6 +----- crates/view/src/planner.rs | 4 ++++ 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/crates/core/transaction/src/plan.rs b/crates/core/transaction/src/plan.rs index 4134c309eb..d1d630e8e1 100644 --- a/crates/core/transaction/src/plan.rs +++ b/crates/core/transaction/src/plan.rs @@ -1,7 +1,6 @@ //! Declarative transaction plans, used for transaction authorization and //! creation. -use crate::action::Action; use anyhow::Result; use penumbra_community_pool::{CommunityPoolDeposit, CommunityPoolOutput, CommunityPoolSpend}; use penumbra_dex::{ @@ -49,18 +48,10 @@ pub struct TransactionPlan { } impl TransactionPlan { - /// Sort the actions by type, using the protobuf field number in the [`Action`]. - pub fn sort_actions(&self, mut actions: Vec) -> Vec { - actions.sort_by_key(|action: &Action| action.variant_index()); - - actions - } - - /// Sort the action plans by type, using the protobuf field number in the [`ActionPlan`]. - pub fn sort_action_plans(&self, mut actions_plans: Vec) -> Vec { - actions_plans.sort_by_key(|action: &ActionPlan| action.variant_index()); - - actions_plans + /// Sort the actions in [`TransactionPlan`] by type, using the protobuf field number in the [`ActionPlan`]. + pub fn sort_actions(&mut self) { + self.actions + .sort_by_key(|action: &ActionPlan| action.variant_index()); } /// Computes the [`EffectHash`] for the [`Transaction`] described by this diff --git a/crates/core/transaction/src/plan/build.rs b/crates/core/transaction/src/plan/build.rs index bbe725e25c..0b687b017f 100644 --- a/crates/core/transaction/src/plan/build.rs +++ b/crates/core/transaction/src/plan/build.rs @@ -15,7 +15,7 @@ impl TransactionPlan { /// [`ActionPlan`]s in the TransactionPlan. pub fn build_unauth_with_actions( self, - mut actions: Vec, + actions: Vec, witness_data: &WitnessData, ) -> Result { // Add the memo if it is planned. @@ -27,9 +27,6 @@ impl TransactionPlan { let detection_data = self.detection_data.as_ref().map(|x| x.detection_data()); - // Implement canonical ordering to the actions to reduce client distinguishability. - actions = self.sort_actions(actions); - let transaction_body = TransactionBody { actions, transaction_parameters: self.transaction_parameters, @@ -122,7 +119,6 @@ impl TransactionPlan { witness_data: &WitnessData, auth_data: &AuthorizationData, ) -> Result { - // TODO: stream progress updates // 1. Build each action. let actions = self .actions diff --git a/crates/view/src/planner.rs b/crates/view/src/planner.rs index fa593d9f0d..fd6526685b 100644 --- a/crates/view/src/planner.rs +++ b/crates/view/src/planner.rs @@ -734,6 +734,10 @@ impl Planner { memo: None, }; + // Implement a canonical ordering to the actions within the transaction + // plan to reduce client distinguishability. + plan.sort_actions(); + if let Some(memo_plan) = self.plan.memo.clone() { plan.memo = Some(MemoPlan::new(&mut OsRng, memo_plan.plaintext)?); } else if plan.output_plans().next().is_some() { From 0a495dab13a2c3a3cc0788000b70922c59ef6484 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Sun, 5 May 2024 14:11:00 -0700 Subject: [PATCH 15/20] format --- crates/view/src/planner.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/view/src/planner.rs b/crates/view/src/planner.rs index cd109d367a..ab98a6b743 100644 --- a/crates/view/src/planner.rs +++ b/crates/view/src/planner.rs @@ -585,7 +585,7 @@ impl Planner { self.transaction_parameters.clone(), memo_plan, )?; - + // Implement a canonical ordering to the actions within the transaction // plan to reduce client distinguishability. plan.sort_actions(); From c21908d10a9acbe85041195ec3515e461a7947bf Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Sun, 5 May 2024 14:17:45 -0700 Subject: [PATCH 16/20] mutable planner --- crates/view/src/planner.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/view/src/planner.rs b/crates/view/src/planner.rs index ab98a6b743..f74bb4cfce 100644 --- a/crates/view/src/planner.rs +++ b/crates/view/src/planner.rs @@ -579,7 +579,7 @@ impl Planner { // (This really should have been considered witness data. Oh well.) let fmd_params = view.fmd_parameters().await?; - let plan = mem::take(&mut self.action_list).into_plan( + let mut plan = mem::take(&mut self.action_list).into_plan( &mut self.rng, &fmd_params, self.transaction_parameters.clone(), From e15313dac5749589c170cecc9c09c67fe528597a Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Sun, 5 May 2024 14:53:50 -0700 Subject: [PATCH 17/20] use sorting method in test --- crates/core/transaction/src/plan.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/core/transaction/src/plan.rs b/crates/core/transaction/src/plan.rs index edfd72218c..cf79dbe19d 100644 --- a/crates/core/transaction/src/plan.rs +++ b/crates/core/transaction/src/plan.rs @@ -534,9 +534,8 @@ mod tests { memo: Some(MemoPlan::new(&mut OsRng, memo_plaintext.clone())), }; - // Implement canonical ordering to the action plans to reduce client distinguishability. - plan.actions - .sort_by_key(|action: &ActionPlan| action.variant_index()); + // Sort actions within the transaction plan. + plan.sort_actions(); println!("{}", serde_json::to_string_pretty(&plan).unwrap()); From e130bc88bd05fa9f40f6363a7d63564f3d1b69ab Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Sun, 5 May 2024 15:01:44 -0700 Subject: [PATCH 18/20] remove unused import --- crates/core/transaction/src/plan.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/transaction/src/plan.rs b/crates/core/transaction/src/plan.rs index cf79dbe19d..5935c292c0 100644 --- a/crates/core/transaction/src/plan.rs +++ b/crates/core/transaction/src/plan.rs @@ -439,7 +439,7 @@ mod tests { use crate::{ memo::MemoPlaintext, plan::{CluePlan, DetectionDataPlan, MemoPlan, TransactionPlan}, - ActionPlan, TransactionParameters, WitnessData, + TransactionParameters, WitnessData, }; /// This isn't an exhaustive test, but we don't currently have a From 68b173f78d055896b412dec5995f9d4047c125d8 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Mon, 6 May 2024 13:28:19 -0700 Subject: [PATCH 19/20] add ordering to action list --- crates/view/src/planner.rs | 4 ---- crates/view/src/planner/action_list.rs | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/view/src/planner.rs b/crates/view/src/planner.rs index f74bb4cfce..b61927e307 100644 --- a/crates/view/src/planner.rs +++ b/crates/view/src/planner.rs @@ -586,10 +586,6 @@ impl Planner { memo_plan, )?; - // Implement a canonical ordering to the actions within the transaction - // plan to reduce client distinguishability. - plan.sort_actions(); - // Reset the planner in case it were reused. We don't want people to do that // but otherwise we can't do builder method chaining with &mut self, and forcing // the builder to move between calls is annoying for callers who are building up diff --git a/crates/view/src/planner/action_list.rs b/crates/view/src/planner/action_list.rs index b0c8b3cb2a..d866eaa692 100644 --- a/crates/view/src/planner/action_list.rs +++ b/crates/view/src/planner/action_list.rs @@ -64,6 +64,10 @@ impl ActionList { }; plan.populate_detection_data(rng, fmd_params.precision_bits.into()); + // Implement a canonical ordering to the actions within the transaction + // plan to reduce client distinguishability. + plan.sort_actions(); + Ok(plan) } From adb4aefd0736e95cbac49097aaedf7996e2b9671 Mon Sep 17 00:00:00 2001 From: Tal Derei Date: Mon, 6 May 2024 13:40:22 -0700 Subject: [PATCH 20/20] remove warnings --- crates/view/src/planner.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/view/src/planner.rs b/crates/view/src/planner.rs index b61927e307..0eb99fcb58 100644 --- a/crates/view/src/planner.rs +++ b/crates/view/src/planner.rs @@ -579,7 +579,7 @@ impl Planner { // (This really should have been considered witness data. Oh well.) let fmd_params = view.fmd_parameters().await?; - let mut plan = mem::take(&mut self.action_list).into_plan( + let plan = mem::take(&mut self.action_list).into_plan( &mut self.rng, &fmd_params, self.transaction_parameters.clone(),