-
Notifications
You must be signed in to change notification settings - Fork 1k
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
[Neo Core Bug]fix 3300 #3301
[Neo Core Bug]fix 3300 #3301
Conversation
You caught me so quickly. This |
Your PR is definitely a good one. It not only fixed my issue, but also fixed another issue.
|
src/Neo.VM/ReferenceCounter.cs
Outdated
private void DecreaseCounter(int count = 1) | ||
{ | ||
references_count -= count; | ||
if (references_count < 0) throw new InvalidOperationException("Reference counter is negative."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But how is it ever possible? Have you faced with the issue when refcount is negative?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, its @dusmart who found the issue. With Array object deepcopied and removed from the stack, all of its references are removed as well, when we add that copied array to the stack, its internal subitems will not be added to the reference counter, but when we remove that copied item from the stack again, the counter will consider the array subitems.
BArray = AArray.DeepCopy
Remove BArray from stack // this will remove BArray and its subitem from the counter.
Aadd BArray back to stack // This will only add BArray itself back to the counter
Remove BArray from stack // This will remove BArray and its subitems from the counter, and create minus counter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AArray.DeepCopy doesn't increase the counter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AArray.DeepCopy doesn't increase the counter?
It should increase the counter:
Line 75 in 6e8c730
referenceCounter.AddReference(item, this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (references_count < 0) throw new InvalidOperationException("Reference counter is negative.");
I think we should not change this code. It's a bug in the handlers implementation, not in the reference counter logic. So we should fix the source problem, not its consequence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- reference counter is supposed to be not negative, it should be the counter's property, should not rely on the callers.
@Jim8y let's discuss it here, we have a designated thread for it. If we add this change, then it may affect some old transactions. And I'd like to see @roman-khimov's opinion on this topic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? isn't you saying its supposed to be positive? then what problem can this change cause? It happened to be negative in the past?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i suggest to move the reference counter into another pr and keep the fix simple
src/Neo.VM/ReferenceCounter.cs
Outdated
private void DecreaseCounter(int count = 1) | ||
{ | ||
references_count -= count; | ||
if (references_count < 0) throw new InvalidOperationException("Reference counter is negative."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AArray.DeepCopy doesn't increase the counter?
It should increase the counter:
Line 75 in 6e8c730
referenceCounter.AddReference(item, this); |
src/Neo.VM/ReferenceCounter.cs
Outdated
private void DecreaseCounter(int count = 1) | ||
{ | ||
references_count -= count; | ||
if (references_count < 0) throw new InvalidOperationException("Reference counter is negative."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (references_count < 0) throw new InvalidOperationException("Reference counter is negative.");
I think we should not change this code. It's a bug in the handlers implementation, not in the reference counter logic. So we should fix the source problem, not its consequence.
@@ -69,7 +69,7 @@ public StackItem ToStackItem(ReferenceCounter referenceCounter) | |||
{ | |||
ScriptHash.ToArray(), | |||
EventName, | |||
State | |||
State.OnStack ? State : State.DeepCopy(true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me that this change is the one that actually fixes the problem. But the problem is that it requires one more hardfork if we care about safety since it changes the behaviour.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just apply to the hardfork you created. will update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardfork has being applied.
* 'fix-3300' of github.com:Jim8y/neo: Fixed up `main.yml` (neo-project#3292) [Neo Core Style] Rename parameters, update comments, fix code style (neo-project#3294)
I can not agree, counter can not and should not be negative, that should not be ensured by outside callers, but should be an internal feature, we have showed you the case where the counter can be negative, how could you sure that others who write the code will not cause the same problem. |
We know it can increase the counter, but it decrease after the deepcopy command finishes. As the deepcopied value is not on the stack. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about a test?
Seems that master branch is not suitable for me. When I build the NEO.CLI locally on I'm going to apply these changes manually upon v3.7.4 |
tested OK with applying diff to v3.7.4
|
* 'fix-3300' of github.com:Jim8y/neo: Fix error when vc_redist is missing (neo-project#3293)
This test ensures that NeoGo node doesn't have the DeepCopy problem described in neo-project/neo#3300 and fixed in neo-project/neo#3301. This problem leads to the fact that Notifications items are not being properly refcounted by C# node which leads to possibility to build an enormously large object on stack. Go node doesn't have this problem. The reason (at least, as I understand it) is in the fact that C# node performs objects refcounting inside the DeepCopy even if the object itself is not yet on stack. I.e. System.Runtime.Notify handler immediately adds references to the notification argumetns inside DeepCopy: https://github.com/neo-project/neo/blob/b1d27f0189861167b8005a7e40e6d8500fb48cc4/src/Neo.VM/Types/Array.cs#L108 https://github.com/neo-project/neo/blob/b1d27f0189861167b8005a7e40e6d8500fb48cc4/src/Neo.VM/Types/Array.cs#L75 Whereas Go node just performs the honest DeepCopy without references counting: https://github.com/nspcc-dev/neo-go/blob/b66cea5cccbcc8446312b012e29aaf2d1837430a/pkg/vm/stackitem/item.go#L1223 Going further, C# node clears refs for notification arguments (for array and underlying array items). System.Runtime.GetNotifications pushes the notificaiton args array back on stack and increments counter only for the external array, not for its arguments. Which results in negative refcounter once notificaiton is removed from the stack. The fix itself (https://github.com/Jim8y/neo/blob/f471c0542ddd8f527478fbdcda76a3ab9194b958/src/Neo/SmartContract/NotifyEventArgs.cs#L84) doesn't need to be ported to NeoGo because Go node adds object to the refcounter only at the moment when it's being pushed to stack by System.Runtime.GetNotifications handler. This object is treated as new object since it was deepcopied earlier by System.Runtime.Notify handler: https://github.com/nspcc-dev/neo-go/blob/b66cea5cccbcc8446312b012e29aaf2d1837430a/pkg/vm/stack.go#L178. Thus, no functoinal changes from the NeoGo side. And we won't intentionally break our node to follow C# pre-Domovoi invalid behaviour. Close #3484, close #3482. Signed-off-by: Anna Shaleva <[email protected]>
Add a note about System.Runtime.GetNotifications refcounting to Domovoi hardfork. Ref. neo-project/neo#3301 and #3485. Although NeoGo doesn't have anything to be updated, there's a behaviour difference between C# and Go nodes before Domovoi hardfork, it deserves a comment. Signed-off-by: Anna Shaleva <[email protected]>
* [Neo Core Bug]fix 3300 (#3301) * fix 3300 * update format * add state subitems to ref counter, with suggestion from DuSmart * apply hardfork * format * my mistake * fix hardfork * remove negative check * add unit test * apply anna's suggestion --------- Co-authored-by: Shargon <[email protected]> Co-authored-by: NGD Admin <[email protected]> * SmartContract: use executing contract state to check permissions (#3290) It's not correct to use an updated contract state got from native Management to check for the allowed method call. We need to use manifest from the currently executing context for that. It may be critical for cases when executing contract is being updated firstly, and after that it calls another contract. So we need an old (executing) contract manifest for this check. This change is moved under D hardfork to avoid state diff issues on nodes update. Although it should be noted that it's hard to meet the trigger criteria. A port of nspcc-dev/neo-go#3473. This bug was discovered during the similar problem described in nspcc-dev/neo-go#3471 and fixed in nspcc-dev/neo-go#3472. I've checked all other similar usages and the rest of them use proper contract state (executing one, not the Management's one). Signed-off-by: Anna Shaleva <[email protected]> Co-authored-by: Shargon <[email protected]> Co-authored-by: Jimmy <[email protected]> Co-authored-by: Vitor Nazário Coelho <[email protected]> * v3.7.5 * Neo.CLI: enable hardforks for NeoFS mainnet (#3240) Otherwise this configuration file is broken. Port changes from nspcc-dev/neo-go#3446. Signed-off-by: Anna Shaleva <[email protected]> * fix workflow & FS config * remove hardfork for fs testnet --------- Signed-off-by: Anna Shaleva <[email protected]> Co-authored-by: Jimmy <[email protected]> Co-authored-by: Shargon <[email protected]> Co-authored-by: NGD Admin <[email protected]> Co-authored-by: Anna Shaleva <[email protected]> Co-authored-by: Vitor Nazário Coelho <[email protected]>
Description
This pr fixes the issue 3300
Fixes # #3300
Type of change
How Has This Been Tested?
Test Configuration:
Checklist: