-
Notifications
You must be signed in to change notification settings - Fork 305
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
Correct swap claim height check #4239
Conversation
Not quite sure why the tests aren't passing, will pick back up tomorrow morning. |
These changes should be based on |
crates/core/component/dex/src/component/router/route_and_fill.rs
Outdated
Show resolved
Hide resolved
pub epoch: FqVar, | ||
pub block: FqVar, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the rationale behind making these an FqVar
rather than an alternate representation?
Also, could we give them different names to clarify that they're not standalone values, but components of a Position
? Like
pub position_epoch_component: FqVar,
pub position_block_component: FqVar,
or some other name? I'm just worried that calling it block
could suggest it's the block height, which it isn't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to store a PositionVar now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No I meant, what's the rationale for the representation? I'm not opposed to using an FqVar, I'm just wondering how we decide one or the other. Can we write up a brief rationale for why we picked one or the other?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A PositionVar
has a position stored internally as both an FqVar
and a series of 48 bit constraints - 16 bits each for the epoch, block, and commitment segment of the position. Since we need to compare the epoch and block from the position from the state commitment proof with the epoch and block from the BSOD, and we're already bit constraining to make two FqVars for the epoch and block in both cases, another (I think cheaper in constraints) option is to compare as bits directly. Comparing as FqVar
s also works though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, in that case wouldn't making the two prefix components FqVars be cheaper? Since we already have the bit-constrained components of the actual position, we can check that they're equal to the provided prefix components without needing to bit-constrain the prefix components, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, you're right. That seems like the way to go to save the additional bit constraints
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah my thinking initially was that using FqVars avoids some overhead; I think using PositionVar is clearer though since it directly matches the domain type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure that comparing bits is cheaper in constraints: checking that (x0 + 2 * x1 + ...) =? (y0 + 2 * y1 + ...) can be done in a single R1CS constraint. Checking x0 =? y0, x1 =? y1 would require several
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that seems like a good reason to use FqVars as in the original design, I think it's clearer than using a Position because it means we don't add any instance variables that don't have meaning but could be (mis)used in the circuit.
50b1d7c
to
0571414
Compare
0571414
to
873b1c7
Compare
d0f12bd
to
5962448
Compare
676864a
to
65407f4
Compare
65407f4
to
3acf558
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know there is a migration to do, but the other changes LGTM
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a comment about relative block conversion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to re-pitch adding tct protos: #4118
so other systems like the web code doesn't have to manually re-create this serialization logic happening in the .into()'s
Took a stab at testing this in a pairing session with @cronokirby today. A few commits were pushed as part of that exploration. We want to do some more testing before we're ready to ship this. |
// Translate inside compact block storage. | ||
translate_compact_block_storage(ctx.clone(), &mut delta).await?; | ||
|
||
delta.put_block_height(0u64); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we reset the block height here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is so we can do an InitChain
handshake with comet and allow it to initialize its internal view before block sync/proposals. The flow looks like this:
pd <- info query -- comet
pd -- app height=0 -> comet
pd <- init chain req -- comet
pd -- init chain resp -> comet
unfortunately, the CometBft spec seem to have been reorganized again, so it will take me a minute to fish out the link
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. So the idea is that setting it to 0
signals that the app is ready for genesis, then once pd
sends the init chain message, it will get set to h+1
as set in the genesis file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's right, it will consume the genesis as a result of reading a zero app height, and then pull the specified initialHeight
let (key, compactblack_bytes): (String, Vec<u8>) = r?; | ||
let block = pb::compact_block::v1::CompactBlock::decode(compactblack_bytes.as_slice())?; | ||
let block = ctx.translate_compact_block(block).await?; | ||
delta.put_proto(key, block); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here the structure is correct, but we need to be reading from/writing to nonverifiable storage (the key looks correct).
let mut stream = delta.nonverifiable_prefix_raw("compactblock/".as_bytes()); | ||
while let Some(r) = stream.next().await { | ||
let (key, compactblack_bytes) = r?; | ||
let block = pb::compact_block::v1::CompactBlock::decode(compactblack_bytes.as_slice())?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: s/black/block/ in var names here.
Most recent round of testing on a private fork of the network showed good results. 👍 Let's make sure to squash this patch into a single commit, as we'll need to cherry-pick it back onto main post-release. |
We recently removed mention of zeroing-out `priv_validator_state.json` for CometBFT as part of the chain upgrade docs. During migration testing on a private fork today, though, several of us observed that without this change, the network would not resume. More research required to understand the root cause here. Refs #4245, #4239.
We recently removed mention of zeroing-out `priv_validator_state.json` for CometBFT as part of the chain upgrade docs. During migration testing on a private fork today, though, several of us observed that without this change, the network would not resume. More research required to understand the root cause here. Refs #4245, #4239.
Make swap_claim check the exact epoch and block in circuit Read epoch from state when creating batch swap output This moves the epoch read directly to the route_and_fill method. Depcrate epoch_starting_height in BSOD Store epoch and block instead of position within BatchSwapOutputDataVar Write migration Add comments about relative block conversion Fix warnings Increment total halt count Change which migration runs Drop extra references to storage before releasing it Use nonverifiable storage for compact block translation This is where they actually are
93a593a
to
0b3f45e
Compare
Squashed into single commit, so it's cherry-pickable. Will wait on CI, then merge into release branch and get things moving. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK, thanks for your work on this @cronokirby @conorsch
This is a cherry-pick of PR #4239, by: Author: Lucas Meier <[email protected]> Date: Thu Apr 18 14:55:50 2024 -0700 This PR: 1. fix a bug in the swap claim circuit 2. includes a migration routine for testnet 71 Swap claim proofs take a `BatchSwapOutputData` as part of their public inputs. This data is used to compute a user's pro-rated share of a batch swap at a given block. For that reason, it is important the output data used in the proof be correct. A swap claim must be bound to the specific BSOD that was produced by that user's swap. The swap claim circuit's validation only checked that the supplied BSOD was produced at the same relative block height as the user's swap. It did not check that the epochs were the same. As a result, it was possible to generate swap claim proofs using a BSOD produced during a different epoch, on potentially much more advantageous terms.
## Describe your changes This is a cherry-pick of #4239, by: Author: Lucas Meier <[email protected]> Date: Thu Apr 18 14:55:50 2024 -0700 This PR: 1. fix a bug in the swap claim circuit 2. includes a migration routine for testnet 71 Swap claim proofs take a `BatchSwapOutputData` as part of their public inputs. This data is used to compute a user's pro-rated share of a batch swap at a given block. For that reason, it is important the output data used in the proof be correct. A swap claim must be bound to the specific BSOD that was produced by that user's swap. The swap claim circuit's validation only checked that the supplied BSOD was produced at the same relative block height as the user's swap. It did not check that the epochs were the same. As a result, it was possible to generate swap claim proofs using a BSOD produced during a different epoch, on potentially much more advantageous terms. ## Issue ticket number and link ## Checklist before requesting a review - [x] If this code contains consensus-breaking changes, I have added the "consensus-breaking" label. Otherwise, I declare my belief that there are not consensus-breaking changes, for the following reason: > This is consensus breaking --------- Co-authored-by: Lucas Meier <[email protected]>
Describe your changes
This changes the circuit check in swap claims to check that the exact epoch and block where a swap was made match that output data for the batch swap of that epoch and block. Previously were effectively only checking that the intra-block value was the same, but not the epoch.
TODO: Write migration for batch swap output datas
Checklist before requesting a review
If this code contains consensus-breaking changes, I have added the "consensus-breaking" label. Otherwise, I declare my belief that there are not consensus-breaking changes, for the following reason: