flow-go
flow-go copied to clipboard
Filter out transactions with insufficient transaction fees
Problem Definition
What problem is this solving?
Currently, a user can submit transactions with zero fees or with insufficient fees or use an account that does not have enough balance to pay for the fees. These transactions make it all the way to the execution node, are executed and recorded on chain as failures. However, this makes it easy to spam the network with such transactions at no cost. In the past there have been such incidences.
Proposed Solution
What are the proposed solutions to this problem?
The Access nodes now have all of the execution state data and can run scripts locally. Hence, the access nodes should be now able to act as a firewall and validate and filter out transactions with insufficient fees or transactions where the payer account does not have enough balance.
However, a performance analysis also needs to be done before introducing this change since the validation will affect all transactions submitted to the chain. This change must also use a feature toggle to turn it Off or On to ensure that access node operators can choose to enable or disable this feature.
Definition of Done
What tests must pass for this issue to be considered solved?
Submitting a transaction with zero fees, or less fees than the minimum fees or using an account that does not have sufficient balance should be rejected by the access node and not make it to the execution node.
### Tasks
- [ ] https://github.com/onflow/flow-go/issues/5823
- [ ] https://github.com/onflow/flow-go/issues/6128
- [ ] https://github.com/onflow/flow-go/issues/6139
- [ ] https://github.com/onflow/flow-go/issues/6129
- [ ] Validate performance of checks on live network
- [ ] Make any performance adjustments needed before broad deployment
In the context of this proposal, I would like to emphasize some subtle aspects:
- I like this proposal as a pragmatic interim step. However, let us be mindful that this is not a long-term solution to the challenge of transaction-driven attacks such as spamming, insufficient payer funds etc. This is because a few byzantine Access Nodes are enough to route a large amount of spam into the system and ANs have (on purpose) too little stake that slashing is a meaningful deterrent (not even touching on the complexities of deciding whether an AN is routing unpayed transactions into the network on purpose or by accident due to data propagation delays with are always there).
- The proposed solution here will only protect from honest clients accidentally submitting unpayed transactions. This is probably the largest fraction of bad transactions; therefore I think this proposal is important to consider.
- This proposal certainly will not protect the network from intentionally malicious transactios (it just makes malicious transactions bit harder, which is not going to be a significant hurdle for somebody actually wanting to spam the network)
- Likely, the proposal would also have too limited effect for dApp developers running their own AN - a model that we explicitly encourage. A dApp developer running their own AN will likely white-list their own transactions, because running a script for every transaction to be submitted adds significant system load for ANs and adds some minor latency. When transactions are white-listed but the dApp runs low on funds to pay for its transactions, their AN would still route those transactions into the network.
- Hence, in my mind most of the time we invest into this interim proposal is eventually throw away work. If all it takes is a few weeks of work and as a result we can hold off implementing the mature solution for a couple more years, than I am all for it. But if takes us 1 - 2 months or more to get to a performant-enough mainnet solution, then I would challenge that implementing this proposal is the best way forward. After all, engineering capacity is one of the most severe constraint on Flow's evolution mid- to longer-term. We simply cannot afford making the problem worse by investing significant time into interim solutions that are throw away work in the long term.
The mature solution is to implement checks on the collectors (but without script execution). First, a collector cluster is massively more BFT compared to a single AN and collectors have significant stake that slashing is a meaningful deterrent. For further details on the mature solution, please see the Sweet Onion Plan
I think the critical issue is spamming is cheap, from spammer to AN, but cost is amplified in the network. From AN to CN , CN to EN etc. if I were a AN operator I would like to prevent this part for sure. On the other hand, there are much easier way to starve AN with script execution.
Eventually I think need to move flowTokenVault to separate register. (it has fixed path anyway)
I think integrating this as an optional validation step for submitted transactions on an Access node should be simple enough. The unknown is what kind of performance impact it would have on the node, especially with higher tx throughput, since checking an account balance is effectively a script execution. However, even at 1000 tps spread across the public cluster, that's not a huge number of executions.
I'll open another issue to create a proof of concept implementation we could trial to get some data before committing to productionalize it.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.