Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

[docs] explain that asserting in a contract is a bad thing to do #11077

Open
matthewdarwin opened this issue Mar 11, 2022 · 0 comments
Open

[docs] explain that asserting in a contract is a bad thing to do #11077

matthewdarwin opened this issue Mar 11, 2022 · 0 comments

Comments

@matthewdarwin
Copy link

Kevin Heifner, [10.03.22 22:08]
Concerning transactions not making it into the chain. Some have described it as rolled-back or lost or reverted. Specifically I would like to address those transactions that successfully executed on an API node but never end being placed into a block by a block producer.

To mitigate against abuse, subjective billing (https://github.com/EOSIO/eos/releases/tag/v2.0.10) and the 3-strike (https://github.com/EOSIO/eos/releases/tag/v2.0.9) rule were introduced over a year ago. The subjective billing was initially on by default when originally released. This subjective billing and 3-strike rule was introduced to prevent users from spamming a node with transactions that fail. Later subjective billing was changed to be off by default. Block producers originally enabled it to stop an "abusive" use of the system. Many block producers were not of late running with subjective billing enabled. With the recent up-tick in transaction spamming, many BPs have again enabled subjective billing. The 3-strike rule is always enabled and currently there is no option to disable it.

Contract developers should keep this behavior in mind when developing their contracts. As an example let's think about a game contract that supports multiple games in progress. The contract could be designed to assert all transactions once a winner for a particular game has been chosen. Also let's assume that the game pays for the use of the contract by being the first authorizer of all the transactions. This is problematic because once a game is won all other transactions for that particular game will assert. When this happens on a BP node it will fail the first 3 transactions of that first authorizer and then drop all other queued transactions of that first authorizer without attempting to execute them. In our example, that could mean perfectly valid transactions (for other instances of games by the same first authorizer).

For example here is a recent part of a log that appears to show just this sort of thing happening (account name changed) on EOS.

Failed 100 trxs, account: fungame, sub bill: 1929835us, reason: assert
Failed 14 trxs, account: fungame, sub bill: 1943016us, reason: assert
Failed 27 trxs, account: fungame, sub bill: 1960774us, reason: assert
Failed 71 trxs, account: fungame, sub bill: 1984389us, reason: assert

An alternate way to design this contract would be to return from the contract once a game has been won instead of asserting. By making the transaction not fail (be a no-op) then you will not be subject to this 3-strike failure rule.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant