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

core: check the signers of on-chained conflicting transaction during new transaction verification #3061

Merged
merged 3 commits into from
Jul 21, 2023

Conversation

AnnaShaleva
Copy link
Member

@AnnaShaleva AnnaShaleva commented Jul 14, 2023

Problem

On-chain conflicting transaction is treated as "good" and valid by default, which may prevent the main transaction from entering the chain in case of an attack. The problem is described by @shargon in neo-project/neo#2818 (comment).

Solution

Check the signers of conflicting transaction and treat conlflict as valid only if the list of signers intersects with signers of incoming main transaction. The check in mempool is updated as far.

@AnnaShaleva
Copy link
Member Author

I've checked this in neo-bench as far (https://github.com/nspcc-dev/neo-bench/tree/test-conflicts), works as expected:

anna@kiwi:~/Documents/GitProjects/nspcc-dev/neo-bench/conflicts_test$ go run ./test.go 
Block count: 5
Good signer: NbrUYaZgyhSkNoRo9ugRyEMdUZxrhkNaWB
Malicious signer: NeP95cDcmYz2naacfASxuv2R5vo6jgdBMW
`smallNetworkFee` value: 10000000 GAS
Waiting for an empty block to be processed...
Block count: 5
Block count: 5
Block count: 6

Starting the mempool test.

tx1: 94a2cb50d3d6d533fcd44f786671dcae51d4fa07dfc4f0e3dff539b21e6fb68d
tx2: 302291c5f6461fd526f2a0f21a5f0a7e13db873db999a54bc84d9b83bb36d88c
tx3: 1c418d7a31905d696d8bc73d1b95b97717c5c06e669f9044dc6fec3fbebdb692
tx4: ce2fd7168ff5ef05e66e1d15b9e1e0b7d7f91def7f22634c0da19b88ea66b2be
tx5: 3fd19c5271e969870d773974f49a50cef2c2d29dadfb0fae199c83e05656f8d2
tx6: 485680a39b0c08b87825dda04ad0f2260777887d392648c60085ced55e458fd7
tx7: 374ce97cd55fcc7c1a38fa745aeef52c7c0a2fb9ecd24c6aa720c075402b9484
tx8: f3238f53703920d0785da2e69068c94b5b3143f11e01f261b0b8e9159da29b33
tx9: 3dd14666a6ccf46b69e5e714d8224c933a8ba63b797f2b56d5619f6594bf2b05
tx10: a591c3e709566564a5fd5e384b76dca14393523c06b888fb744e10ba53e66b38
tx11: 03b50b93998c03e9793206449d5bc18c2f73dc55deee9569bd2396fcee1b30d9

Starting test for on-chain transactions.

Waiting for the block to be processed and tx2 to be accepted...

Waiting for the block to be processed and tx15Malicious to be accepted...

Waiting for the block to be processed and tx14 to be accepted...

Test finished successfully.

@AnnaShaleva AnnaShaleva force-pushed the check-onchain-conflicts branch 2 times, most recently from 34ec8c9 to c65ae76 Compare July 18, 2023 15:49
@codecov
Copy link

codecov bot commented Jul 18, 2023

Codecov Report

Merging #3061 (133082e) into master (35ebdc1) will increase coverage by 0.00%.
The diff coverage is 90.66%.

❗ Current head 133082e differs from pull request most recent head ee4b8f8. Consider uploading reports for the commit ee4b8f8 to get more accurate results

@@           Coverage Diff           @@
##           master    #3061   +/-   ##
=======================================
  Coverage   84.64%   84.64%           
=======================================
  Files         329      329           
  Lines       43792    43846   +54     
=======================================
+ Hits        37069    37115   +46     
- Misses       5220     5226    +6     
- Partials     1503     1505    +2     
Impacted Files Coverage Δ
pkg/core/dao/dao.go 80.49% <86.00%> (+0.23%) ⬆️
pkg/core/blockchain.go 78.65% <100.00%> (+0.27%) ⬆️
pkg/core/mempool/mem_pool.go 97.18% <100.00%> (+0.06%) ⬆️
pkg/core/transaction/transaction.go 86.66% <100.00%> (+1.48%) ⬆️

... and 6 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@AnnaShaleva AnnaShaleva marked this pull request as draft July 19, 2023 11:02
@AnnaShaleva
Copy link
Member Author

I'd like to optimize our storage scheme a bit to save a couple of bytes per conflicting record. Thus, not ready for review yet.

@AnnaShaleva AnnaShaleva marked this pull request as ready for review July 19, 2023 11:53
@AnnaShaleva
Copy link
Member Author

Optimisation is done, ready for review.

pkg/core/blockchain.go Show resolved Hide resolved
pkg/core/transaction/transaction.go Outdated Show resolved Hide resolved
pkg/core/dao/dao.go Outdated Show resolved Hide resolved
pkg/core/dao/dao.go Outdated Show resolved Hide resolved
pkg/core/dao/dao.go Outdated Show resolved Hide resolved
pkg/core/mempool/mem_pool.go Outdated Show resolved Hide resolved
pkg/core/blockchain_neotest_test.go Outdated Show resolved Hide resolved
pkg/core/blockchain_neotest_test.go Outdated Show resolved Hide resolved
pkg/core/blockchain_neotest_test.go Outdated Show resolved Hide resolved
pkg/core/blockchain_neotest_test.go Show resolved Hide resolved
pkg/core/blockchain_neotest_test.go Outdated Show resolved Hide resolved
pkg/core/blockchain_neotest_test.go Outdated Show resolved Hide resolved
pkg/core/blockchain_neotest_test.go Outdated Show resolved Hide resolved
`(*Blockchain).HasTransaction` is one of the oldest methods in our
codebase, and currently it's completely unused. I also doubt that
this method works as expected because it returns `true` if transaction
in the mempool.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
Witnesses are not yet created by the moment we return this error,
thus, it was always 0 as an actual number of witnesses in
ErrInvalidWitnessNum.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
pkg/core/dao/dao.go Outdated Show resolved Hide resolved
During new transaction verification if there's an on-chain conflicting
transaction, we should check the signers of this conflicting transaction.
If the signers intersect with signers of the incoming transaction, then
the conflict is treated as valid and verification for new incoming
transaction should fail. Otherwise, the conflict is treated as the
malicious attack attempt and will not be taken into account;
verification for the new incoming transaction should continue.

This commint implements the scheme described at
neo-project/neo#2818 (comment),
thanks to @shargon for digging.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
@roman-khimov roman-khimov merged commit 081f9d3 into master Jul 21, 2023
@roman-khimov roman-khimov deleted the check-onchain-conflicts branch July 21, 2023 19:36
AnnaShaleva added a commit to AnnaShaleva/neo that referenced this pull request Aug 24, 2023
This patch should be a part of fd1748d, but
was accidentally skipped. This patch matches exactly the NeoGo behaviour that
was added in nspcc-dev/neo-go#3061 and that was
discussed earlier in neo-project#2818 (comment).

Fix the issue described in neo-project#2818 (comment).

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
shargon added a commit to neo-project/neo that referenced this pull request Sep 4, 2023
* Payloads: implement Conflicts attribute

Closes #1991.

* Update src/Neo/Ledger/MemoryPool.cs

* Fix conflicting tx fees accounting

Fix the comment #2818 (comment).

* Reformat code and improve variables naming

Fix Vitor's comments.

* Make comments more clear and adjust variables naming

Fix Owen's feedback.

* Fix Conflicts attribute verification

Consider the case when transaction B has the hash of transaction A
in the Conflicts attribute and transaction B is on-chain. Let the
transaction C has the hash of transaction A in the Conflicts attribute.
Then transaction C still should be able to pass verification and should
be accepted to the subsequent block, because transaction A isn't on chain
and transaction A will never be accepted.

Thanks to Owen for testing, this case is described at the
#2818 (review).
The expected behaviour in the described case is that TXID-D and TXID-E will
be successfully accepted to the mempool and to chain, because the conflicting
TXID-A is not on chain (and it's OK that the hash of TXID-A is on-chain as
the conflicting hash).

* Fix formatting, comments and add a testcase for conflicting mempool txs

* Add one more testcase for conflicting transactions

Testcase provided by Vitor in #2818 (comment).

* Implement economic adjustments for Conflicts attribute

Transaction that conflicts with mempooled transactions have to pay
larger network fee than the sum of all conflicting transactions in
the pool that have the same sender as the newcomer.

Port the nspcc-dev/neo-go#3031.

* Remove Trimmed value

* Check signers of on-chained conflict during new tx verification

Fix the problem described in
#2818 (review).

During new transaction verification if there's an on-chain conflicting
transaction, we should check the signers of this conflicting transaction.
If the signers contain payer of the incoming transaction, then the conflict
is treated as valid and verification for new incoming transaction should
fail. Otherwise, the conflict is treated as the malicious attack attempt
and will not be taken into account; verification for the new incoming
transaction should continue in this case.

* Properly handle duplicating Conflicts hashes from the persisted transactions

* Store signers of all conflicting on-chain transactions with the same Conflicts attribute

Store not only signers of the latest conflicting on-chain transaction, but
signers of all conflicting transactions with the same attribute.

* MemoryPool: consider signers intersection on Conflicts check

This patch should be a part of fd1748d, but
was accidentally skipped. This patch matches exactly the NeoGo behaviour that
was added in nspcc-dev/neo-go#3061 and that was
discussed earlier in #2818 (comment).

Fix the issue described in #2818 (comment).

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>

* MemoryPool: add test for on-chain conflict

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>

* Clean using

* Refactor Malicious_OnChain_Conflict test

Move it to the UT_Blockchain.cs file and refactor it a bit to make it
actually pass as expected.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>

* Use Distinct to filter out duplicating conflicting on-chain signers

Co-authored-by: Shargon <shargon@gmail.com>

* Use HashSet as a container of conflicting hashes in the mempool

Fix #2818 (comment).

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>

---------

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
Co-authored-by: Shargon <shargon@gmail.com>
Co-authored-by: Vitor Nazário Coelho <vncoelho@gmail.com>
Co-authored-by: Jimmy <jinghui@wayne.edu>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants