Skip to content

Commit

Permalink
Make swap_claim check the exact epoch and block in circuit
Browse files Browse the repository at this point in the history
  • Loading branch information
cronokirby committed Apr 19, 2024
1 parent b0c8cc4 commit 0571414
Show file tree
Hide file tree
Showing 34 changed files with 144 additions and 88 deletions.
1 change: 1 addition & 0 deletions crates/bench/benches/swap_claim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ fn swap_claim_proving_time(c: &mut Criterion) {
height: height.into(),
trading_pair: swap_plaintext.trading_pair,
epoch_starting_height: (epoch_duration * position.epoch()).into(),
sct_position_prefix: position,
};
let (lambda_1, lambda_2) = output_data.pro_rata_outputs((delta_1_i, delta_2_i));

Expand Down
1 change: 1 addition & 0 deletions crates/bin/pcli/tests/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ fn swap_claim_parameters_vs_current_swap_claim_circuit() {
height: height.into(),
trading_pair: swap_plaintext.trading_pair,
epoch_starting_height: (epoch_duration * position.epoch()).into(),
sct_position_prefix: position,
};
let (lambda_1, lambda_2) = output_data.pro_rata_outputs((delta_1_i, delta_2_i));

Expand Down
47 changes: 25 additions & 22 deletions crates/core/component/dex/src/batch_swap_output_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ use ark_r1cs_std::{
select::CondSelectGadget,
};
use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError};
use decaf377::{r1cs::FqVar, Fq};
use decaf377::Fq;
use penumbra_proto::{penumbra::core::component::dex::v1 as pb, DomainType};
use penumbra_tct::{r1cs::PositionVar, Position};
use serde::{Deserialize, Serialize};

use penumbra_num::fixpoint::{bit_constrain, U128x128, U128x128Var};
use penumbra_num::fixpoint::{U128x128, U128x128Var};
use penumbra_num::{Amount, AmountVar};

use crate::TradingPairVar;
Expand Down Expand Up @@ -38,6 +39,8 @@ pub struct BatchSwapOutputData {
pub trading_pair: TradingPair,
/// The starting block height of the epoch for which the batch swap data is valid.
pub epoch_starting_height: u64,
/// The position prefix where this batch swap occurred. The commitment index must be 0.
pub sct_position_prefix: Position,
}

impl BatchSwapOutputData {
Expand Down Expand Up @@ -116,20 +119,15 @@ impl ToConstraintField<Fq> for BatchSwapOutputData {
.to_field_elements()
.expect("U128x128 types are Bls12-377 field members"),
);
public_inputs.extend(
Fq::from(self.height)
.to_field_elements()
.expect("Fq types are Bls12-377 field members"),
);
public_inputs.extend(
self.trading_pair
.to_field_elements()
.expect("trading_pair is a Bls12-377 field member"),
);
public_inputs.extend(
Fq::from(self.epoch_starting_height)
self.sct_position_prefix
.to_field_elements()
.expect("Fq types are Bls12-377 field members"),
.expect("Position types are Bls12-377 field members"),
);
Some(public_inputs)
}
Expand All @@ -142,9 +140,8 @@ pub struct BatchSwapOutputDataVar {
pub lambda_2: U128x128Var,
pub unfilled_1: U128x128Var,
pub unfilled_2: U128x128Var,
pub height: FqVar,
pub trading_pair: TradingPairVar,
pub epoch_starting_height: FqVar,
pub sct_position_prefix: PositionVar,
}

impl AllocVar<BatchSwapOutputData, Fq> for BatchSwapOutputDataVar {
Expand All @@ -168,18 +165,13 @@ impl AllocVar<BatchSwapOutputData, Fq> for BatchSwapOutputDataVar {
let unfilled_1 = U128x128Var::new_variable(cs.clone(), || Ok(unfilled_1_fixpoint), mode)?;
let unfilled_2_fixpoint: U128x128 = output_data.unfilled_2.into();
let unfilled_2 = U128x128Var::new_variable(cs.clone(), || Ok(unfilled_2_fixpoint), mode)?;
let height = FqVar::new_variable(cs.clone(), || Ok(Fq::from(output_data.height)), mode)?;
// Check the height is 64 bits
let _ = bit_constrain(height.clone(), 64);
let trading_pair = TradingPairVar::new_variable_unchecked(
cs.clone(),
|| Ok(output_data.trading_pair),
mode,
)?;
let epoch_starting_height =
FqVar::new_variable(cs, || Ok(Fq::from(output_data.epoch_starting_height)), mode)?;
// Check the epoch starting height is 64 bits
let _ = bit_constrain(epoch_starting_height.clone(), 64);
let sct_position_prefix =
PositionVar::new_variable(cs.clone(), || Ok(output_data.sct_position_prefix), mode)?;

Ok(Self {
delta_1,
Expand All @@ -189,8 +181,7 @@ impl AllocVar<BatchSwapOutputData, Fq> for BatchSwapOutputDataVar {
unfilled_1,
unfilled_2,
trading_pair,
height,
epoch_starting_height,
sct_position_prefix,
})
}
}
Expand All @@ -211,6 +202,7 @@ impl From<BatchSwapOutputData> for pb::BatchSwapOutputData {
height: s.height,
epoch_starting_height: s.epoch_starting_height,
trading_pair: Some(s.trading_pair.into()),
sct_position_prefix: s.sct_position_prefix.into(),
}
}
}
Expand Down Expand Up @@ -276,6 +268,14 @@ impl From<BatchSwapOutputData> for pb::BatchSwapOutputDataResponse {
impl TryFrom<pb::BatchSwapOutputData> for BatchSwapOutputData {
type Error = anyhow::Error;
fn try_from(s: pb::BatchSwapOutputData) -> Result<Self, Self::Error> {
let sct_position_prefix = {
let prefix = Position::from(s.sct_position_prefix);
anyhow::ensure!(
prefix.commitment() == 0,
"sct_position_prefix.commitment() != 0"
);
prefix
};
Ok(Self {
delta_1: s
.delta_1
Expand Down Expand Up @@ -307,6 +307,7 @@ impl TryFrom<pb::BatchSwapOutputData> for BatchSwapOutputData {
.ok_or_else(|| anyhow!("Missing trading_pair"))?
.try_into()?,
epoch_starting_height: s.epoch_starting_height,
sct_position_prefix,
})
}
}
Expand Down Expand Up @@ -421,9 +422,10 @@ mod tests {
lambda_2: Amount::from(1u32),
unfilled_1: Amount::from(1u32),
unfilled_2: Amount::from(1u32),
height: 1,
height: 0,
trading_pair,
epoch_starting_height: 1,
epoch_starting_height: 0,
sct_position_prefix: 0u64.into(),
},
}
}
Expand All @@ -445,6 +447,7 @@ mod tests {
height: 0u64,
trading_pair,
epoch_starting_height: 0u64,
sct_position_prefix: 0u64.into(),
};

// Now suppose our user's contribution is:
Expand Down
12 changes: 11 additions & 1 deletion crates/core/component/dex/src/component/circuit_breaker/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ mod tests {
height: 1,
trading_pair: pair_1.into_directed_trading_pair().into(),
epoch_starting_height: 0,
sct_position_prefix: Default::default(),
},
None,
None,
Expand Down Expand Up @@ -252,7 +253,16 @@ mod tests {
let routing_params = state.routing_params().await.unwrap();
// This call should panic due to the outflow of gn not being covered by the circuit breaker.
state
.handle_batch_swaps(trading_pair, swap_flow, 0, 0, routing_params)
.handle_batch_swaps(
trading_pair,
swap_flow,
0,
Epoch {
index: 0,
start_height: 0,
},
routing_params,
)
.await
.expect("unable to process batch swaps");
}
Expand Down
2 changes: 1 addition & 1 deletion crates/core/component/dex/src/component/dex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl Component for Dex {
.height
.try_into()
.expect("height is part of the end block data"),
current_epoch.start_height,
current_epoch,
// Always include both ends of the target pair as fixed candidates.
routing_params
.clone()
Expand Down
21 changes: 11 additions & 10 deletions crates/core/component/dex/src/component/router/route_and_fill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use async_trait::async_trait;
use cnidarium::StateWrite;
use penumbra_asset::{asset, Value};
use penumbra_num::Amount;
use penumbra_sct::epoch::Epoch;
use tracing::instrument;

use crate::{
Expand All @@ -23,21 +24,14 @@ use super::fill_route::FillError;
/// a block's batch swap flows.
#[async_trait]
pub trait HandleBatchSwaps: StateWrite + Sized {
#[instrument(skip(
self,
trading_pair,
batch_data,
block_height,
epoch_starting_height,
params
))]
#[instrument(skip(self, trading_pair, batch_data, block_height, epoch, params))]
async fn handle_batch_swaps(
self: &mut Arc<Self>,
trading_pair: TradingPair,
batch_data: SwapFlow,
// TODO: why not read these 2 from the state?
block_height: u64,
epoch_starting_height: u64,
epoch: Epoch,
params: RoutingParams,
) -> Result<()>
where
Expand Down Expand Up @@ -97,14 +91,21 @@ pub trait HandleBatchSwaps: StateWrite + Sized {
};
let output_data = BatchSwapOutputData {
height: block_height,
epoch_starting_height,
epoch_starting_height: epoch.start_height,
trading_pair,
delta_1,
delta_2,
lambda_1,
lambda_2,
unfilled_1,
unfilled_2,
sct_position_prefix: (
u16::try_from(epoch.index).expect("epoch index should be small enough"),
u16::try_from(block_height - epoch.start_height)
.expect("block index should be small enough"),
0,
)
.into(),
};

// Fetch the swap execution object that should have been modified during the routing and filling.
Expand Down
23 changes: 21 additions & 2 deletions crates/core/component/dex/src/component/router/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use core::panic;
use futures::StreamExt;
use penumbra_asset::{asset, Value};
use penumbra_num::{fixpoint::U128x128, Amount};
use penumbra_sct::epoch::Epoch;
use rand_core::OsRng;
use std::sync::Arc;

Expand Down Expand Up @@ -1024,7 +1025,16 @@ async fn best_position_route_and_fill() -> anyhow::Result<()> {
.unwrap();
let routing_params = state.routing_params().await.unwrap();
state
.handle_batch_swaps(trading_pair, swap_flow, 0u32.into(), 0, routing_params)
.handle_batch_swaps(
trading_pair,
swap_flow,
0u32.into(),
Epoch {
index: 0,
start_height: 0,
},
routing_params,
)
.await
.expect("unable to process batch swaps");

Expand Down Expand Up @@ -1165,7 +1175,16 @@ async fn multi_hop_route_and_fill() -> anyhow::Result<()> {
.unwrap();
let routing_params = state.routing_params().await.unwrap();
state
.handle_batch_swaps(trading_pair, swap_flow, 0u32.into(), 0, routing_params)
.handle_batch_swaps(
trading_pair,
swap_flow,
0u32.into(),
Epoch {
index: 0,
start_height: 0,
},
routing_params,
)
.await
.expect("unable to process batch swaps");

Expand Down
24 changes: 22 additions & 2 deletions crates/core/component/dex/src/component/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use cnidarium::{ArcStateDeltaExt, StateDelta, TempStorage};
use futures::StreamExt;
use penumbra_asset::{asset, Value};
use penumbra_num::Amount;
use penumbra_sct::epoch::Epoch;
use rand_core::OsRng;

use crate::lp::action::PositionOpen;
Expand Down Expand Up @@ -632,7 +633,16 @@ async fn swap_execution_tests() -> anyhow::Result<()> {
.unwrap();
let routing_params = state.routing_params().await.unwrap();
state
.handle_batch_swaps(trading_pair, swap_flow, 0, 0, routing_params)
.handle_batch_swaps(
trading_pair,
swap_flow,
0,
Epoch {
index: 0,
start_height: 0,
},
routing_params,
)
.await
.expect("unable to process batch swaps");

Expand Down Expand Up @@ -740,7 +750,16 @@ async fn swap_execution_tests() -> anyhow::Result<()> {
.unwrap();
let routing_params = state.routing_params().await.unwrap();
state
.handle_batch_swaps(trading_pair, swap_flow, 0u32.into(), 0, routing_params)
.handle_batch_swaps(
trading_pair,
swap_flow,
0u32.into(),
Epoch {
index: 0,
start_height: 0,
},
routing_params,
)
.await
.expect("unable to process batch swaps");

Expand All @@ -758,6 +777,7 @@ async fn swap_execution_tests() -> anyhow::Result<()> {
height: 0,
epoch_starting_height: 0,
trading_pair,
sct_position_prefix: Default::default(),
}
);

Expand Down
Loading

0 comments on commit 0571414

Please sign in to comment.