Skip to content
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

SmartContract: restrict the number of allowed notifications #3548

Open
wants to merge 24 commits into
base: master
Choose a base branch
from

Conversation

AnnaShaleva
Copy link
Member

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

  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

How Has This Been Tested?

  • Unit-tests should be added once we agree on solution.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Jim8y and others added 8 commits August 8, 2024 00:24
* 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 <[email protected]>
Signed-off-by: Anna Shaleva <[email protected]>
@cschuchardt88
Copy link
Member

This needs to be in VM limit class.

@@ -78,7 +78,7 @@ private void DesignateAsRole(ApplicationEngine engine, Role role, ECPoint[] node
list.AddRange(nodes);
list.Sort();
engine.SnapshotCache.Add(key, new StorageItem(list));

Copy link
Member

Choose a reason for hiding this comment

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

revert

Copy link
Member Author

@AnnaShaleva AnnaShaleva Oct 23, 2024

Choose a reason for hiding this comment

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

Formatting job is failing without this change.

@AnnaShaleva
Copy link
Member Author

This needs to be in VM limit class.

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)
Copy link
Member

Choose a reason for hiding this comment

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

Looks good to me, we just need to ensure .Count is correct calculated at this step.

Copy link
Member

@cschuchardt88 cschuchardt88 Oct 23, 2024

Choose a reason for hiding this comment

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

Is trigger really needed? Limits shouldn't have a trigger.

Copy link
Member Author

Choose a reason for hiding this comment

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

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

@cschuchardt88
Copy link
Member

cschuchardt88 commented Oct 23, 2024

This needs to be in VM limit class.

Strictly speaking, it's not a VM limit. Notifications are not a part of VM, they are a part of execution engine.

All the same thing. Class is called ExecutionEngineLimits in Neo.VM namespace. How to use engine.Limit.MaxNotification

@Jim8y
Copy link
Contributor

Jim8y commented Oct 24, 2024

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.

@AnnaShaleva
Copy link
Member Author

AnnaShaleva commented Oct 24, 2024

i think size * number is the real reason

Exactly, as described in nspcc-dev/neo-go#3490 (comment).

i prefer to make the price related to the notifaction size.

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.

Jim8y and others added 10 commits November 6, 2024 12:37
* 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.
# Conflicts:
#	src/Neo/Neo.csproj
#	src/Neo/SmartContract/Native/RoleManagement.cs
@Jim8y Jim8y mentioned this pull request Nov 19, 2024
11 tasks
shargon
shargon previously approved these changes Nov 20, 2024
@shargon
Copy link
Member

shargon commented Dec 20, 2024

Any feedback or merge?

nan01ab
nan01ab previously approved these changes Dec 24, 2024
@Jim8y
Copy link
Contributor

Jim8y commented Dec 31, 2024

Any feedback or merge?

As is discussed in our previous meeting, this should wait for #3644

Base automatically changed from HF_Echidna to master January 23, 2025 09:52
@NGDAdmin NGDAdmin dismissed stale reviews from nan01ab and shargon January 23, 2025 09:52

The base branch was changed.

@@ -40,7 +40,8 @@
"HF_Aspidochelone": 3000000,
"HF_Basilisk": 4500000,
"HF_Cockatrice": 5800000,
"HF_Domovoi": 5800000
"HF_Domovoi": 5800000,
"HF_Echidna": 5800001
Copy link
Member

Choose a reason for hiding this comment

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

@AnnaShaleva Should be removed from config

Copy link
Member

Choose a reason for hiding this comment

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

It comes from the branch change

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Discussion Initial issue state - proposed but not yet accepted Hardfork
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants