diff --git a/Cargo.lock b/Cargo.lock index 6c88b2ebe4..de3f1e249d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4653,6 +4653,7 @@ dependencies = [ "once_cell", "parking_lot", "penumbra-asset", + "penumbra-auction", "penumbra-community-pool", "penumbra-compact-block", "penumbra-dex", diff --git a/crates/bin/pcli/src/command/tx.rs b/crates/bin/pcli/src/command/tx.rs index 2803747423..8d674e79b1 100644 --- a/crates/bin/pcli/src/command/tx.rs +++ b/crates/bin/pcli/src/command/tx.rs @@ -1274,7 +1274,9 @@ impl TxCmd { .await?; app.build_and_submit_transaction(plan).await?; } - TxCmd::Position(PositionCmd::RewardClaim {}) => todo!(), + TxCmd::Position(PositionCmd::RewardClaim {}) => { + unimplemented!("deprecated, remove this") + } TxCmd::Position(PositionCmd::Replicate(replicate_cmd)) => { replicate_cmd.exec(app).await?; } diff --git a/crates/bin/pcli/src/transaction_view_ext.rs b/crates/bin/pcli/src/transaction_view_ext.rs index c2ed4b1c2c..b9d27c356d 100644 --- a/crates/bin/pcli/src/transaction_view_ext.rs +++ b/crates/bin/pcli/src/transaction_view_ext.rs @@ -378,6 +378,13 @@ impl TransactionViewExt for TransactionView { penumbra_transaction::ActionView::Delegate(_) => ["Delegation", ""], penumbra_transaction::ActionView::Undelegate(_) => ["Undelegation", ""], penumbra_transaction::ActionView::UndelegateClaim(_) => ["Undelegation Claim", ""], + penumbra_transaction::ActionView::ActionDutchAuctionSchedule(_) => todo!(), + penumbra_transaction::ActionView::ActionDutchAuctionEnd(_) => { + todo!() + } + penumbra_transaction::ActionView::ActionDutchAuctionWithdraw(_) => { + todo!() + } }; actions_table.add_row(row); diff --git a/crates/cnidarium/src/gen/proto_descriptor.bin.no_lfs b/crates/cnidarium/src/gen/proto_descriptor.bin.no_lfs index 2473a12985..d50e1bd881 100644 Binary files a/crates/cnidarium/src/gen/proto_descriptor.bin.no_lfs and b/crates/cnidarium/src/gen/proto_descriptor.bin.no_lfs differ diff --git a/crates/core/app/Cargo.toml b/crates/core/app/Cargo.toml index 3210cde095..3a3372ac51 100644 --- a/crates/core/app/Cargo.toml +++ b/crates/core/app/Cargo.toml @@ -36,6 +36,7 @@ metrics = { workspace = true } once_cell = { workspace = true } parking_lot = { workspace = true } penumbra-asset = { workspace = true, default-features = true } +penumbra-auction = { workspace = true, default-features = true } penumbra-community-pool = { workspace = true, default-features = true } penumbra-compact-block = { workspace = true, default-features = true } penumbra-dex = { workspace = true, default-features = true } diff --git a/crates/core/app/src/action_handler/actions.rs b/crates/core/app/src/action_handler/actions.rs index 99f80c8005..4d74d185db 100644 --- a/crates/core/app/src/action_handler/actions.rs +++ b/crates/core/app/src/action_handler/actions.rs @@ -48,9 +48,9 @@ impl AppActionHandler for Action { Action::CommunityPoolSpend(action) => action.check_stateless(()).await, Action::CommunityPoolOutput(action) => action.check_stateless(()).await, Action::CommunityPoolDeposit(action) => action.check_stateless(()).await, - Action::ActionDutchAuctionSchedule(_) => todo!(), - Action::ActionDutchAuctionEnd(_) => todo!(), - Action::ActionDutchAuctionWithdraw(_) => todo!(), + Action::ActionDutchAuctionSchedule(action) => action.check_stateless(()).await, + Action::ActionDutchAuctionEnd(action) => action.check_stateless(()).await, + Action::ActionDutchAuctionWithdraw(action) => action.check_stateless(()).await, } } @@ -95,9 +95,9 @@ impl AppActionHandler for Action { Action::CommunityPoolSpend(action) => action.check_historical(state).await, Action::CommunityPoolOutput(action) => action.check_historical(state).await, Action::CommunityPoolDeposit(action) => action.check_historical(state).await, - Action::ActionDutchAuctionSchedule(_) => todo!(), - Action::ActionDutchAuctionEnd(_) => todo!(), - Action::ActionDutchAuctionWithdraw(_) => todo!(), + Action::ActionDutchAuctionSchedule(action) => action.check_historical(state).await, + Action::ActionDutchAuctionEnd(action) => action.check_historical(state).await, + Action::ActionDutchAuctionWithdraw(action) => action.check_historical(state).await, } } @@ -130,9 +130,9 @@ impl AppActionHandler for Action { Action::CommunityPoolSpend(action) => action.check_and_execute(state).await, Action::CommunityPoolOutput(action) => action.check_and_execute(state).await, Action::CommunityPoolDeposit(action) => action.check_and_execute(state).await, - Action::ActionDutchAuctionSchedule(_) => todo!(), - Action::ActionDutchAuctionEnd(_) => todo!(), - Action::ActionDutchAuctionWithdraw(_) => todo!(), + Action::ActionDutchAuctionSchedule(action) => action.check_and_execute(state).await, + Action::ActionDutchAuctionEnd(action) => action.check_and_execute(state).await, + Action::ActionDutchAuctionWithdraw(action) => action.check_and_execute(state).await, } } } diff --git a/crates/core/app/src/action_handler/actions/submit.rs b/crates/core/app/src/action_handler/actions/submit.rs index 4bfb0282d2..1fddfed9cd 100644 --- a/crates/core/app/src/action_handler/actions/submit.rs +++ b/crates/core/app/src/action_handler/actions/submit.rs @@ -116,10 +116,10 @@ impl AppActionHandler for ProposalSubmit { | CommunityPoolSpend(_) | CommunityPoolOutput(_) | Ics20Withdrawal(_) - | CommunityPoolDeposit(_) => {} - ActionDutchAuctionSchedule(_) => todo!(), - ActionDutchAuctionEnd(_) => todo!(), - ActionDutchAuctionWithdraw(_) => todo!(), + | CommunityPoolDeposit(_) + | ActionDutchAuctionSchedule(_) + | ActionDutchAuctionEnd(_) + | ActionDutchAuctionWithdraw(_) => {} } } } diff --git a/crates/core/component/auction/src/auction/dutch/actions/end.rs b/crates/core/component/auction/src/auction/dutch/actions/end.rs index e06464dddf..b0ce842fb5 100644 --- a/crates/core/component/auction/src/auction/dutch/actions/end.rs +++ b/crates/core/component/auction/src/auction/dutch/actions/end.rs @@ -1,6 +1,7 @@ use anyhow::anyhow; use penumbra_asset::{Balance, Value}; use penumbra_proto::{core::component::auction::v1alpha1 as pb, DomainType}; +use penumbra_txhash::{EffectHash, EffectingData}; use serde::{Deserialize, Serialize}; use crate::auction::{id::AuctionId, AuctionNft}; @@ -39,6 +40,12 @@ impl ActionDutchAuctionEnd { } } +/* Effect hash */ +impl EffectingData for ActionDutchAuctionEnd { + fn effect_hash(&self) -> EffectHash { + EffectHash::from_proto_effecting_data(&self.to_proto()) + } +} /* Protobuf impls */ impl DomainType for ActionDutchAuctionEnd { type Proto = pb::ActionDutchAuctionEnd; diff --git a/crates/core/component/auction/src/auction/dutch/actions/mod.rs b/crates/core/component/auction/src/auction/dutch/actions/mod.rs index c9451d47c5..90d3c2a813 100644 --- a/crates/core/component/auction/src/auction/dutch/actions/mod.rs +++ b/crates/core/component/auction/src/auction/dutch/actions/mod.rs @@ -6,3 +6,6 @@ pub use end::ActionDutchAuctionEnd; pub mod withdraw; pub use withdraw::ActionDutchAuctionWithdraw; + +pub mod plan; +pub use plan::ActionDutchAuctionWithdrawPlan; diff --git a/crates/core/component/auction/src/auction/dutch/actions/plan.rs b/crates/core/component/auction/src/auction/dutch/actions/plan.rs new file mode 100644 index 0000000000..18ae8e2917 --- /dev/null +++ b/crates/core/component/auction/src/auction/dutch/actions/plan.rs @@ -0,0 +1,100 @@ +use ark_ff::Zero; +use decaf377::Fr; +use penumbra_asset::{balance, Balance, Value}; +use penumbra_proto::{penumbra::core::component::auction::v1alpha1 as pb, DomainType}; +use serde::{Deserialize, Serialize}; + +use crate::auction::{dutch::ActionDutchAuctionWithdraw, AuctionId, AuctionNft}; + +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde( + try_from = "pb::ActionDutchAuctionWithdrawPlan", + into = "pb::ActionDutchAuctionWithdrawPlan" +)] +pub struct ActionDutchAuctionWithdrawPlan { + pub auction_id: AuctionId, + pub seq: u64, + pub reserves_input: Value, + pub reserves_output: Value, +} + +impl ActionDutchAuctionWithdrawPlan { + pub fn to_action(&self) -> ActionDutchAuctionWithdraw { + ActionDutchAuctionWithdraw { + auction_id: self.auction_id, + reserves_commitment: self.reserves_commitment(), + seq: self.seq, + } + } + + pub fn reserves_balance(&self) -> Balance { + Balance::from(self.reserves_input) + Balance::from(self.reserves_output) + } + + pub fn reserves_commitment(&self) -> balance::Commitment { + self.reserves_balance().commit(Fr::zero()) + } + + pub fn balance(&self) -> Balance { + let reserves_balance = self.reserves_balance(); + let prev_auction_nft = Balance::from(Value { + amount: 1u128.into(), + asset_id: AuctionNft::new(self.auction_id, self.seq.saturating_sub(1)).asset_id(), + }); + + let next_auction_nft = Balance::from(Value { + amount: 1u128.into(), + asset_id: AuctionNft::new(self.auction_id, self.seq).asset_id(), + }); + + reserves_balance + next_auction_nft - prev_auction_nft + } +} + +impl DomainType for ActionDutchAuctionWithdrawPlan { + type Proto = pb::ActionDutchAuctionWithdrawPlan; +} + +impl From for pb::ActionDutchAuctionWithdrawPlan { + fn from(domain: ActionDutchAuctionWithdrawPlan) -> Self { + Self { + auction_id: Some(domain.auction_id.into()), + seq: domain.seq, + reserves_input: Some(domain.reserves_input.into()), + reserves_output: Some(domain.reserves_output.into()), + } + } +} + +impl TryFrom for ActionDutchAuctionWithdrawPlan { + type Error = anyhow::Error; + fn try_from(msg: pb::ActionDutchAuctionWithdrawPlan) -> Result { + Ok(Self { + auction_id: msg + .auction_id + .ok_or_else(|| { + anyhow::anyhow!( + "ActionDutchAuctionWithdrawPlan message is missing an auction id" + ) + })? + .try_into()?, + seq: msg.seq, + reserves_input: msg + .reserves_input + .ok_or_else(|| { + anyhow::anyhow!( + "ActionDutchAuctionWithdrawPlan message is missing a reserves input" + ) + })? + .try_into()?, + reserves_output: msg + .reserves_output + .ok_or_else(|| { + anyhow::anyhow!( + "ActionDutchAuctionWithdrawPlan message is missing a reserves output" + ) + })? + .try_into()?, + }) + } +} diff --git a/crates/core/component/auction/src/auction/dutch/actions/schedule.rs b/crates/core/component/auction/src/auction/dutch/actions/schedule.rs index 370a6222f6..c97e1cfed4 100644 --- a/crates/core/component/auction/src/auction/dutch/actions/schedule.rs +++ b/crates/core/component/auction/src/auction/dutch/actions/schedule.rs @@ -2,6 +2,7 @@ use crate::auction::{dutch::DutchAuctionDescription, nft::AuctionNft}; use anyhow::anyhow; use penumbra_asset::{Balance, Value}; use penumbra_proto::{core::component::auction::v1alpha1 as pb, DomainType}; +use penumbra_txhash::{EffectHash, EffectingData}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -37,6 +38,13 @@ impl ActionDutchAuctionSchedule { } } +/* Effect hash */ +impl EffectingData for ActionDutchAuctionSchedule { + fn effect_hash(&self) -> EffectHash { + EffectHash::from_proto_effecting_data(&self.to_proto()) + } +} + /* Protobuf impls */ impl DomainType for ActionDutchAuctionSchedule { type Proto = pb::ActionDutchAuctionSchedule; diff --git a/crates/core/component/auction/src/auction/dutch/actions/withdraw.rs b/crates/core/component/auction/src/auction/dutch/actions/withdraw.rs index d7c4113e46..b40e0ade45 100644 --- a/crates/core/component/auction/src/auction/dutch/actions/withdraw.rs +++ b/crates/core/component/auction/src/auction/dutch/actions/withdraw.rs @@ -4,6 +4,7 @@ use ark_ff::Zero; use decaf377_rdsa::Fr; use penumbra_asset::{balance, Balance, Value}; use penumbra_proto::{core::component::auction::v1alpha1 as pb, DomainType}; +use penumbra_txhash::{EffectHash, EffectingData}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -55,6 +56,13 @@ impl ActionDutchAuctionWithdraw { } } +/* Effect hash */ +impl EffectingData for ActionDutchAuctionWithdraw { + fn effect_hash(&self) -> EffectHash { + EffectHash::from_proto_effecting_data(&self.to_proto()) + } +} + /* Protobuf impls */ impl DomainType for ActionDutchAuctionWithdraw { type Proto = pb::ActionDutchAuctionWithdraw; diff --git a/crates/core/component/auction/src/component/action_handler/dutch/schedule.rs b/crates/core/component/auction/src/component/action_handler/dutch/schedule.rs index 8ee70b4547..6f2e7f21dc 100644 --- a/crates/core/component/auction/src/component/action_handler/dutch/schedule.rs +++ b/crates/core/component/auction/src/component/action_handler/dutch/schedule.rs @@ -4,7 +4,7 @@ use anyhow::{ensure, Result}; use async_trait::async_trait; use cnidarium::StateWrite; use cnidarium_component::ActionHandler; -use penumbra_sct::component::clock::EpochRead; // AuctionRead? +use penumbra_sct::component::clock::EpochRead; use crate::auction::dutch::ActionDutchAuctionSchedule; use crate::component::DutchAuctionManager; diff --git a/crates/core/transaction/src/action.rs b/crates/core/transaction/src/action.rs index b103c88f9b..8b7d7a4ebd 100644 --- a/crates/core/transaction/src/action.rs +++ b/crates/core/transaction/src/action.rs @@ -71,10 +71,9 @@ impl EffectingData for Action { Action::CommunityPoolSpend(d) => d.effect_hash(), Action::CommunityPoolOutput(d) => d.effect_hash(), Action::CommunityPoolDeposit(d) => d.effect_hash(), - // TODO: fill in skeleton - Action::ActionDutchAuctionSchedule(_) => todo!(), - Action::ActionDutchAuctionEnd(_) => todo!(), - Action::ActionDutchAuctionWithdraw(_) => todo!(), + Action::ActionDutchAuctionSchedule(a) => a.effect_hash(), + Action::ActionDutchAuctionEnd(a) => a.effect_hash(), + Action::ActionDutchAuctionWithdraw(a) => a.effect_hash(), } } } @@ -119,10 +118,13 @@ impl Action { Action::CommunityPoolDeposit(_) => tracing::info_span!("CommunityPoolDeposit", ?idx), Action::CommunityPoolSpend(_) => tracing::info_span!("CommunityPoolSpend", ?idx), Action::CommunityPoolOutput(_) => tracing::info_span!("CommunityPoolOutput", ?idx), - // TODO: fill in skeleton - Action::ActionDutchAuctionSchedule(_) => todo!(), - Action::ActionDutchAuctionEnd(_) => todo!(), - Action::ActionDutchAuctionWithdraw(_) => todo!(), + Action::ActionDutchAuctionSchedule(_) => { + tracing::info_span!("ActionDutchAuctionSchedule", ?idx) + } + Action::ActionDutchAuctionEnd(_) => tracing::info_span!("ActionDutchAuctionEnd", ?idx), + Action::ActionDutchAuctionWithdraw(_) => { + tracing::info_span!("ActionDutchAuctionWithdraw", ?idx) + } } } } @@ -154,9 +156,9 @@ impl IsAction for Action { Action::IbcRelay(x) => x.balance_commitment(), Action::ValidatorDefinition(_) => balance::Commitment::default(), // TODO: fill in skeleton - Action::ActionDutchAuctionSchedule(_) => todo!(), - Action::ActionDutchAuctionEnd(_) => todo!(), - Action::ActionDutchAuctionWithdraw(_) => todo!(), + Action::ActionDutchAuctionSchedule(action) => action.balance_commitment(), + Action::ActionDutchAuctionEnd(action) => action.balance_commitment(), + Action::ActionDutchAuctionWithdraw(action) => action.balance_commitment(), } } @@ -181,10 +183,8 @@ impl IsAction for Action { Action::CommunityPoolSpend(x) => x.view_from_perspective(txp), Action::CommunityPoolOutput(x) => x.view_from_perspective(txp), Action::CommunityPoolDeposit(x) => x.view_from_perspective(txp), - // TODO: figure out where to implement the actual decryption methods for these? where are their action definitions? Action::ValidatorDefinition(x) => ActionView::ValidatorDefinition(x.to_owned()), Action::IbcRelay(x) => ActionView::IbcRelay(x.to_owned()), - // TODO: fill in skeleton Action::ActionDutchAuctionSchedule(_) => todo!(), Action::ActionDutchAuctionEnd(_) => todo!(), Action::ActionDutchAuctionWithdraw(_) => todo!(), @@ -262,10 +262,15 @@ impl From for pb::Action { Action::CommunityPoolDeposit(inner) => pb::Action { action: Some(pb::action::Action::CommunityPoolDeposit(inner.into())), }, - // TODO: fill in skeleton - Action::ActionDutchAuctionSchedule(_) => todo!(), - Action::ActionDutchAuctionEnd(_) => todo!(), - Action::ActionDutchAuctionWithdraw(_) => todo!(), + Action::ActionDutchAuctionSchedule(inner) => pb::Action { + action: Some(pb::action::Action::ActionDutchAuctionSchedule(inner.into())), + }, + Action::ActionDutchAuctionEnd(inner) => pb::Action { + action: Some(pb::action::Action::ActionDutchAuctionEnd(inner.into())), + }, + Action::ActionDutchAuctionWithdraw(inner) => pb::Action { + action: Some(pb::action::Action::ActionDutchAuctionWithdraw(inner.into())), + }, } } } @@ -331,6 +336,15 @@ impl TryFrom for Action { pb::action::Action::CommunityPoolDeposit(inner) => { Ok(Action::CommunityPoolDeposit(inner.try_into()?)) } + pb::action::Action::ActionDutchAuctionSchedule(inner) => { + Ok(Action::ActionDutchAuctionSchedule(inner.try_into()?)) + } + pb::action::Action::ActionDutchAuctionEnd(inner) => { + Ok(Action::ActionDutchAuctionEnd(inner.try_into()?)) + } + pb::action::Action::ActionDutchAuctionWithdraw(inner) => { + Ok(Action::ActionDutchAuctionWithdraw(inner.try_into()?)) + } } } } diff --git a/crates/core/transaction/src/is_action.rs b/crates/core/transaction/src/is_action.rs index f580e902ad..e534daaf22 100644 --- a/crates/core/transaction/src/is_action.rs +++ b/crates/core/transaction/src/is_action.rs @@ -416,7 +416,7 @@ impl IsAction for ActionDutchAuctionSchedule { } fn view_from_perspective(&self, _txp: &TransactionPerspective) -> ActionView { - todo!() + ActionView::ActionDutchAuctionSchedule(self.to_owned()) } } @@ -426,7 +426,7 @@ impl IsAction for ActionDutchAuctionEnd { } fn view_from_perspective(&self, _txp: &TransactionPerspective) -> ActionView { - todo!() + ActionView::ActionDutchAuctionEnd(self.to_owned()) } } @@ -436,6 +436,6 @@ impl IsAction for ActionDutchAuctionWithdraw { } fn view_from_perspective(&self, _txp: &TransactionPerspective) -> ActionView { - todo!() + ActionView::ActionDutchAuctionWithdraw(self.to_owned()) } } diff --git a/crates/core/transaction/src/plan/action.rs b/crates/core/transaction/src/plan/action.rs index f314ea2b1e..5d3039375d 100644 --- a/crates/core/transaction/src/plan/action.rs +++ b/crates/core/transaction/src/plan/action.rs @@ -6,7 +6,7 @@ use decaf377::Fr; use penumbra_asset::Balance; use penumbra_auction::auction::dutch::actions::ActionDutchAuctionEnd; use penumbra_auction::auction::dutch::actions::ActionDutchAuctionSchedule; -use penumbra_auction::auction::dutch::actions::ActionDutchAuctionWithdraw; +use penumbra_auction::auction::dutch::actions::ActionDutchAuctionWithdrawPlan; use penumbra_community_pool::{CommunityPoolDeposit, CommunityPoolOutput, CommunityPoolSpend}; use penumbra_txhash::{EffectHash, EffectingData}; @@ -81,7 +81,7 @@ pub enum ActionPlan { ActionDutchAuctionSchedule(ActionDutchAuctionSchedule), ActionDutchAuctionEnd(ActionDutchAuctionEnd), - ActionDutchAuctionWithdraw(ActionDutchAuctionWithdraw), + ActionDutchAuctionWithdraw(ActionDutchAuctionWithdrawPlan), } impl ActionPlan { @@ -160,10 +160,11 @@ impl ActionPlan { CommunityPoolOutput(plan) => Action::CommunityPoolOutput(plan.clone()), CommunityPoolDeposit(plan) => Action::CommunityPoolDeposit(plan.clone()), Ics20Withdrawal(plan) => Action::Ics20Withdrawal(plan.clone()), - // TODO: fill in skeleton - ActionDutchAuctionSchedule(_) => todo!(), - ActionDutchAuctionEnd(_) => todo!(), - ActionDutchAuctionWithdraw(_) => todo!(), + ActionDutchAuctionSchedule(plan) => Action::ActionDutchAuctionSchedule(plan.clone()), + ActionDutchAuctionEnd(plan) => Action::ActionDutchAuctionEnd(plan.clone()), + ActionDutchAuctionWithdraw(plan) => { + Action::ActionDutchAuctionWithdraw(plan.to_action()) + } }) } @@ -189,12 +190,12 @@ impl ActionPlan { PositionClose(position_close) => position_close.balance(), PositionWithdraw(position_withdraw) => position_withdraw.balance(), Ics20Withdrawal(withdrawal) => withdrawal.balance(), + ActionDutchAuctionSchedule(action) => action.balance(), + ActionDutchAuctionEnd(action) => action.balance(), + ActionDutchAuctionWithdraw(action) => action.balance(), + // None of these contribute to transaction balance: IbcAction(_) | ValidatorDefinition(_) | ValidatorVote(_) => Balance::default(), - // TODO: fill in skeleton - ActionDutchAuctionSchedule(_) => todo!(), - ActionDutchAuctionEnd(_) => todo!(), - ActionDutchAuctionWithdraw(_) => todo!(), } } @@ -223,10 +224,9 @@ impl ActionPlan { CommunityPoolOutput(_) => Fr::zero(), CommunityPoolDeposit(_) => Fr::zero(), Ics20Withdrawal(_) => Fr::zero(), - // TODO: fill in skeleton - ActionDutchAuctionSchedule(_) => todo!(), - ActionDutchAuctionEnd(_) => todo!(), - ActionDutchAuctionWithdraw(_) => todo!(), + ActionDutchAuctionSchedule(_) => Fr::zero(), + ActionDutchAuctionEnd(_) => Fr::zero(), + ActionDutchAuctionWithdraw(_) => Fr::zero(), } } @@ -256,10 +256,9 @@ impl ActionPlan { CommunityPoolOutput(plan) => plan.effect_hash(), CommunityPoolDeposit(plan) => plan.effect_hash(), Ics20Withdrawal(plan) => plan.effect_hash(), - // TODO: fill in skeleton - ActionDutchAuctionSchedule(_) => todo!(), - ActionDutchAuctionEnd(_) => todo!(), - ActionDutchAuctionWithdraw(_) => todo!(), + ActionDutchAuctionSchedule(plan) => plan.effect_hash(), + ActionDutchAuctionEnd(plan) => plan.effect_hash(), + ActionDutchAuctionWithdraw(plan) => plan.to_action().effect_hash(), } } } @@ -440,10 +439,21 @@ impl From for pb_t::ActionPlan { ActionPlan::Ics20Withdrawal(inner) => pb_t::ActionPlan { action: Some(pb_t::action_plan::Action::Ics20Withdrawal(inner.into())), }, - // TODO: fill in skeleton - ActionPlan::ActionDutchAuctionSchedule(_) => todo!(), - ActionPlan::ActionDutchAuctionEnd(_) => todo!(), - ActionPlan::ActionDutchAuctionWithdraw(_) => todo!(), + ActionPlan::ActionDutchAuctionSchedule(inner) => pb_t::ActionPlan { + action: Some(pb_t::action_plan::Action::ActionDutchAuctionSchedule( + inner.into(), + )), + }, + ActionPlan::ActionDutchAuctionEnd(inner) => pb_t::ActionPlan { + action: Some(pb_t::action_plan::Action::ActionDutchAuctionEnd( + inner.into(), + )), + }, + ActionPlan::ActionDutchAuctionWithdraw(inner) => pb_t::ActionPlan { + action: Some(pb_t::action_plan::Action::ActionDutchAuctionWithdraw( + inner.into(), + )), + }, } } } @@ -517,6 +527,15 @@ impl TryFrom for ActionPlan { pb_t::action_plan::Action::CommunityPoolOutput(inner) => { Ok(ActionPlan::CommunityPoolOutput(inner.try_into()?)) } + pb_t::action_plan::Action::ActionDutchAuctionSchedule(inner) => { + Ok(ActionPlan::ActionDutchAuctionSchedule(inner.try_into()?)) + } + pb_t::action_plan::Action::ActionDutchAuctionEnd(inner) => { + Ok(ActionPlan::ActionDutchAuctionEnd(inner.try_into()?)) + } + pb_t::action_plan::Action::ActionDutchAuctionWithdraw(inner) => { + Ok(ActionPlan::ActionDutchAuctionWithdraw(inner.try_into()?)) + } pb_t::action_plan::Action::Ics20Withdrawal(inner) => { Ok(ActionPlan::Ics20Withdrawal(inner.try_into()?)) } diff --git a/crates/core/transaction/src/view/action_view.rs b/crates/core/transaction/src/view/action_view.rs index 84aeb1e0ba..ef00229838 100644 --- a/crates/core/transaction/src/view/action_view.rs +++ b/crates/core/transaction/src/view/action_view.rs @@ -1,3 +1,6 @@ +use penumbra_auction::auction::dutch::{ + ActionDutchAuctionEnd, ActionDutchAuctionSchedule, ActionDutchAuctionWithdraw, +}; use penumbra_community_pool::{CommunityPoolDeposit, CommunityPoolOutput, CommunityPoolSpend}; use penumbra_dex::{ lp::action::{PositionClose, PositionOpen, PositionWithdraw}, @@ -44,6 +47,9 @@ pub enum ActionView { CommunityPoolDeposit(CommunityPoolDeposit), CommunityPoolSpend(CommunityPoolSpend), CommunityPoolOutput(CommunityPoolOutput), + ActionDutchAuctionSchedule(ActionDutchAuctionSchedule), + ActionDutchAuctionEnd(ActionDutchAuctionEnd), + ActionDutchAuctionWithdraw(ActionDutchAuctionWithdraw), } impl DomainType for ActionView { @@ -86,6 +92,13 @@ impl TryFrom for ActionView { AV::CommunityPoolDeposit(x) => ActionView::CommunityPoolDeposit(x.try_into()?), AV::CommunityPoolSpend(x) => ActionView::CommunityPoolSpend(x.try_into()?), AV::CommunityPoolOutput(x) => ActionView::CommunityPoolOutput(x.try_into()?), + AV::ActionDutchAuctionSchedule(x) => { + ActionView::ActionDutchAuctionSchedule(x.try_into()?) + } + AV::ActionDutchAuctionEnd(x) => ActionView::ActionDutchAuctionEnd(x.try_into()?), + AV::ActionDutchAuctionWithdraw(x) => { + ActionView::ActionDutchAuctionWithdraw(x.try_into()?) + } }, ) } @@ -117,6 +130,13 @@ impl From for pbt::ActionView { ActionView::CommunityPoolDeposit(x) => AV::CommunityPoolDeposit(x.into()), ActionView::CommunityPoolSpend(x) => AV::CommunityPoolSpend(x.into()), ActionView::CommunityPoolOutput(x) => AV::CommunityPoolOutput(x.into()), + ActionView::ActionDutchAuctionSchedule(x) => { + AV::ActionDutchAuctionSchedule(x.into()) + } + ActionView::ActionDutchAuctionEnd(x) => AV::ActionDutchAuctionEnd(x.into()), + ActionView::ActionDutchAuctionWithdraw(x) => { + AV::ActionDutchAuctionWithdraw(x.into()) + } }), } } @@ -146,6 +166,9 @@ impl From for Action { ActionView::CommunityPoolDeposit(x) => Action::CommunityPoolDeposit(x), ActionView::CommunityPoolSpend(x) => Action::CommunityPoolSpend(x), ActionView::CommunityPoolOutput(x) => Action::CommunityPoolOutput(x), + ActionView::ActionDutchAuctionSchedule(x) => Action::ActionDutchAuctionSchedule(x), + ActionView::ActionDutchAuctionEnd(x) => Action::ActionDutchAuctionEnd(x), + ActionView::ActionDutchAuctionWithdraw(x) => Action::ActionDutchAuctionWithdraw(x), } } } diff --git a/crates/proto/src/gen/penumbra.core.component.auction.v1alpha1.rs b/crates/proto/src/gen/penumbra.core.component.auction.v1alpha1.rs index 44d0d87f5b..07b4f355ab 100644 --- a/crates/proto/src/gen/penumbra.core.component.auction.v1alpha1.rs +++ b/crates/proto/src/gen/penumbra.core.component.auction.v1alpha1.rs @@ -275,6 +275,28 @@ impl ::prost::Name for ActionDutchAuctionScheduleView { ) } } +/// A plan to a `ActionDutchAuctionWithdraw` which contains both private and public data. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ActionDutchAuctionWithdrawPlan { + #[prost(message, optional, tag = "1")] + pub auction_id: ::core::option::Option, + #[prost(uint64, tag = "2")] + pub seq: u64, + #[prost(message, optional, tag = "3")] + pub reserves_input: ::core::option::Option, + #[prost(message, optional, tag = "4")] + pub reserves_output: ::core::option::Option, +} +impl ::prost::Name for ActionDutchAuctionWithdrawPlan { + const NAME: &'static str = "ActionDutchAuctionWithdrawPlan"; + const PACKAGE: &'static str = "penumbra.core.component.auction.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!( + "penumbra.core.component.auction.v1alpha1.{}", Self::NAME + ) + } +} /// Generated client implementations. #[cfg(feature = "rpc")] pub mod query_service_client { diff --git a/crates/proto/src/gen/penumbra.core.component.auction.v1alpha1.serde.rs b/crates/proto/src/gen/penumbra.core.component.auction.v1alpha1.serde.rs index 1b8516d301..ee693da763 100644 --- a/crates/proto/src/gen/penumbra.core.component.auction.v1alpha1.serde.rs +++ b/crates/proto/src/gen/penumbra.core.component.auction.v1alpha1.serde.rs @@ -472,6 +472,158 @@ impl<'de> serde::Deserialize<'de> for ActionDutchAuctionWithdraw { deserializer.deserialize_struct("penumbra.core.component.auction.v1alpha1.ActionDutchAuctionWithdraw", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for ActionDutchAuctionWithdrawPlan { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.auction_id.is_some() { + len += 1; + } + if self.seq != 0 { + len += 1; + } + if self.reserves_input.is_some() { + len += 1; + } + if self.reserves_output.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("penumbra.core.component.auction.v1alpha1.ActionDutchAuctionWithdrawPlan", len)?; + if let Some(v) = self.auction_id.as_ref() { + struct_ser.serialize_field("auctionId", v)?; + } + if self.seq != 0 { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("seq", ToString::to_string(&self.seq).as_str())?; + } + if let Some(v) = self.reserves_input.as_ref() { + struct_ser.serialize_field("reservesInput", v)?; + } + if let Some(v) = self.reserves_output.as_ref() { + struct_ser.serialize_field("reservesOutput", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for ActionDutchAuctionWithdrawPlan { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "auction_id", + "auctionId", + "seq", + "reserves_input", + "reservesInput", + "reserves_output", + "reservesOutput", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + AuctionId, + Seq, + ReservesInput, + ReservesOutput, + __SkipField__, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "auctionId" | "auction_id" => Ok(GeneratedField::AuctionId), + "seq" => Ok(GeneratedField::Seq), + "reservesInput" | "reserves_input" => Ok(GeneratedField::ReservesInput), + "reservesOutput" | "reserves_output" => Ok(GeneratedField::ReservesOutput), + _ => Ok(GeneratedField::__SkipField__), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = ActionDutchAuctionWithdrawPlan; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct penumbra.core.component.auction.v1alpha1.ActionDutchAuctionWithdrawPlan") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut auction_id__ = None; + let mut seq__ = None; + let mut reserves_input__ = None; + let mut reserves_output__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::AuctionId => { + if auction_id__.is_some() { + return Err(serde::de::Error::duplicate_field("auctionId")); + } + auction_id__ = map_.next_value()?; + } + GeneratedField::Seq => { + if seq__.is_some() { + return Err(serde::de::Error::duplicate_field("seq")); + } + seq__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::ReservesInput => { + if reserves_input__.is_some() { + return Err(serde::de::Error::duplicate_field("reservesInput")); + } + reserves_input__ = map_.next_value()?; + } + GeneratedField::ReservesOutput => { + if reserves_output__.is_some() { + return Err(serde::de::Error::duplicate_field("reservesOutput")); + } + reserves_output__ = map_.next_value()?; + } + GeneratedField::__SkipField__ => { + let _ = map_.next_value::()?; + } + } + } + Ok(ActionDutchAuctionWithdrawPlan { + auction_id: auction_id__, + seq: seq__.unwrap_or_default(), + reserves_input: reserves_input__, + reserves_output: reserves_output__, + }) + } + } + deserializer.deserialize_struct("penumbra.core.component.auction.v1alpha1.ActionDutchAuctionWithdrawPlan", FIELDS, GeneratedVisitor) + } +} impl serde::Serialize for ActionDutchAuctionWithdrawView { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result diff --git a/crates/proto/src/gen/penumbra.core.transaction.v1.rs b/crates/proto/src/gen/penumbra.core.transaction.v1.rs index d75557b65e..98b0852670 100644 --- a/crates/proto/src/gen/penumbra.core.transaction.v1.rs +++ b/crates/proto/src/gen/penumbra.core.transaction.v1.rs @@ -94,7 +94,7 @@ impl ::prost::Name for DetectionData { pub struct Action { #[prost( oneof = "action::Action", - tags = "1, 2, 3, 4, 16, 17, 18, 19, 20, 21, 22, 30, 31, 32, 34, 40, 41, 42, 50, 51, 52, 200" + tags = "1, 2, 3, 4, 16, 17, 18, 19, 20, 21, 22, 30, 31, 32, 34, 40, 41, 42, 50, 51, 52, 53, 54, 55, 200" )] pub action: ::core::option::Option, } @@ -164,6 +164,19 @@ pub mod action { CommunityPoolDeposit( super::super::super::component::governance::v1::CommunityPoolDeposit, ), + /// Dutch auctions + #[prost(message, tag = "53")] + ActionDutchAuctionSchedule( + super::super::super::component::auction::v1alpha1::ActionDutchAuctionSchedule, + ), + #[prost(message, tag = "54")] + ActionDutchAuctionEnd( + super::super::super::component::auction::v1alpha1::ActionDutchAuctionEnd, + ), + #[prost(message, tag = "55")] + ActionDutchAuctionWithdraw( + super::super::super::component::auction::v1alpha1::ActionDutchAuctionWithdraw, + ), #[prost(message, tag = "200")] Ics20Withdrawal(super::super::super::component::ibc::v1::Ics20Withdrawal), } @@ -387,7 +400,7 @@ impl ::prost::Name for TransactionBodyView { pub struct ActionView { #[prost( oneof = "action_view::ActionView", - tags = "1, 2, 3, 4, 16, 17, 18, 19, 20, 21, 22, 30, 31, 32, 34, 41, 42, 50, 51, 52, 43, 200" + tags = "1, 2, 3, 4, 16, 17, 18, 19, 20, 21, 22, 30, 31, 32, 34, 41, 42, 50, 51, 52, 53, 54, 55, 43, 200" )] pub action_view: ::core::option::Option, } @@ -454,6 +467,19 @@ pub mod action_view { CommunityPoolDeposit( super::super::super::component::governance::v1::CommunityPoolDeposit, ), + /// Dutch auctions + #[prost(message, tag = "53")] + ActionDutchAuctionSchedule( + super::super::super::component::auction::v1alpha1::ActionDutchAuctionSchedule, + ), + #[prost(message, tag = "54")] + ActionDutchAuctionEnd( + super::super::super::component::auction::v1alpha1::ActionDutchAuctionEnd, + ), + #[prost(message, tag = "55")] + ActionDutchAuctionWithdraw( + super::super::super::component::auction::v1alpha1::ActionDutchAuctionWithdraw, + ), /// TODO: we have no way to recover the opening of the undelegate_claim's /// balance commitment, and can only infer the value from looking at the rest /// of the transaction. is that fine? @@ -568,7 +594,7 @@ impl ::prost::Name for DetectionDataPlan { pub struct ActionPlan { #[prost( oneof = "action_plan::Action", - tags = "1, 2, 3, 4, 16, 17, 18, 19, 20, 21, 22, 200, 30, 31, 32, 34, 40, 41, 42, 50, 51, 52" + tags = "1, 2, 3, 4, 16, 17, 18, 19, 20, 21, 22, 200, 30, 31, 32, 34, 40, 41, 42, 50, 51, 52, 53, 54, 55" )] pub action: ::core::option::Option, } @@ -644,6 +670,19 @@ pub mod action_plan { CommunityPoolDeposit( super::super::super::component::governance::v1::CommunityPoolDeposit, ), + /// Dutch auctions + #[prost(message, tag = "53")] + ActionDutchAuctionSchedule( + super::super::super::component::auction::v1alpha1::ActionDutchAuctionSchedule, + ), + #[prost(message, tag = "54")] + ActionDutchAuctionEnd( + super::super::super::component::auction::v1alpha1::ActionDutchAuctionEnd, + ), + #[prost(message, tag = "55")] + ActionDutchAuctionWithdraw( + super::super::super::component::auction::v1alpha1::ActionDutchAuctionWithdrawPlan, + ), } } impl ::prost::Name for ActionPlan { diff --git a/crates/proto/src/gen/penumbra.core.transaction.v1.serde.rs b/crates/proto/src/gen/penumbra.core.transaction.v1.serde.rs index 82d4f0c729..c754bce6b3 100644 --- a/crates/proto/src/gen/penumbra.core.transaction.v1.serde.rs +++ b/crates/proto/src/gen/penumbra.core.transaction.v1.serde.rs @@ -75,6 +75,15 @@ impl serde::Serialize for Action { action::Action::CommunityPoolDeposit(v) => { struct_ser.serialize_field("communityPoolDeposit", v)?; } + action::Action::ActionDutchAuctionSchedule(v) => { + struct_ser.serialize_field("actionDutchAuctionSchedule", v)?; + } + action::Action::ActionDutchAuctionEnd(v) => { + struct_ser.serialize_field("actionDutchAuctionEnd", v)?; + } + action::Action::ActionDutchAuctionWithdraw(v) => { + struct_ser.serialize_field("actionDutchAuctionWithdraw", v)?; + } action::Action::Ics20Withdrawal(v) => { struct_ser.serialize_field("ics20Withdrawal", v)?; } @@ -127,6 +136,12 @@ impl<'de> serde::Deserialize<'de> for Action { "communityPoolOutput", "community_pool_deposit", "communityPoolDeposit", + "action_dutch_auction_schedule", + "actionDutchAuctionSchedule", + "action_dutch_auction_end", + "actionDutchAuctionEnd", + "action_dutch_auction_withdraw", + "actionDutchAuctionWithdraw", "ics20_withdrawal", "ics20Withdrawal", ]; @@ -154,6 +169,9 @@ impl<'de> serde::Deserialize<'de> for Action { CommunityPoolSpend, CommunityPoolOutput, CommunityPoolDeposit, + ActionDutchAuctionSchedule, + ActionDutchAuctionEnd, + ActionDutchAuctionWithdraw, Ics20Withdrawal, __SkipField__, } @@ -198,6 +216,9 @@ impl<'de> serde::Deserialize<'de> for Action { "communityPoolSpend" | "community_pool_spend" => Ok(GeneratedField::CommunityPoolSpend), "communityPoolOutput" | "community_pool_output" => Ok(GeneratedField::CommunityPoolOutput), "communityPoolDeposit" | "community_pool_deposit" => Ok(GeneratedField::CommunityPoolDeposit), + "actionDutchAuctionSchedule" | "action_dutch_auction_schedule" => Ok(GeneratedField::ActionDutchAuctionSchedule), + "actionDutchAuctionEnd" | "action_dutch_auction_end" => Ok(GeneratedField::ActionDutchAuctionEnd), + "actionDutchAuctionWithdraw" | "action_dutch_auction_withdraw" => Ok(GeneratedField::ActionDutchAuctionWithdraw), "ics20Withdrawal" | "ics20_withdrawal" => Ok(GeneratedField::Ics20Withdrawal), _ => Ok(GeneratedField::__SkipField__), } @@ -366,6 +387,27 @@ impl<'de> serde::Deserialize<'de> for Action { return Err(serde::de::Error::duplicate_field("communityPoolDeposit")); } action__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Action::CommunityPoolDeposit) +; + } + GeneratedField::ActionDutchAuctionSchedule => { + if action__.is_some() { + return Err(serde::de::Error::duplicate_field("actionDutchAuctionSchedule")); + } + action__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Action::ActionDutchAuctionSchedule) +; + } + GeneratedField::ActionDutchAuctionEnd => { + if action__.is_some() { + return Err(serde::de::Error::duplicate_field("actionDutchAuctionEnd")); + } + action__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Action::ActionDutchAuctionEnd) +; + } + GeneratedField::ActionDutchAuctionWithdraw => { + if action__.is_some() { + return Err(serde::de::Error::duplicate_field("actionDutchAuctionWithdraw")); + } + action__ = map_.next_value::<::std::option::Option<_>>()?.map(action::Action::ActionDutchAuctionWithdraw) ; } GeneratedField::Ics20Withdrawal => { @@ -468,6 +510,15 @@ impl serde::Serialize for ActionPlan { action_plan::Action::CommunityPoolDeposit(v) => { struct_ser.serialize_field("communityPoolDeposit", v)?; } + action_plan::Action::ActionDutchAuctionSchedule(v) => { + struct_ser.serialize_field("actionDutchAuctionSchedule", v)?; + } + action_plan::Action::ActionDutchAuctionEnd(v) => { + struct_ser.serialize_field("actionDutchAuctionEnd", v)?; + } + action_plan::Action::ActionDutchAuctionWithdraw(v) => { + struct_ser.serialize_field("actionDutchAuctionWithdraw", v)?; + } } } struct_ser.end() @@ -519,6 +570,12 @@ impl<'de> serde::Deserialize<'de> for ActionPlan { "communityPoolOutput", "community_pool_deposit", "communityPoolDeposit", + "action_dutch_auction_schedule", + "actionDutchAuctionSchedule", + "action_dutch_auction_end", + "actionDutchAuctionEnd", + "action_dutch_auction_withdraw", + "actionDutchAuctionWithdraw", ]; #[allow(clippy::enum_variant_names)] @@ -545,6 +602,9 @@ impl<'de> serde::Deserialize<'de> for ActionPlan { CommunityPoolSpend, CommunityPoolOutput, CommunityPoolDeposit, + ActionDutchAuctionSchedule, + ActionDutchAuctionEnd, + ActionDutchAuctionWithdraw, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -589,6 +649,9 @@ impl<'de> serde::Deserialize<'de> for ActionPlan { "communityPoolSpend" | "community_pool_spend" => Ok(GeneratedField::CommunityPoolSpend), "communityPoolOutput" | "community_pool_output" => Ok(GeneratedField::CommunityPoolOutput), "communityPoolDeposit" | "community_pool_deposit" => Ok(GeneratedField::CommunityPoolDeposit), + "actionDutchAuctionSchedule" | "action_dutch_auction_schedule" => Ok(GeneratedField::ActionDutchAuctionSchedule), + "actionDutchAuctionEnd" | "action_dutch_auction_end" => Ok(GeneratedField::ActionDutchAuctionEnd), + "actionDutchAuctionWithdraw" | "action_dutch_auction_withdraw" => Ok(GeneratedField::ActionDutchAuctionWithdraw), _ => Ok(GeneratedField::__SkipField__), } } @@ -763,6 +826,27 @@ impl<'de> serde::Deserialize<'de> for ActionPlan { return Err(serde::de::Error::duplicate_field("communityPoolDeposit")); } action__ = map_.next_value::<::std::option::Option<_>>()?.map(action_plan::Action::CommunityPoolDeposit) +; + } + GeneratedField::ActionDutchAuctionSchedule => { + if action__.is_some() { + return Err(serde::de::Error::duplicate_field("actionDutchAuctionSchedule")); + } + action__ = map_.next_value::<::std::option::Option<_>>()?.map(action_plan::Action::ActionDutchAuctionSchedule) +; + } + GeneratedField::ActionDutchAuctionEnd => { + if action__.is_some() { + return Err(serde::de::Error::duplicate_field("actionDutchAuctionEnd")); + } + action__ = map_.next_value::<::std::option::Option<_>>()?.map(action_plan::Action::ActionDutchAuctionEnd) +; + } + GeneratedField::ActionDutchAuctionWithdraw => { + if action__.is_some() { + return Err(serde::de::Error::duplicate_field("actionDutchAuctionWithdraw")); + } + action__ = map_.next_value::<::std::option::Option<_>>()?.map(action_plan::Action::ActionDutchAuctionWithdraw) ; } GeneratedField::__SkipField__ => { @@ -852,6 +936,15 @@ impl serde::Serialize for ActionView { action_view::ActionView::CommunityPoolDeposit(v) => { struct_ser.serialize_field("communityPoolDeposit", v)?; } + action_view::ActionView::ActionDutchAuctionSchedule(v) => { + struct_ser.serialize_field("actionDutchAuctionSchedule", v)?; + } + action_view::ActionView::ActionDutchAuctionEnd(v) => { + struct_ser.serialize_field("actionDutchAuctionEnd", v)?; + } + action_view::ActionView::ActionDutchAuctionWithdraw(v) => { + struct_ser.serialize_field("actionDutchAuctionWithdraw", v)?; + } action_view::ActionView::UndelegateClaim(v) => { struct_ser.serialize_field("undelegateClaim", v)?; } @@ -905,6 +998,12 @@ impl<'de> serde::Deserialize<'de> for ActionView { "communityPoolOutput", "community_pool_deposit", "communityPoolDeposit", + "action_dutch_auction_schedule", + "actionDutchAuctionSchedule", + "action_dutch_auction_end", + "actionDutchAuctionEnd", + "action_dutch_auction_withdraw", + "actionDutchAuctionWithdraw", "undelegate_claim", "undelegateClaim", "ics20_withdrawal", @@ -933,6 +1032,9 @@ impl<'de> serde::Deserialize<'de> for ActionView { CommunityPoolSpend, CommunityPoolOutput, CommunityPoolDeposit, + ActionDutchAuctionSchedule, + ActionDutchAuctionEnd, + ActionDutchAuctionWithdraw, UndelegateClaim, Ics20Withdrawal, __SkipField__, @@ -977,6 +1079,9 @@ impl<'de> serde::Deserialize<'de> for ActionView { "communityPoolSpend" | "community_pool_spend" => Ok(GeneratedField::CommunityPoolSpend), "communityPoolOutput" | "community_pool_output" => Ok(GeneratedField::CommunityPoolOutput), "communityPoolDeposit" | "community_pool_deposit" => Ok(GeneratedField::CommunityPoolDeposit), + "actionDutchAuctionSchedule" | "action_dutch_auction_schedule" => Ok(GeneratedField::ActionDutchAuctionSchedule), + "actionDutchAuctionEnd" | "action_dutch_auction_end" => Ok(GeneratedField::ActionDutchAuctionEnd), + "actionDutchAuctionWithdraw" | "action_dutch_auction_withdraw" => Ok(GeneratedField::ActionDutchAuctionWithdraw), "undelegateClaim" | "undelegate_claim" => Ok(GeneratedField::UndelegateClaim), "ics20Withdrawal" | "ics20_withdrawal" => Ok(GeneratedField::Ics20Withdrawal), _ => Ok(GeneratedField::__SkipField__), @@ -1139,6 +1244,27 @@ impl<'de> serde::Deserialize<'de> for ActionView { return Err(serde::de::Error::duplicate_field("communityPoolDeposit")); } action_view__ = map_.next_value::<::std::option::Option<_>>()?.map(action_view::ActionView::CommunityPoolDeposit) +; + } + GeneratedField::ActionDutchAuctionSchedule => { + if action_view__.is_some() { + return Err(serde::de::Error::duplicate_field("actionDutchAuctionSchedule")); + } + action_view__ = map_.next_value::<::std::option::Option<_>>()?.map(action_view::ActionView::ActionDutchAuctionSchedule) +; + } + GeneratedField::ActionDutchAuctionEnd => { + if action_view__.is_some() { + return Err(serde::de::Error::duplicate_field("actionDutchAuctionEnd")); + } + action_view__ = map_.next_value::<::std::option::Option<_>>()?.map(action_view::ActionView::ActionDutchAuctionEnd) +; + } + GeneratedField::ActionDutchAuctionWithdraw => { + if action_view__.is_some() { + return Err(serde::de::Error::duplicate_field("actionDutchAuctionWithdraw")); + } + action_view__ = map_.next_value::<::std::option::Option<_>>()?.map(action_view::ActionView::ActionDutchAuctionWithdraw) ; } GeneratedField::UndelegateClaim => { diff --git a/crates/proto/src/gen/proto_descriptor.bin.no_lfs b/crates/proto/src/gen/proto_descriptor.bin.no_lfs index db36c4744d..e2f91d75e6 100644 Binary files a/crates/proto/src/gen/proto_descriptor.bin.no_lfs and b/crates/proto/src/gen/proto_descriptor.bin.no_lfs differ diff --git a/proto/penumbra/penumbra/core/component/auction/v1alpha1/auction.proto b/proto/penumbra/penumbra/core/component/auction/v1alpha1/auction.proto index 809c5b51cf..ee6507f3ef 100644 --- a/proto/penumbra/penumbra/core/component/auction/v1alpha1/auction.proto +++ b/proto/penumbra/penumbra/core/component/auction/v1alpha1/auction.proto @@ -103,30 +103,38 @@ message ActionDutchAuctionEnd { // Withdraw funds from the ended auction associated with the specified `auction_id` message ActionDutchAuctionWithdraw { - // The auction to withdraw funds from. - AuctionId auction_id = 1; - // The sequence number of the withdrawal. - uint64 seq = 2; - // A transparent (zero blinding factor) commitment to the - // auction's final reserves. - // - // The chain will check this commitment by recomputing it - // with the on-chain state. - asset.v1.BalanceCommitment reserves_commitment = 3; + // The auction to withdraw funds from. + AuctionId auction_id = 1; + // The sequence number of the withdrawal. + uint64 seq = 2; + // A transparent (zero blinding factor) commitment to the + // auction's final reserves. + // + // The chain will check this commitment by recomputing it + // with the on-chain state. + asset.v1.BalanceCommitment reserves_commitment = 3; } // An `ActionDutchAuctionWithdraw` augmented with additional metadata. message ActionDutchAuctionWithdrawView { - ActionDutchAuctionWithdraw action = 1; - // A sequence of values that sum together to the provided - // reserves commitment. - repeated asset.v1.ValueView reserves = 2; + ActionDutchAuctionWithdraw action = 1; + // A sequence of values that sum together to the provided + // reserves commitment. + repeated asset.v1.ValueView reserves = 2; } // An `ActionDutchAuctionSchedule` augmented with additional metadata. message ActionDutchAuctionScheduleView { - ActionDutchAuctionSchedule action = 1; - AuctionId auction_id = 2; - asset.v1.Metadata input_metadata = 3; - asset.v1.Metadata output_metadata = 4; + ActionDutchAuctionSchedule action = 1; + AuctionId auction_id = 2; + asset.v1.Metadata input_metadata = 3; + asset.v1.Metadata output_metadata = 4; +} + +// A plan to a `ActionDutchAuctionWithdraw` which contains both private and public data. +message ActionDutchAuctionWithdrawPlan { + AuctionId auction_id = 1; + uint64 seq = 2; + asset.v1.Value reserves_input = 3; + asset.v1.Value reserves_output = 4; } diff --git a/proto/penumbra/penumbra/core/transaction/v1/transaction.proto b/proto/penumbra/penumbra/core/transaction/v1/transaction.proto index c033bf0e67..bc4ee0e20a 100644 --- a/proto/penumbra/penumbra/core/transaction/v1/transaction.proto +++ b/proto/penumbra/penumbra/core/transaction/v1/transaction.proto @@ -3,6 +3,7 @@ package penumbra.core.transaction.v1; import "google/protobuf/any.proto"; import "penumbra/core/asset/v1/asset.proto"; +import "penumbra/core/component/auction/v1alpha1/auction.proto"; import "penumbra/core/component/dex/v1/dex.proto"; import "penumbra/core/component/fee/v1/fee.proto"; import "penumbra/core/component/governance/v1/governance.proto"; @@ -96,6 +97,11 @@ message Action { component.governance.v1.CommunityPoolOutput community_pool_output = 51; component.governance.v1.CommunityPoolDeposit community_pool_deposit = 52; + // Dutch auctions + component.auction.v1alpha1.ActionDutchAuctionSchedule action_dutch_auction_schedule = 53; + component.auction.v1alpha1.ActionDutchAuctionEnd action_dutch_auction_end = 54; + component.auction.v1alpha1.ActionDutchAuctionWithdraw action_dutch_auction_withdraw = 55; + component.ibc.v1.Ics20Withdrawal ics20_withdrawal = 200; } } @@ -216,6 +222,10 @@ message ActionView { component.governance.v1.CommunityPoolSpend community_pool_spend = 50; component.governance.v1.CommunityPoolOutput community_pool_output = 51; component.governance.v1.CommunityPoolDeposit community_pool_deposit = 52; + // Dutch auctions + component.auction.v1alpha1.ActionDutchAuctionSchedule action_dutch_auction_schedule = 53; + component.auction.v1alpha1.ActionDutchAuctionEnd action_dutch_auction_end = 54; + component.auction.v1alpha1.ActionDutchAuctionWithdraw action_dutch_auction_withdraw = 55; // TODO: we have no way to recover the opening of the undelegate_claim's // balance commitment, and can only infer the value from looking at the rest @@ -309,6 +319,11 @@ message ActionPlan { component.governance.v1.CommunityPoolSpend community_pool_spend = 50; component.governance.v1.CommunityPoolOutput community_pool_output = 51; component.governance.v1.CommunityPoolDeposit community_pool_deposit = 52; + + // Dutch auctions + component.auction.v1alpha1.ActionDutchAuctionSchedule action_dutch_auction_schedule = 53; + component.auction.v1alpha1.ActionDutchAuctionEnd action_dutch_auction_end = 54; + component.auction.v1alpha1.ActionDutchAuctionWithdrawPlan action_dutch_auction_withdraw = 55; } }