Skip to content

avoid waiting for all EVM nodes to sync the latest nonce#1757

Merged
shamardy merged 3 commits intodevfrom
fix-wait-addr-nonce
Apr 18, 2023
Merged

avoid waiting for all EVM nodes to sync the latest nonce#1757
shamardy merged 3 commits intodevfrom
fix-wait-addr-nonce

Conversation

@shamardy
Copy link
Copy Markdown
Collaborator

fixes #1724 (comment), #1724 (comment)

Note: This fix might not work for load balanced nodes since we don't have a way to know which node behind the load balancer returned the latest nonce and the transaction might be sent to another node.

…nd evm transactions to only the nodes that synced the latest nonce
@cipig
Copy link
Copy Markdown

cipig commented Apr 14, 2023

swaps work fine with PLG20 using just the load balanced RPC endpoint https://polygon-rpc.com on both maker and taker:
image

cipig
cipig previously approved these changes Apr 14, 2023
Copy link
Copy Markdown

@cipig cipig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BEP20 to PLG20 works fine too
image

laruh
laruh previously approved these changes Apr 14, 2023
Copy link
Copy Markdown

@laruh laruh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Comment thread CHANGELOG.md Outdated
Copy link
Copy Markdown

@caglaryucekaya caglaryucekaya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

Comment thread mm2src/coins/eth.rs
) -> Box<dyn Future<Item = (U256, Vec<Web3Instance>), Error = String> + Send> {
let fut = async move {
let mut errors: u32 = 0;
loop {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can change this with a repeatable future since we started to work on this function

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, it can be done. Will have to change the function to async to do that.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't know about this, then it can stay as it is

Comment thread mm2src/coins/eth.rs Outdated
} else {
warn!("Max nonce {} != {} min nonce", max, min);
}
let max = nonces.iter().map(|(n, _)| *n).max().unwrap();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use expect here instead of unwrap, writing that nonces is checked above and will not be empty.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment thread mm2src/coins/eth.rs
/// Nodes might need some time to sync and there can be other coins that use same nodes in different order.
/// We need to be sure that nonce is updated on all of them before and after transaction is sent.
/// Requests the nonce from all available nodes and returns the highest nonce available with the list of nodes that returned the highest nonce.
/// Transactions will be sent using the nodes that returned the highest nonce.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means we will trust the result from a single node now. Do you think it can cause any problems?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already sent the transaction to a single node before this PR, we now make sure that the node that we send the transaction to is up to date, so I don't think we will have more problems than we already did. The idea was that swap operations can continue to work even if only one node is up to date and all other nodes are down or outdated, this eliminates the case that happened recently where a taker couldn't spend a swap transaction because one node was not working right.

Alternatively, I can add a 60s delay for the nodes to reach consensus/same state or nonce, if they didn't, we use only the nodes that are up to date as it's done here and log an error for the nodes that are not up to date or take time to sync, what do you think @caglaryucekaya?

In the end I don't think this is a final solution, there is no best solution for the nonce problem in EVM transactions, some wallets (e.g. metamask) save the nonce value and increase it internally, but this not ideal if a transaction is sent from another wallet by the user (if the user uses the same seed in multiple wallets). Other solutions is to wait for confirmation of a transaction before sending another, I believe some EVM DEXs do that to avoid such problems.

The best solution to avoid trusting a single node is to send the transaction to all nodes but this has a higher cost than sending it to only one node.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, I can add a 60s delay for the nodes to reach consensus/same state or nonce, if they didn't, we use only the nodes that are up to date as it's done here and log an error for the nodes that are not up to date or take time to sync, what do you think @caglaryucekaya?

If we're going to accept the largest nonce in the end, it wouldn't bring anything to wait for the others for 60s. I was thinking of a case where the largest nonce result returned is incorrect, but we can ignore that since it wouldn't happen.

@shamardy shamardy dismissed stale reviews from laruh and cipig via b33c054 April 17, 2023 17:04
Copy link
Copy Markdown

@onur-ozkan onur-ozkan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥

Copy link
Copy Markdown

@caglaryucekaya caglaryucekaya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@shamardy shamardy merged commit ef753cd into dev Apr 18, 2023
@shamardy shamardy deleted the fix-wait-addr-nonce branch April 18, 2023 11:31
@shamardy shamardy self-assigned this Apr 20, 2023
@shamardy shamardy mentioned this pull request Apr 21, 2023
@shamardy shamardy restored the fix-wait-addr-nonce branch April 21, 2023 14:21
@shamardy shamardy deleted the fix-wait-addr-nonce branch May 1, 2023 14:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants