-
Notifications
You must be signed in to change notification settings - Fork 10
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
Make EVM transaction submission non-blocking #654
Comments
Fibonacci backoff here was the mistake I guess, Fibanocci backoff assumes uniform availability ( chance of seal in R1 == Rn ) But chance of seal in Flow is actually starting from 0 ( R1=0 ) and somehow increasing over time ( Rn+1 > Rn ) I think for temporary measure starting check from T+d ( where d = educated guess of seal time ( 10 seconds for example ) ) solves the problem. |
Yeah, it seems that the Fibonacci backoff is causing the "large" gaps between retries. It could worth the effort to try out your suggestion, as a temporary measure, before removing the need for awaiting the transaction result altogether. Thanks for the suggestion 🙏 |
Be careful with this! The AN will always be looking at state which is 5-15 seconds behind the state in which the transaction will be executed. For example, I could submit a tx with nonce 5 to one GW, then two seconds later, submit a tx with nonce 6 to another GW. This is highly likely (but not guaranteed!) to succeed if allowed to happen. Less likely (but also possible) a tx that looks like it doesn't have enough balance to run might be waiting for a deposit that is currently in flight. What's odd is that I don't see how this is any different between Ethereum and Flow. On Ethereum, the node I'm talking to also has a delayed view of the state, and can't be sure there isn't a transaction somewhere in the mempool that might make a valid tx invalid, or vice versa. The latency on Flow and the block time on Ethereum are also similar, so it should feel "pretty normal" to an Ethereum dev. There might be more to dig into here... 🤔 |
You have a good point here 👌 . I'll also add the case where some tool out there simply by-passes the GW altogether, by using Cadence transactions which wrap
I believe that one significant difference here, is the fact that Geth nodes communicate with each other. So all the pending transactions are present in the txpool of each node. That's why they are able to perform state validation checks, by using the txpool's internal state. See: https://github.com/onflow/go-ethereum/blob/master/core/txpool/validation.go#L172-L202. I am unsure as to what other Ethereum nodes do on this case. |
Anatomy of transaction submission for Step 1: eth_sendRawTransaction
Step 2: SubmitTransaction
Step 3: SendTxSimply calls Step 4: Add
Step 5: Add
Step 5.1: pool.validateTxBasics
Step 5.2: txpool.ValidateTransaction
Step 5.3: pool.addTxsLocked
Step 5.4: pool.add
Step 5.5: pool.validateTx
Step 5.6: txpool.ValidateTransactionWithState
If during Step 5.* there's any validation error, the submitted transaction will not be included at all in the That's what EVM Gateway also does, but in a blocking manner. Meaning that it waits for the Flow transaction to be sealed, so we can extract any validation errors, mostly related to state (nonce, balance etc). One significant difference here is that EVM Gateway does not have a Another notable difference is how the transaction-related JSON-RPC endpoints behave, for transactions that are still in the Logic for eth_getTransactionByHash:
Logic for eth_getTransactionReceipt
For EVM Gateway, submitted transactions that passed validation, are not searchable by their transaction hash, via the above endpoints, until the corresponding |
We just had a sync on how to approach this - we want to ensure we don't run into sequence number conflicts, because that would fail the EVM Tx execution with users not being able to tell by looking at the EVM Tx hash. We will increase the amount of keys th EVM GW is using for Tx submission and implement #118 to ensure the ley is not reused until the Tx using it was executed. |
Depends on: #586
Currently, whenever a transaction is submitted to the EVM Gateway, by calling the
eth_sendRawTransaction
JSON-RPC endpoint, under the hood we submit a Flow transaction to the Flow network, which wraps a call toEVM.run
.The
eth_sendRawTransaction
is a blocking operation, as it awaits to receive the status of the submitted Flow transaction, until it becomessealed
(see: https://github.com/onflow/flow-evm-gateway/blob/main/services/requester/pool.go#L71-L78). This is done with a retriable operation, using aFibonacci
back-off mechanism. And it has been reported to take some time, on average 20-25 seconds to response (as per community devs).The rationale behind this is the fact that only EVM transactions with a
failed
orsuccessful
status are included in EVM blocks (see: https://github.com/onflow/flow-go/blob/master/fvm/evm/stdlib/contract.cdc#L318-L329).However, the
eth_sendRawTransaction
endpoint has to return the EVM tx hash, or an error message, in the case ofinvalid
transactions. Examples ofinvalid
transactions are cases ofnonce mismatch
, orinsufficient balance
. The EVM Gateway had no other way of getting back these validation errors, other than waiting for the Flow transaction to seal.With the implementation of the local state index, we now have access to the
nonce
andbalance
and we can perform all validation checks, removing the need to submit transactions which are known to be invalid.The list of possible validation errors can be found here: https://github.com/onflow/flow-go/blob/master/fvm/evm/types/codeFinder.go#L11-L54
The validation checks performed by Geth, can be found here: https://github.com/onflow/go-ethereum/blob/master/core/state_transition.go#L374-L382.
If we move all the validation checks on the EVM Gateway side, we can remove the blocking nature of
eth_sendRawTransaction
, thus making it more efficient.Discord thread: https://discord.com/channels/613813861610684416/1162086721471647874/1305607307157311519
The text was updated successfully, but these errors were encountered: