Fix Parallel verification issues (v1)#1417
Fix Parallel verification issues (v1)#1417shargon wants to merge 6 commits intoneo-project:masterfrom
Conversation
|
I will fix the UT when we decide if this is the right fix. Maybe we should move this check to |
src/neo/Ledger/MemoryPool.cs
Outdated
| { | ||
| _unsortedTransactions.Remove(hash); | ||
| return false; | ||
| } |
There was a problem hiding this comment.
I think this isn't the best way. And it's not enough when balance < SendersFeeMonitor.AddSenderFee(tx), more txs will be removed from memory pool.
There was a problem hiding this comment.
Since we already have UpdatePoolForBlockPersisted, and this TryAdd is called from a single thread (the Blockchain actor). We need to find the cause of this phenomenon.
neo/src/neo/Ledger/MemoryPool.cs
Lines 351 to 361 in fc1a64b
There was a problem hiding this comment.
This happend because it's not a single thread, Blockchain actor, but was send by RPC
So we can add a lock in OnNewTransaction and check if it's solved
There was a problem hiding this comment.
So we can add a lock in OnNewTransaction and check if it's solved
It doesn't work in my tests..
cloud8little
left a comment
There was a problem hiding this comment.
I can still get the error with one single CN, and the sender wallet with only one address.
[15:19:21.903] relay block: height=23 hash=0x35e977d9d7eeabc3e0e568cb9cc6590ebc378929d34fd283c32f19abb20e45c2 tx=0
[15:19:21.913] persist block: height=23 hash=0x35e977d9d7eeabc3e0e568cb9cc6590ebc378929d34fd283c32f19abb20e45c2 tx=0
[15:19:21.923] initialize: height=24 view=0 index=0 role=Primary
[15:19:36.922] timeout: height=24 view=0
[15:19:36.930] send prepare request: height=24 view=0
[15:19:36.954] send commit
[15:19:36.965] relay block: height=24 hash=0x85d722eecef7f7b1f8d0ac761e13f999ed27584f0abb1fc7336f9bc404cdd2ef tx=512
[ERROR][2020/1/16 7:19:37][Thread 0021][akka://NeoSystem/user/$a] Operation is not valid due to the current state of the object.
Cause: System.InvalidOperationException: Operation is not valid due to the current state of the object.
at Neo.Ledger.Blockchain.Persist(Block block) in D:\NEO\Github\neo\src\neo\Ledger\Blockchain.cs:line 501
at Neo.Ledger.Blockchain.OnNewBlock(Block block) in D:\NEO\Github\neo\src\neo\Ledger\Blockchain.cs:line 328
at Neo.Ledger.Blockchain.OnReceive(Object message) in D:\NEO\Github\neo\src\neo\Ledger\Blockchain.cs:line 465
at Akka.Actor.UntypedActor.Receive(Object message)
at Akka.Actor.ActorBase.AroundReceive(Receive receive, Object message)
at Akka.Actor.ActorCell.ReceiveMessage(Object message)
at Akka.Actor.ActorCell.Invoke(Envelope envelope)
[ERROR][2020/1/16 7:19:37][Thread 0021][akka://NeoSystem/user/$a] Error while creating actor instance of type Neo.Ledger.Blockchain with 2 args: (Neo.NeoSystem,Neo.Plugins.Storage.Store)
Cause: [akka://NeoSystem/user/$a#1090028194]: Akka.Actor.PostRestartException: Exception post restart (System.InvalidOperationException)
---> System.TypeLoadException: Error while creating actor instance of type Neo.Ledger.Blockchain with 2 args: (Neo.NeoSystem,Neo.Plugins.Storage.Store)
---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---> System.InvalidOperationException: Operation is not valid due to the current state of the object.
at Neo.Ledger.Blockchain..ctor(NeoSystem system, IStore store) in D:\NEO\Github\neo\src\neo\Ledger\Blockchain.cs:line 111
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at System.Activator.CreateInstance(Type type, Object[] args)
at Akka.Actor.Props.ActivatorProducer.Produce()
at Akka.Actor.Props.NewActor()
--- End of inner exception stack trace ---
at Akka.Actor.Props.NewActor()
at Akka.Actor.ActorCell.CreateNewActorInstance()
at Akka.Actor.ActorCell.<>c__DisplayClass109_0.<NewActor>b__0()
at Akka.Actor.ActorCell.UseThreadContext(Action action)
at Akka.Actor.ActorCell.NewActor()
at Akka.Actor.ActorCell.FinishRecreate(Exception cause, ActorBase failedActor)
--- End of inner exception stack trace ---
sender wallet with initial balance 100000 gas.
request:
{
"jsonrpc": "2.0",
"method": "sendtoaddress",
"params": ["0x8c23f196d8a1bfd103a9dcb1f9ccf0c611377d3b", "NcnELA9BMsxDCzatGmTT5Tbq5dFTEXMarN",0.00000001],
"id": 1
}
use jmeter to send 600 requests at one time.
|
I'll help investigate this problem |
|
@cloud8little thanks for your test, i spent half hour without issues and before the fix the issue was thrown in the first 4 blocks... I will review it more! |
|
@cloud8little if you try to replicate your issue with multiple threads, you will get another error produced by parallel verification |
eryeer
left a comment
There was a problem hiding this comment.
Good job, In this case the gas calculation error can be prevented.
| try | ||
| { | ||
| // Check balance | ||
| BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, tx.Sender); |
There was a problem hiding this comment.
In this sense, the key error was to not consider the current Balance of the sender, which is updated in parallel during OnPersist event?
There was a problem hiding this comment.
I think we should move the "balance check" to BlockChain.OnParallelVerified, which is right place to verify the transaction.
|
Test cases:
Test result: [PASS]
|
|
I have told you that it is very dangerous to use multithreading in actors. |
|
I think we can call |
|
We need to check if after this changes, parallel will be faster |
#1423 we can choose wich is the best one. |
Close #1420
Note: The issue doesn't happen without parallel verification.