-
Notifications
You must be signed in to change notification settings - Fork 13
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
Implement fee estimate #325
Conversation
Updated. The basic functionality is working according to the spec as far as I can tell. However there are a lot of todos where things are unclear, please have a look. The main task now is to retrieve the actual |
88637a6
to
eeb8f87
Compare
@shekohex @drewstone any suggestions? |
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.
Good start, hopefully my answers help give more direction here. Let me know if some things aren't clear.
// TODO: hardcoded | ||
let estimated_gas_amount = U256::from(1_721_713); | ||
|
||
// TODO: need to get the actual tokens which are being exchanged (also in handle_vanchor_relay_tx) |
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.
Correct, currently each "bridge" or "set of anchors" is directly coupled with a specific Webb wrapped token. If a relayer receives a request to submit a transaction against Anchor A on Ethereum then we should be able to directly check A.token().
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.
You can organize as you think is best, perhaps with function args or new structs.
wrapped_token: &str, | ||
base_token: &str, | ||
) -> f64 { | ||
let tokens = &[wrapped_token, base_token]; |
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.
At launch the wrapped_token
is likely not going to be listed on any exchanges or markets and therefore no prices. The division at the end seems problematic. Let's just use the base_token
here.
crates/relayer-utils/src/fees.rs
Outdated
|
||
/// Estimate gas price using etherscan.io. Note that this functionality is only available | ||
/// on mainnet. | ||
async fn estimate_gas_price() -> crate::Result<u64> { |
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.
To your previous question about support for different blockchains, here is a perfect function (as many of the others also are) to parameterize this by the chain. Currently, we have the notion of a TypedChainId
that we use to identify chains and ecosystems. You can find this in webb-rs and in Typescript.
The idea with our TypedChainId
is that it identifies a blockchain ecosystem and a chain in that ecosystem. We needed a unique identifier that could work for different ecosystems where chains shared the same chain identifier. It fits into a u48
(or 6-bytes), but we use u64
more commonly and reserve 8-bytes for this identifier in our protocol messages. An example of an 8-byte (or 6-byte.. drop the 0x0000) TypedChainId
is 0x0000010000000001. The last 4-bytes represent the u32
valued chain identifier of all EVM and Substrate based chains.
We could match on different ecosystems/chain identifiers and switch where and how we query for gas. The only two relevant ecosystems atm are EVMs and Substrate chains.
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.
For future consideration, we have in the past tried to integrate this protocol with CosmWasm (Cosmos based smart contract system) chains. In Cosmos, people use very long chain identifiers. So while we have this u64
based identifier which supports nearly every ecosystem, it does not support Cosmos chains.
Example: https://github.com/cosmos/chain-registry/blob/master/gravitybridge/chain.json#L8 (I think this exceeds a u64
)
I suppose as we start to consider v2 of the protocol we really do need to ensure our protocol messages support the variation in chain identifiers, addresses, etc.
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.
In Rust the normal solution for such different data types is something like:
enum ChainTypes {
Ethereum(u64),
Cosmos(String),
}
Serde has a couple of different ways to serialize this
Edit: So it this would be a change to TypedChainId
.
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.
Remember we need a binary format that so small and so efficient, easy to implement and test. Not just that, but also it should be fairly easy to implement in different languages and platforms.
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.
In that case we could take a hash of the chain id string, and store the first 64 bits of that hash. That would be enough to check that the chain id matches another id.
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.
We could do hashing yes, in that case it might fit into our currently allotted 6 bytes. This is actually what we had already planned for the cosmos work.
Nonetheless, the main focus initially is support for EVM and Substrate chains (where we have our current implementations). I would also please ensure you try and leverage the tools we already have built rather than create new ones, specifically the TypedChainId
s for identifying chains.
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 mentioned that in my other pull request:
I tried to use TypedChainId but thats not possible because Typescript tests use randomly generated chain ids, and converting them to TypedChainId fails. At the same time I noticed that there are many different types used for chain id (string, u32, u64). It would be good to refactor this in the future for more consistency.
/// Handler for fee estimation | ||
/// | ||
/// TODO: do we need to add another endpoint for substrate? | ||
pub async fn handle_fee_info() -> Result<impl warp::Reply, Infallible> { |
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.
Coming back to this now at the end of my review after understanding the flows more..
I think we need to parameterize these functions or wrap them in some parameterizable struct by the
TypedChainId
Transaction
type (2 input transfer, 16 input transfer, 2 input withdrawal, 16 input withdrawal)VAnchor
address in question, after all the honest user is requesting info since they're about to relay a transaction spending some funds whose destination chain is theTypedChainId
.
This will tell us the type of chain under consideration so we can switch APIs and gas estimation issues.
For dealing with the Webb wrapped token in case I didn't add enough details, I would recommend checking out the API for submitting a relayable transaction. In that logic, there should be a clear |
Im currently working through the comments and added the caching of I also added fee info to the test case |
- remove static var - add comments - add fee logic for handle_vanchor_relay_tx
- better number types - fixed refund of 1 usd which gets converted to wrapped token - validate refund amount - remove params for fee_info endpoint
- Automatically compile relayer when tests are executed - Add refundWallet for test
Salman suggested to merge this PR first and finish the remaining tasks in a separate PR, so that its easier to review. We can do this if you want, but the code is still not fully working, except in a very specific scenario (certainly not ready for deployment). I will list the main changes and remaining tasks here: Main changes:
Todo now:
Todo potentially in separate PRs:
|
This is ready to review. After review is done, I we can keep the PR open and wait until I finish the remaining tasks in a second PR, then merge both of them together. This way we avoid breaking the main branch, as the code currently only handles fees for relaying USDC on Ethereum. |
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.
LGTM! Good job @Nutomic
Looking forward for the new PRs!
This looks great too! Great work @Nutomic |
We aren’t actually dealing with any string chain ids at the moment too.
Cosmos was just mentioned for the future consideration. We can hash to u32
as well in that case.
…On Mon, Jan 30, 2023 at 7:34 PM Nutomic ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In crates/relayer-utils/src/fees.rs
<#325 (comment)>:
> + wrapped_token: &str,
+ base_token: &str,
+) -> f64 {
+ let tokens = &[wrapped_token, base_token];
+ let prices = COIN_GECKO_CLIENT
+ .price(tokens, &["usd"], false, false, false, false)
+ .await
+ .unwrap();
+ let wrapped_price = prices[wrapped_token].usd.unwrap();
+ let base_price = prices[base_token].usd.unwrap();
+ wrapped_price / base_price
+}
+
+/// Estimate gas price using etherscan.io. Note that this functionality is only available
+/// on mainnet.
+async fn estimate_gas_price() -> crate::Result<u64> {
I mentioned that in my other pull request:
I tried to use TypedChainId but thats not possible because Typescript
tests use randomly generated chain ids, and converting them to TypedChainId
fails. At the same time I noticed that there are many different types used
for chain id (string, u32, u64). It would be good to refactor this in the
future for more consistency.
—
Reply to this email directly, view it on GitHub
<#325 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ADELLF77V7LWQKBRSSX5GITWVB2Z7ANCNFSM6AAAAAATYCP2RE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Can you say more about the errors using the TyoedChainId in Typescript? I’m
pretty sure we have examples using it.
…On Mon, Jan 30, 2023 at 7:35 PM Drew Stone ***@***.***> wrote:
We aren’t actually dealing with any string chain ids at the moment too.
Cosmos was just mentioned for the future consideration. We can hash to u32
as well in that case.
On Mon, Jan 30, 2023 at 7:34 PM Nutomic ***@***.***> wrote:
> ***@***.**** commented on this pull request.
> ------------------------------
>
> In crates/relayer-utils/src/fees.rs
> <#325 (comment)>:
>
> > + wrapped_token: &str,
> + base_token: &str,
> +) -> f64 {
> + let tokens = &[wrapped_token, base_token];
> + let prices = COIN_GECKO_CLIENT
> + .price(tokens, &["usd"], false, false, false, false)
> + .await
> + .unwrap();
> + let wrapped_price = prices[wrapped_token].usd.unwrap();
> + let base_price = prices[base_token].usd.unwrap();
> + wrapped_price / base_price
> +}
> +
> +/// Estimate gas price using etherscan.io. Note that this functionality is only available
> +/// on mainnet.
> +async fn estimate_gas_price() -> crate::Result<u64> {
>
> I mentioned that in my other pull request:
>
> I tried to use TypedChainId but thats not possible because Typescript
> tests use randomly generated chain ids, and converting them to TypedChainId
> fails. At the same time I noticed that there are many different types used
> for chain id (string, u32, u64). It would be good to refactor this in the
> future for more consistency.
>
> —
> Reply to this email directly, view it on GitHub
> <#325 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/ADELLF77V7LWQKBRSSX5GITWVB2Z7ANCNFSM6AAAAAATYCP2RE>
> .
> You are receiving this because you were mentioned.Message ID:
> ***@***.***>
>
|
@drewstone TypedChainId doesnt support the chain id which is used in Typescript tests which is 3334. Calling |
@Nutomic please refer to: https://github.com/webb-tools/webb-rs/blob/main/proposals/src/header.rs. There is a method to get it from a u64. But really I want you to read how we construct it from bytes as that is the encoding that we want. As far as you've mentioned, 3334 fits within a u32. If it's an EVM chain the prefixed 2 bytes should reflect that. |
Closing this one, we can merge #330 only. |
Very much work in progress
Summary of changes
Todo
Reference issue to close (if applicable)
Code Checklist