Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Planner refactor debug (do not merge) #4276

Closed
wants to merge 41 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
0f2e375
simplify rust planner
TalDerei Apr 1, 2024
58f196c
add memo field for outputs
TalDerei Apr 1, 2024
f88a7c1
don't double count spendable notes
TalDerei Apr 2, 2024
c27c67e
fold back in voting functionality
TalDerei Apr 2, 2024
2d23776
clippy
TalDerei Apr 2, 2024
8825694
logging galore
TalDerei Apr 2, 2024
e14a6c1
extraneous outputs causing binding signature verification failures
TalDerei Apr 2, 2024
452d960
add delegator vote to planner
TalDerei Apr 2, 2024
8662b02
properly handle memos
TalDerei Apr 2, 2024
4aafaf0
Merge branch 'main' into planner-refactor
TalDerei Apr 2, 2024
dcc36f7
add fee recalculations in the presence of non-zero fees
TalDerei Apr 4, 2024
200f753
add non-zero fee test
TalDerei Apr 4, 2024
f2c4a70
minor doc change
TalDerei Apr 4, 2024
736568e
filter and sort by largest notes
TalDerei Apr 5, 2024
55b9814
reduce code duplication
TalDerei Apr 14, 2024
15f3cdc
add unit test and expand comments
TalDerei Apr 14, 2024
7eed426
fmt and clippy
TalDerei Apr 14, 2024
2263397
Merge branch 'main' into planner-refactor-debug
TalDerei Apr 26, 2024
76c01eb
try 0 fees
TalDerei Apr 26, 2024
54fcfb2
don't perform fee overestimation for swapclaims
TalDerei Apr 26, 2024
f99390c
add back gas fees
TalDerei Apr 26, 2024
e65c037
partial gas fees
TalDerei Apr 26, 2024
620752b
updated planner and tracing
TalDerei Apr 26, 2024
3ca964e
back to zero fees
TalDerei Apr 26, 2024
698aad5
frankensteins monster
TalDerei Apr 28, 2024
5949f76
frankensteins monster 2
TalDerei Apr 28, 2024
ac92875
remove auction to compile
TalDerei Apr 28, 2024
6fb9de5
merge
TalDerei Apr 28, 2024
f2c5037
fix random to compile doesn't matter
TalDerei Apr 28, 2024
66f1d90
add back fees
TalDerei Apr 28, 2024
a73f847
curious
TalDerei Apr 28, 2024
3cb38d7
another test
TalDerei Apr 28, 2024
7d10bff
modified original planner
TalDerei Apr 29, 2024
f518b08
frankenstein is not happy
TalDerei Apr 29, 2024
52649be
we're in a special place
TalDerei Apr 29, 2024
27fc911
I only venture here
TalDerei Apr 29, 2024
4ddd17a
way closer, just need to clean up
TalDerei Apr 30, 2024
20e2ae1
test
TalDerei Apr 30, 2024
7b9702d
Merge branch 'main' into planner-refactor-debug
TalDerei Apr 30, 2024
d05aeb9
remove errors
TalDerei Apr 30, 2024
149d441
test
TalDerei Apr 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
231 changes: 231 additions & 0 deletions crates/bin/pcli/src/command/auction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
use super::tx::FeeTier;
use crate::App;
use anyhow::Context;
use clap::Subcommand;
use penumbra_asset::{asset, Value};
use penumbra_auction::auction::AuctionId;
use penumbra_keys::keys::AddressIndex;
use penumbra_num::Amount;
use penumbra_proto::view::v1::GasPricesRequest;
use penumbra_wallet::plan::Planner;
use rand_core::OsRng;

#[derive(Debug, Subcommand)]
pub enum AuctionCmd {
/// Commands related to Dutch auctions
#[clap(display_order = 100, subcommand)]
Dutch(DutchCmd),
}

/// Commands related to Dutch auctions
#[derive(Debug, Subcommand)]
pub enum DutchCmd {
/// Schedule a Dutch auction, a tool to help accomplish price discovery.
#[clap(display_order = 100, name = "schedule")]
DutchAuctionSchedule {
/// Source address initiating the auction.
#[clap(long, display_order = 100)]
source: u32,
/// The value the seller wishes to auction.
#[clap(long, display_order = 200)]
input: String,
/// The asset ID of the target asset the seller wishes to acquire.
#[clap(long, display_order = 300)]
output: String,
/// The maximum output the seller can receive.
///
/// This implicitly defines the starting price for the auction.
#[clap(long, display_order = 400)]
max_output: u64,
/// The minimum output the seller is willing to receive.
///
/// This implicitly defines the ending price for the auction.
#[clap(long, display_order = 500)]
min_output: u64,
/// The block height at which the auction begins.
///
/// This allows the seller to schedule an auction at a future time.
#[clap(long, display_order = 600)]
start_height: u64,
/// The block height at which the auction ends.
///
/// Together with `start_height`, `max_output`, and `min_output`,
/// this implicitly defines the speed of the auction.
#[clap(long, display_order = 700)]
end_height: u64,
/// The number of discrete price steps to use for the auction.
///
/// `end_height - start_height` must be a multiple of `step_count`.
#[clap(long, display_order = 800)]
step_count: u64,
/// A random nonce used to allow identical auctions to have
/// distinct auction IDs.
#[clap(long, display_order = 900)]
nonce: u64,
/// The selected fee tier to multiply the fee amount by.
#[clap(short, long, value_enum, default_value_t, display_order = 1000)]
fee_tier: FeeTier,
},
/// Withdraws the reserves of the Dutch auction.
#[clap(display_order = 200, name = "withdraw")]
DutchAuctionWithdraw {
/// Source address withdrawing from the auction.
#[clap(long, display_order = 100)]
source: u32,
/// The auction to withdraw funds from.
#[clap(long, display_order = 200)]
auction_id: String,
/// The sequence number of the withdrawal.
#[clap(long, display_order = 300)]
seq: u64,
/// The amount of the input asset directly owned by the auction.
///
/// The auction may also own the input asset indirectly,
/// via the reserves of `current_position` if it exists.
#[clap(long, display_order = 400)]
reserves_input: String,
/// The amount of the output asset directly owned by the auction.
///
/// The auction may also own the output asset indirectly,
/// via the reserves of `current_position` if it exists.
#[clap(long, display_order = 500)]
reserves_output: String,
/// The selected fee tier to multiply the fee amount by.
#[clap(short, long, value_enum, default_value_t, display_order = 600)]
fee_tier: FeeTier,
},
/// Ends a Dutch auction.
#[clap(display_order = 300, name = "end")]
DutchAuctionEnd {
/// Source address withdrawing from auction.
#[clap(long, display_order = 100)]
source: u32,
/// Identifier of the auction.
#[clap(long, display_order = 200)]
auction_id: String,
/// The selected fee tier to multiply the fee amount by.
#[clap(short, long, value_enum, default_value_t, display_order = 300)]
fee_tier: FeeTier,
},
}

impl DutchCmd {
/// Process the command by performing the appropriate action.
pub async fn exec(&self, app: &mut App) -> anyhow::Result<()> {
let gas_prices = app
.view
.as_mut()
.context("view service must be initialized")?
.gas_prices(GasPricesRequest {})
.await?
.into_inner()
.gas_prices
.expect("gas prices must be available")
.try_into()?;

match self {
DutchCmd::DutchAuctionSchedule {
source,
input,
output,
max_output,
min_output,
start_height,
end_height,
step_count,
nonce: _,
fee_tier,
} => {
let input = input.parse::<Value>()?;
let output = output.parse::<asset::Id>()?;
let max_output = Amount::from(*max_output);
let min_output = Amount::from(*min_output);

let mut planner = Planner::new(OsRng);
planner
.set_gas_prices(gas_prices)
.set_fee_tier((*fee_tier).into());

planner.dutch_auction_schedule(
input,
output,
max_output,
min_output,
*start_height,
*end_height,
*step_count,
[0; 32],
);

let plan = planner
.plan(
app.view
.as_mut()
.context("view service must be initialized")?,
AddressIndex::new(*source),
)
.await
.context("can't build send transaction")?;
app.build_and_submit_transaction(plan).await?;
Ok(())
}
DutchCmd::DutchAuctionWithdraw {
source,
auction_id,
seq,
reserves_input,
reserves_output,
fee_tier,
} => {
let auction_id = auction_id.parse::<AuctionId>()?;
let reserves_input = reserves_input.parse::<Value>()?;
let reserves_output = reserves_output.parse::<Value>()?;

let mut planner = Planner::new(OsRng);
planner
.set_gas_prices(gas_prices)
.set_fee_tier((*fee_tier).into());

planner.dutch_auction_withdraw(auction_id, *seq, reserves_input, reserves_output);

let plan = planner
.plan(
app.view
.as_mut()
.context("view service must be initialized")?,
AddressIndex::new(*source),
)
.await
.context("can't build send transaction")?;
app.build_and_submit_transaction(plan).await?;
Ok(())
}
DutchCmd::DutchAuctionEnd {
auction_id,
source,
fee_tier,
} => {
let auction_id = auction_id.parse::<AuctionId>()?;

let mut planner = Planner::new(OsRng);
planner
.set_gas_prices(gas_prices)
.set_fee_tier((*fee_tier).into());

planner.dutch_auction_end(auction_id);

let plan = planner
.plan(
app.view
.as_mut()
.context("view service must be initialized")?,
AddressIndex::new(*source),
)
.await
.context("can't build send transaction")?;
app.build_and_submit_transaction(plan).await?;
Ok(())
}
}
}
}
120 changes: 6 additions & 114 deletions crates/bin/pcli/src/command/tx/auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use clap::Subcommand;
use penumbra_asset::Value;
use penumbra_auction::auction::{dutch::DutchAuction, AuctionId};
use penumbra_dex::lp::position::Position;
use penumbra_fee::state_key::gas_prices;
use penumbra_keys::keys::AddressIndex;
use penumbra_proto::{view::v1::GasPricesRequest, DomainType, Name};
use penumbra_view::SpendableNoteRecord;
Expand Down Expand Up @@ -107,16 +108,6 @@ pub enum DutchCmd {
impl DutchCmd {
/// Process the command by performing the appropriate action.
pub async fn exec(&self, app: &mut App) -> anyhow::Result<()> {
let gas_prices = app
.view
.as_mut()
.context("view service must be initialized")?
.gas_prices(GasPricesRequest {})
.await?
.into_inner()
.gas_prices
.expect("gas prices must be available")
.try_into()?;

match self {
DutchCmd::DutchAuctionSchedule {
Expand All @@ -129,120 +120,21 @@ impl DutchCmd {
step_count,
fee_tier,
} => {
let mut nonce = [0u8; 32];
OsRng.fill_bytes(&mut nonce);

let input = input.parse::<Value>()?;
let max_output = max_output.parse::<Value>()?;
let min_output = min_output.parse::<Value>()?;
let output_id = max_output.asset_id;

let plan = Planner::new(OsRng)
.set_gas_prices(gas_prices)
.set_fee_tier((*fee_tier).into())
.dutch_auction_schedule(
input,
output_id,
max_output.amount,
min_output.amount,
*start_height,
*end_height,
*step_count,
nonce,
)
.plan(
app.view
.as_mut()
.context("view service must be initialized")?,
AddressIndex::new(*source),
)
.await
.context("can't build send transaction")?;
app.build_and_submit_transaction(plan).await?;
// let input = input.parse::<Value>()?;
Ok(())
}
DutchCmd::DutchAuctionEnd {
auction_id,
DutchCmd::DutchAuctionWithdraw {
source,
auction_id,
fee_tier,
} => {
let auction_id = auction_id.parse::<AuctionId>()?;

let plan = Planner::new(OsRng)
.set_gas_prices(gas_prices)
.set_fee_tier((*fee_tier).into())
.dutch_auction_end(auction_id)
.plan(
app.view
.as_mut()
.context("view service must be initialized")?,
AddressIndex::new(*source),
)
.await
.context("can't build send transaction")?;
app.build_and_submit_transaction(plan).await?;
Ok(())
}
DutchCmd::DutchAuctionWithdraw {
source,
DutchCmd::DutchAuctionEnd {
auction_id,
// seq,
// reserves_input,
// reserves_output,
source,
fee_tier,
} => {
let auction_id = auction_id.parse::<AuctionId>()?;

use pbjson_types::Any;
use penumbra_view::ViewClient;
let view_client = app.view();
let (auction_id, _, auction_raw, _): (
AuctionId,
SpendableNoteRecord,
Option<Any>,
Vec<Position>,
) = view_client
.auctions(None, true, true)
.await?
.into_iter()
.find(|(id, _, _, _)| &auction_id == id)
.ok_or_else(|| anyhow!("the auction id is unknown from the view service!"))?;

let Some(raw_da_state) = auction_raw else {
bail!("auction state is missing from view server response")
};

use penumbra_proto::core::component::auction::v1alpha1 as pb_auction;
// We're processing a Dutch auction:
assert_eq!(raw_da_state.type_url, pb_auction::DutchAuction::type_url());

let dutch_auction = DutchAuction::decode(raw_da_state.value)?;

let reserves_input = Value {
amount: dutch_auction.state.input_reserves,
asset_id: dutch_auction.description.input.asset_id,
};
let reserves_output = Value {
amount: dutch_auction.state.output_reserves,
asset_id: dutch_auction.description.output_id,
};
let seq = dutch_auction.state.sequence + 1;

let mut planner = Planner::new(OsRng);

let plan = planner
.set_gas_prices(gas_prices)
.set_fee_tier((*fee_tier).into())
.dutch_auction_withdraw(auction_id, seq, reserves_input, reserves_output)
.plan(
app.view
.as_mut()
.context("view service must be initialized")?,
AddressIndex::new(*source),
)
.await
.context("can't build send transaction")?;
app.build_and_submit_transaction(plan).await?;
Ok(())
}
}
Expand Down
Loading
Loading