-
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
Set max persisted conflicts signers #2908
Conversation
// Check already stored signers | ||
|
||
var conflictingSigners = tx.Signers.Select(s => s.Account); | ||
|
||
foreach (var attr in tx.GetAttributes<Conflicts>()) | ||
{ | ||
var conflictRecord = snapshot.TryGet( | ||
new KeyBuilder(NativeContract.Ledger.Id, LedgerContract.Prefix_Transaction).Add(attr.Hash))? | ||
.GetInteroperable<TransactionState>(); | ||
if (conflictRecord == null) continue; | ||
|
||
if (conflictRecord.ConflictingSigners.Concat(conflictingSigners).Distinct().Count() > 100) | ||
{ | ||
return false; | ||
} | ||
} | ||
|
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.
The direction is right, this will fix the problem (if, of course, the true source of the problem is the conflicting signers list overflow). We need to test this patch against the nice scenario provided by @vang1ong7ang in #2907 (comment).
By the way, I think this PR's idea will solve this golang-C# inconsistency indeed if golang follows. #2907 (comment) While I'm not sure if it can prevent the entire issue of #2907 if no mempool change is made. |
I think @AnnaShaleva knows what happened and works on the right direction |
Adding over-tight restrictions doesn't completely solve the problem, it just makes the functionality worse and worse. |
First of all, I'll port this And actually, this problem with neo/src/Neo/SmartContract/Native/LedgerContract.cs Lines 263 to 268 in 5207956
Which uses GetTransactionState that retrieves all (both proper and dummy) transactions:neo/src/Neo/SmartContract/Native/LedgerContract.cs Lines 244 to 249 in 5207956
And likely throws the exception on deserialization (right before the Transaction field check).
|
Co-authored-by: Anna Shaleva <[email protected]>
@vang1ong7ang, why do you think so? |
max attr per tx / max signers per tx / max conflict per tx / ... are not something critical, reducing them only increase a little bit the cost of the hacker. |
Ready to merge @roman-khimov @Liaojinghui could you review it? |
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.
Let's wait for the other PR, test both together and merge both of them solving the issue.
On Monday I can try to prepare a temporary network similar to testnet that we can all test.
To be responsible, only collecting approvals is not enough for the merge. Build your 7-node private testnet and follow the instructions at #2907, only if you can prove to others that it can not break the testnet then is the merge deemed good. I think that’s why Vang provides the details. It’s for good purposes like this. Ignore me if you developers have your own ways. These words comes because I feel unfair for Vang when you want him to build a private environment while you won’t. |
…ict record Instead of restricting the maximum number of conflicting signers per conflict record we can restrict the number of transactions that make their contribution to this conflict record. The constraint nature is the same, it doesn't allow to spam the chain with a large set of transactions with the same Conflicts attribute. However, this approach has several benefits over restricting the number of signers for these conflicting transactions: 1. It significantly simplifies and accelerates a newly-pooled transactions verification. We don't need to perform this `Concat(signers).Distinct().Count()` operation anymore on new transaction addition. 2. It has a space for improvement which is not presented in this commit, but have to be implemented if the current solution will be accepted by the core developers. A space for improvement is the following: during Conflicts attribute verification we don't actually need to retrieve the whole list of conflicting signers for the conflict record. What we need instead is to check the `ConflictingTransactionsCount` field only. Thus, we may safely omit the `ConflictingSigners` deserialisation from stack item. 3. It allows to easily port the same constraint to the mempool (see the further commit) which, in turn, roughly restrict the overall possible number of transactions per conflict record in Ledger contract up to 2*MaxAllowedConflictingTransactions. It means, that the maximum number of signers per conflict record in the worst case equals to 2*MaxAllowedConflictingTransactions*(MaxTransactionAttributes-1)=480. At the same time, the overhead the current commit brings in the `TransactionState` is quite insignificant (it's only a single extra Integer field). Note 1: this PR changes the native Ledger scheme, thus, requires the DB resync on upgrade. States will differs from the current 3.6.0 T5. Note 2: this PR (as far as neo-project#2908) doesn't help with those transactions that already were included into blocks 2690038-2690040 of the current T5 due to the neo-project#2907 (comment). We need to have a separate discussion on these "malicious" blocks and decide how to handle them. However, this PR doesn't ever prevent the node from the proper processing of these blocks on resync, the blocks will be processed successfully (with HALT state, the same as they were processed by the 3.6.0 release). Signed-off-by: Anna Shaleva <[email protected]>
Instead of restricting the maximum number of conflicting signers per conflict record we can restrict the number of transactions that make their contribution to this conflict record. The constraint nature is the same, it doesn't allow to spam the chain with a large set of transactions with the same Conflicts attribute. However, this approach has several benefits over restricting the number of signers for these conflicting transactions: 1. It significantly simplifies and accelerates a newly-pooled transactions verification. We don't need to perform this `Concat(signers).Distinct().Count()` operation anymore on new transaction addition. 2. It has a space for improvement which is not presented in this commit, but have to be implemented if the current solution will be accepted by the core developers. A space for improvement is the following: during Conflicts attribute verification we don't actually need to retrieve the whole list of conflicting signers for the conflict record. What we need instead is to check the `ConflictingTransactionsCount` field only. Thus, we may safely omit the `ConflictingSigners` deserialisation from stack item. 3. It allows to easily port the same constraint to the mempool (see the further commit) which, in turn, roughly restrict the overall possible number of transactions per conflict record in Ledger contract up to 2*MaxAllowedConflictingTransactions. It means, that the maximum number of signers per conflict record in the worst case equals to 2*MaxAllowedConflictingTransactions*(MaxTransactionAttributes-1)=480. At the same time, the overhead the current commit brings in the `TransactionState` is quite insignificant (it's only a single extra Integer field). Note 1: this PR changes the native Ledger scheme, thus, requires the DB resync on upgrade. States will differ from the current 3.6.0 T5. Note 2: this PR (as far as neo-project#2908) doesn't help with those transactions that already were included into blocks 2690038-2690040 of the current T5 due to the neo-project#2907 (comment). We need to have a separate discussion on these "malicious" blocks and decide how to handle them. However, this PR doesn't ever prevent the node from the proper processing of these blocks on resync, the blocks will be processed successfully (with HALT state, the same as they were processed by the 3.6.0 release). Signed-off-by: Anna Shaleva <[email protected]>
I've created the second part of this PR, please, check out the #2911. See also #2907 (comment) comment. |
…lict record (#2911) * Revert "Sort and limit size" This reverts commit 2a69047. As it was said in #2909 (comment), we can't save only a part of on-chained conflicting signers. Instead, we need to construct new blocks in such way so that there were no conflicting signers limit overflow. It's not hard to implement, see the further commits. Signed-off-by: Anna Shaleva <[email protected]> * Ledger: restrict max number of conflicting txs per conflict record Instead of restricting the maximum number of conflicting signers per conflict record we can restrict the number of transactions that make their contribution to this conflict record. The constraint nature is the same, it doesn't allow to spam the chain with a large set of transactions with the same Conflicts attribute. However, this approach has several benefits over restricting the number of signers for these conflicting transactions: 1. It significantly simplifies and accelerates a newly-pooled transactions verification. We don't need to perform this `Concat(signers).Distinct().Count()` operation anymore on new transaction addition. 2. It has a space for improvement which is not presented in this commit, but have to be implemented if the current solution will be accepted by the core developers. A space for improvement is the following: during Conflicts attribute verification we don't actually need to retrieve the whole list of conflicting signers for the conflict record. What we need instead is to check the `ConflictingTransactionsCount` field only. Thus, we may safely omit the `ConflictingSigners` deserialisation from stack item. 3. It allows to easily port the same constraint to the mempool (see the further commit) which, in turn, roughly restrict the overall possible number of transactions per conflict record in Ledger contract up to 2*MaxAllowedConflictingTransactions. It means, that the maximum number of signers per conflict record in the worst case equals to 2*MaxAllowedConflictingTransactions*(MaxTransactionAttributes-1)=480. At the same time, the overhead the current commit brings in the `TransactionState` is quite insignificant (it's only a single extra Integer field). Note 1: this PR changes the native Ledger scheme, thus, requires the DB resync on upgrade. States will differ from the current 3.6.0 T5. Note 2: this PR (as far as #2908) doesn't help with those transactions that already were included into blocks 2690038-2690040 of the current T5 due to the #2907 (comment). We need to have a separate discussion on these "malicious" blocks and decide how to handle them. However, this PR doesn't ever prevent the node from the proper processing of these blocks on resync, the blocks will be processed successfully (with HALT state, the same as they were processed by the 3.6.0 release). Signed-off-by: Anna Shaleva <[email protected]> * MemoryPool: restrict max number of conflicting txs per conflict record Port the Ledger conflicting tx restriction logic to the MemoryPool: the maximum number of mempooled transactions that has the same Conflicts attribute (i.e. those that conflict with the same transaction) is restricted by the LedgerContract.MaxAllowedConflictingTransactions constant. This restriction, combined with the existing Ledger's storage restriction, roughly restricts the overall possible number of transactions per conflict record in Ledger contract up to 2*MaxAllowedConflictingTransactions. It means, that the maximum number of signers per conflict record in the worst case equals to 2*MaxAllowedConflictingTransactions*(MaxTransactionAttributes-1)=480. Signed-off-by: Anna Shaleva <[email protected]> --------- Signed-off-by: Anna Shaleva <[email protected]>
Closed in favor of #2913 |
Partially fix of #2907
First step, ledger fix
Second step, memory pool fix ( @AnnaShaleva thanks for it)