-
Notifications
You must be signed in to change notification settings - Fork 79
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
Storing quotes longer, in case an on-chain order placement is intended #414
Conversation
@@ -16,6 +15,20 @@ pub enum PriceQuality { | |||
Optimal, | |||
} | |||
|
|||
#[derive(Eq, PartialEq, Clone, Copy, Debug, Default, Deserialize, Serialize, Hash)] | |||
#[serde(rename_all = "lowercase")] | |||
pub enum QuoteSigningScheme { |
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.
An alternative implementation could look like this:
#[derive( Debug, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum QuoteSigningScheme {
#[default]
Eip712,
EthSign,
Eip1271AsOnchainOrder,
/// EIP orders can be off-chain and on-chain orders
Eip1271 {
#[serde(default)]
intended_onchain_order: bool
},
PreSign {
#[serde(default)]
intended_onchain_order: bool
},
}
But I never managed to make it backwards compatible with the current API. Hence I decided for the current form. See my playground: https://play.rust-lang.org/?version=nightly&mode=release&edition=2021&gist=db2ec1559dc581fa97c01ad7e2a70ce3
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.
One thing I'm not super a fan of is introducing new artificial signingScheme
values that don't actually exist.
Here is a way that should be backwards compatible (basically it allows an additional onchainOrder: bool
field in the JSON that gets "matched" up with the signingScheme
field): https://play.rust-lang.org/?version=nightly&mode=release&edition=2021&gist=c0cbff908ab7446fc457453299f8e01c
Its almost the same as yours, I just added #[serde(tag = "signingScheme")]
to the QuoteSigngingScheme
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.
Wow... the "tag" command is smart!
But unfortunately, it is not fully backwards compatible. Serde default and serde flatten do not work together, but your solution requires both:
serde-rs/serde#1626
Here is your playground with a failing test: https://play.rust-lang.org/?version=nightly&mode=release&edition=2021&gist=68ed5b31ba40052762430b6d8e742002
I would love to take your solution, but I could not find a solution for that failing unit test
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.
Serde default and serde flatten do not work together, but your solution requires both:
So close! Dang, I didn't know.
In this case, I would recommend deserializing to an intermediate structure and then
match (data.signing_scheme, data.onchain_order) {
(scheme, true) if scheme.is_ecdsa_scheme() => bail!("ECDSA-signed orders cannot be on-chain"),
// ...
}
Something like: https://play.rust-lang.org/?version=nightly&mode=release&edition=2021&gist=0d309b803690a14fbb9cfe9e8a37b1fe
What's since is that serde
generates the code to convert from the intermediary struct to the QuoteSigningScheme
struct without "leaking" the abstraction.
Could you turn this into a draft PR until it should be reviewed? There is a button for that when you create the PR but also should be somewhere for already existing ones. |
Codecov Report
@@ Coverage Diff @@
## main #414 +/- ##
==========================================
+ Coverage 63.91% 63.96% +0.05%
==========================================
Files 228 228
Lines 43917 44252 +335
==========================================
+ Hits 28068 28308 +240
- Misses 15849 15944 +95 |
I am very sorry about the unnecessary noise. I will setup git hooks next so that it will not happen again. |
It is completely fine to have PRs that are not meant for review yet. I just ask that you mark those as Draft so that's clear. I often make PRs to see whether CI succeeds. |
@@ -713,7 +745,8 @@ mod tests { | |||
sell_token_price: 0.2, | |||
}, | |||
kind: OrderKind::Sell, | |||
expiration: now + chrono::Duration::seconds(QUOTE_VALIDITY_SECONDS), | |||
expiration: now + Duration::seconds(STANDARD_QUOTE_VALIDITY_SECONDS), |
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.
Unrelated to this PR (so not asking it to be done here) - but we should probably give the same "allow for configuration" for the STANDARD_QUOTE_VALIDITY_SECONDS
parameter.
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.
Changes look great in general.
Just have one comment about how we represent the new signing schemes in JSON.
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.
The changes work for me.
I don't like that signing schemes are used to store information that has nothing to do with signing schemes, but my understanding is that this is a workaround because we wouldn't be able to decode the current JSON representation of quotes after these changes if we add a flag onchainOrder
(Serde doesn't support that in our setup).
Would it be so bad to break backward compatibility for quotes?
-- Adding new column on table quotes to differentiate the two on-chain signing schemes | ||
-- This is required as different signing schemes have different expirations | ||
CREATE TYPE OnchainSigningScheme AS ENUM ('eip1271', 'presign'); |
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.
(Nits, feel free to ignore.)
I imagine this will be reused to add different behavior to different quote types in the future if needed (e.g., ETH flow orders have a longer expiration for whatever reason).
Then I'd rename OnchainSigningScheme
to QuoteType
just to point out that the signing scheme has nothing to do with this entry (except that it so happens that the two types we have now correspond to the two signature types).
We could also have a different order type for normal quotes instead of making the field NULL
able (maybe eoa
?).
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 think this is a fair suggestion. Maybe "OnchainQuoteType"?
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 kinda like that Federico suggests making it even more general, not just for onchain orders.
I would call it QuoteType
and introduce a new enum value eoa
. eoa
would then also be the default value.
This would also remove the "weird" IS NOT DISTINCT FROM
syntax.
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 wouldn't call it eoa
since, techincally, you can place EIP-1271 and Presign orders as well.
Maybe standard
?
Also, super nit-picky, but can we use Kind
instead of Type
, as it is the "Rust-y" naming convention for these kinds of enums?
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.
Changes look good to me! Only comment is the nit for naming of the onchain_signing_scheme: OnchainSigningScheme
to kind: QuoteKind
to make it more future proof.
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.
Looks great! Thanks for incorporating all the changes.
This PR contains the logic for the new quoting system. I implemented it as Nick suggested in this closed PR: https://github.com/cowprotocol/services/pull/396
Let me summarise the logic for placing orders again:
Additionally, we prepare the PreSign for onchain order placements: the quotes will have a longer validity and order placement via on-chain event can be introduced later.
We introduce this kind of on-chain order placement without an API-call call, as it allows new features, e.g. onchain calculating the valid_to of an order. See the thread here: https://cowservices.slack.com/archives/C036BL4AANP/p1657018904390399
PS: This PR substitutes the PR: #355. I think the split into two PRs makes no longer sense as the logic is so tightly connected. Though it makes this PR a little bit bigger.
Test Plan
None