SmartContract: restrict the number of allowed notifications#3548
SmartContract: restrict the number of allowed notifications#3548
Conversation
* Add entries to Designation event * Change to HF_Echidna * Add UT * Add count
* add base64url * active in * update placehold hf height * fix hf issue and move methods to proper place. * fix test * use identifymodel instead.
* Add entries to Designation event * Change to HF_Echidna * Add UT * Add count
* add base64url * active in * update placehold hf height * fix hf issue and move methods to proper place. * fix test * use identifymodel instead.
# Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
Fix the problem described in nspcc-dev/neo-go#3490. Port the solution from nspcc-dev/neo-go#3640. MaxNotificationsCount constraint is chosen based on the Mainnet statistics of the number of notifications per every transaction, ref. nspcc-dev/neo-go#3490 (comment). Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
|
This needs to be in VM limit |
| list.AddRange(nodes); | ||
| list.Sort(); | ||
| engine.SnapshotCache.Add(key, new StorageItem(list)); | ||
There was a problem hiding this comment.
Formatting job is failing without this change.
Strictly speaking, it's not a VM limit. Notifications are not a part of VM, they are a part of execution engine. |
| // Restrict the number of notifications for Application executions. Do not check | ||
| // persisting triggers to avoid native persist failure. Do not check verification | ||
| // trigger since verification context is loaded with ReadOnly flag. | ||
| if (IsHardforkEnabled(Hardfork.HF_Echidna) && Trigger == TriggerType.Application && notifications.Count == MaxNotificationCount) |
There was a problem hiding this comment.
Looks good to me, we just need to ensure .Count is correct calculated at this step.
There was a problem hiding this comment.
Is trigger really needed? Limits shouldn't have a trigger.
There was a problem hiding this comment.
Yes, it's needed, because we can't allow OnPersist and PostPersist failures (imagine that in future MaxNotificationCount may be reduced to some lower value). And for Verification trigger this check is useless by design, no notifications are possible with this trigger.
There was a problem hiding this comment.
All the same thing. Class is called |
|
instead of limiting number of notifactions, i prefer to make the price related to the notifaction size. From @AnnaShaleva 's excellent benchmark, i think size * number is the real reason. Cause i think its a normal practice contract may need to send a lof of notifactions, but definately abnormal to send large notifactions. |
Exactly, as described in nspcc-dev/neo-go#3490 (comment).
Yes, it's an alternative solution proposed in nspcc-dev/neo-go#3490 (comment). But we need to discuss it because even with extremely expensive notifications there's a chance that CNs will be killed by a single transaction. Yes, the user will have to pay for it, but CNs may not be able to process this transaction. Also, large number of notifications is harmful for both C# and Go RPC servers. So to me, the restriction of the overall notifications number is required, but at the same time it can be combined with dynamic price solution. |
The base branch was changed.
src/Neo.CLI/config.fs.mainnet.json
Outdated
| "HF_Cockatrice": 5800000, | ||
| "HF_Domovoi": 5800000 | ||
| "HF_Domovoi": 5800000, | ||
| "HF_Echidna": 5800001 |
There was a problem hiding this comment.
It comes from the branch change
|
This should be included in 3.8 |
|
Previously we’ve agreed that this solution is less preferable than #3600. @roman-khimov do you think we need to merge it? |
Why not complementary? |
|
The theory is that if we're to have #3552 done with |
8dd5b25 to
7345ac4
Compare
Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
7345ac4 to
c309f63
Compare
|
Good, updated. Then let's consider merging this PR in 3.8. I'm also voting for the merge since I agree that this solution is better than nothing. Later, when we have lower |
|
@neo-project/core please review |
…ect#3548) * add hardofork HF_Echidna * Add entries to `Designation` event (neo-project#3397) * Add entries to Designation event * Change to HF_Echidna * Add UT * Add count * [Neo Core StdLib] Add Base64url (neo-project#3453) * add base64url * active in * update placehold hf height * fix hf issue and move methods to proper place. * fix test * use identifymodel instead. * add hardofork HF_Echidna * Add entries to `Designation` event (neo-project#3397) * Add entries to Designation event * Change to HF_Echidna * Add UT * Add count * [Neo Core StdLib] Add Base64url (neo-project#3453) * add base64url * active in * update placehold hf height * fix hf issue and move methods to proper place. * fix test * use identifymodel instead. * SmartContract: restrict the number of allowed notifications Fix the problem described in nspcc-dev/neo-go#3490. Port the solution from nspcc-dev/neo-go#3640. MaxNotificationsCount constraint is chosen based on the Mainnet statistics of the number of notifications per every transaction, ref. nspcc-dev/neo-go#3490 (comment). Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru> * SmartContract: fix format Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru> * Update src/Neo/SmartContract/ApplicationEngine.Runtime.cs * Avoid notification creation * add hardofork HF_Echidna * Add entries to `Designation` event (neo-project#3397) * Add entries to Designation event * Change to HF_Echidna * Add UT * Add count * [Neo Core StdLib] Add Base64url (neo-project#3453) * add base64url * active in * update placehold hf height * fix hf issue and move methods to proper place. * fix test * use identifymodel instead. * format * Fixed typo * Added back neo-project#3397 * fix format * Update src/Neo/SmartContract/Native/RoleManagement.cs * Neo.CLI: revert configuration changes Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru> --------- Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru> Co-authored-by: Jimmy <jinghui@wayne.edu> Co-authored-by: Shargon <shargon@gmail.com> Co-authored-by: Christopher Schuchardt <cschuchardt88@gmail.com> Co-authored-by: NGD Admin <154295625+NGDAdmin@users.noreply.github.com>
Description
The problem is described in nspcc-dev/neo-go#3490. In short words, an arbitrary number of smart contract notifications is allowed (up to VM's GasLimit and MaxBlockSystemFee, but it's huge), which results in a possibility to DoS the node. 10K of large notifications emitted in a single transaction result in block acceptance delays for both Go and C# nodes. 50K of large notifications may result in the node failure. I did these tests on privnet, you may find the results in nspcc-dev/neo-go#3490 (comment). Please, don't try to DoS mainnet/testnet using this vulnerability.
Port the solution from nspcc-dev/neo-go#3640, but an alternative solution is described in nspcc-dev/neo-go#3640 (comment) and in nspcc-dev/neo-go#3490 (comment). MaxNotificationsCount constraint is chosen based on the Mainnet statistics of the number of notifications per every transaction, ref. nspcc-dev/neo-go#3490 (comment).
This PR is a subject of discussion, hence please, share your thoughts on the described problem and proposed solution. Once we agree on the solution, I'll add unit-tests to this PR.
Type of change
How Has This Been Tested?
Checklist: