Skip to content

Conversation

theStack
Copy link
Contributor

@theStack theStack commented Nov 8, 2020

If the blockchain is rescanned for a single block (i.e. start and stop hashes are equal, and with that also the estimated start/stop verification progress values) the progress calculation could lead to a NaN value caused by a division by zero (0.0/0.0), resulting in an invalid JSON result for the getwalletinfo RPC. This PR fixes this behaviour by setting the progress to zero in that special case. Fixes #20297.

The behaviour can easily be reproduced by continuously running single block rescans in an endless loop, e.g. via

#!/bin/bash
while true
do
    bitcoin-cli rescanblockchain $(bitcoin-cli getblockcount)
done

and at the same time perform some getwalletinfo RPCs.

On the master branch, this leads to frequent invalid responses (tested on mainchain):

$ bitcoin-cli getwalletinfo
error: couldn't parse reply from server
$ curl --user `cat ~/.bitcoin/.cookie` --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getwalletinfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/
{"result":{"walletname":"","walletversion":169900,"format":"bdb","balance":0.00000000,"unconfirmed_balance":0.00000000,"immature_balance":0.00000000,"txcount":0,"keypoololdest":1603677276,"keypoolsize":1000,"hdseedid":"3196e33ecb47c7130e6ca60f2f895f9259860dca","keypoolsize_hd_internal":1000,"paytxfee":0.00000000,"private_keys_enabled":true,"avoid_reuse":false,"scanning":{"duration":0,"progress":},"descriptors":false},"error":null,"id":"curltest"}

(note that missing value for "progress" in the JSON result).

On the PR branch, the behaviour doesn't occur anymore.

@practicalswift
Copy link
Contributor

ACK 4771bac, but consider getting rid of the UBSan suppression that is no longer needed after this change :)

FWIW I've tried getting rid of this and all other float divide by zeros in our code base before (see PR #17208), but I had to close that PR due to lack of reviewer interest back then :)

Please consider taking on the other cases from #17208 when you're done with this one. I'd be glad to review :)

@DrahtBot DrahtBot added the Wallet label Nov 8, 2020
Copy link
Contributor

@kristapsk kristapsk left a comment

Choose a reason for hiding this comment

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

ACK 4771bac

@maflcko maflcko added this to the 0.21.0 milestone Nov 10, 2020
@maflcko
Copy link
Member

maflcko commented Nov 11, 2020

Please remove the unused suppression:

diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan
index 75257d886..784273952 100644
--- a/test/sanitizer_suppressions/ubsan
+++ b/test/sanitizer_suppressions/ubsan
@@ -1,7 +1,6 @@
 # -fsanitize=undefined suppressions
 # =================================
 float-divide-by-zero:validation.cpp
-float-divide-by-zero:wallet/wallet.cpp
 
 # -fsanitize=integer suppressions
 # ===============================

Copy link
Member

@hebasto hebasto left a comment

Choose a reason for hiding this comment

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

Approach ACK 4771bac, tested on Linux Mint 20 (x86_64).

Still addressing of #20344 (comment) is anticipated :)

If the blockchain is rescanned for a single block (i.e. start and stop hashes
are equal, and with that also the estimated verification progress) the progress
calculation could lead to a NaN value caused by a division by zero, resulting in
an invalid JSON result for the getwalletinfo RPC.  Fixed by setting the progress
to zero in that special case.

Co-authored-by: MarcoFalke <falke.marco@gmail.com>
@theStack theStack force-pushed the 20201108-wallet-avoid_div_by_zero_on_single_block_rescan branch from 4771bac to 5e14602 Compare November 11, 2020 12:17
@theStack
Copy link
Contributor Author

theStack commented Nov 11, 2020

Force-pushed with the UBSan suppression removal as suggested by practicalswift and MarcoFalke.

Please consider taking on the other cases from #17208 when you're done with this one. I'd be glad to review :)

Thanks for the suggestion and review offer, will definitely take a look into it.

Copy link
Contributor

@promag promag left a comment

Choose a reason for hiding this comment

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

Core review ACK 5e14602.

@maflcko
Copy link
Member

maflcko commented Nov 11, 2020

review ACK 5e14602

@maflcko maflcko merged commit d9f5132 into bitcoin:master Nov 11, 2020
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Nov 11, 2020
…ngle block range

5e14602 wallet: fix scanning progress calculation for single block range (Sebastian Falbesoner)

Pull request description:

  If the blockchain is rescanned for a single block (i.e. start and stop hashes are equal, and with that also the estimated start/stop verification progress values) the progress calculation could lead to a NaN value caused by a division by zero (0.0/0.0), resulting in an invalid JSON result for the `getwalletinfo` RPC.  This PR fixes this behaviour by setting the progress to zero in that special case. Fixes bitcoin#20297.

  The behaviour can easily be reproduced by continuously running single block rescans in an endless loop, e.g. via
  ```bash
  #!/bin/bash
  while true
  do
      bitcoin-cli rescanblockchain $(bitcoin-cli getblockcount)
  done
  ```

  and at the same time perform some `getwalletinfo` RPCs.

  On the master branch, this leads to frequent invalid responses (tested on mainchain):
  ```
  $ bitcoin-cli getwalletinfo
  error: couldn't parse reply from server
  $ curl --user `cat ~/.bitcoin/.cookie` --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getwalletinfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/
  {"result":{"walletname":"","walletversion":169900,"format":"bdb","balance":0.00000000,"unconfirmed_balance":0.00000000,"immature_balance":0.00000000,"txcount":0,"keypoololdest":1603677276,"keypoolsize":1000,"hdseedid":"3196e33ecb47c7130e6ca60f2f895f9259860dca","keypoolsize_hd_internal":1000,"paytxfee":0.00000000,"private_keys_enabled":true,"avoid_reuse":false,"scanning":{"duration":0,"progress":},"descriptors":false},"error":null,"id":"curltest"}
  ```
  (note that missing value for "progress" in the JSON result).

  On the PR branch, the behaviour doesn't occur anymore.

ACKs for top commit:
  MarcoFalke:
    review ACK 5e14602
  promag:
    Core review ACK 5e14602.

Tree-SHA512: f0e6aad5a6cd08b36c5fe820fff0ef26663229b39169a4dbe757f3c795a41cf5c69c9dc90efe7515675ae1059307f8971123781a0514d10704123a6f28b125ab
@fanquake
Copy link
Member

@jonasschnelli reported on IRC that builds have been failing on his CI since this PR was merged. https://bitcoinbuilds.org/index.php?job=ffb7d59f-379f-4f27-a273-a5595b8c5f07:

********* Start testing of WalletTests *********
Config: Using QtTest library 5.9.5, Qt 5.9.5 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 7.4.0)
PASS   : WalletTests::initTestCase()
QDEBUG : WalletTests::walletTests() TransactionTablePriv::refreshWallet
wallet/wallet.cpp:3113:51: runtime error: division by zero
    #0 0x55d52a716807 in CWallet::CreateTransactionInternal(std::vector<CRecipient, std::allocator<CRecipient> > const&, std::shared_ptr<CTransaction const>&, long&, int&, bilingual_str&, CCoinControl const&, FeeCalculation&, bool) /home/ubuntu/src/src/wallet/wallet.cpp:3113:51
    #1 0x55d52a710290 in CWallet::CreateTransaction(std::vector<CRecipient, std::allocator<CRecipient> > const&, std::shared_ptr<CTransaction const>&, long&, int&, bilingual_str&, CCoinControl const&, FeeCalculation&, bool) /home/ubuntu/src/src/wallet/wallet.cpp:3133:16
    #2 0x55d52a470eaa in interfaces::(anonymous namespace)::WalletImpl::createTransaction(std::vector<CRecipient, std::allocator<CRecipient> > const&, CCoinControl const&, bool, int&, long&, bilingual_str&) /home/ubuntu/src/src/interfaces/wallet.cpp:235:24
    #3 0x55d5294ff6b5 in WalletModel::prepareTransaction(WalletModelTransaction&, CCoinControl const&) /home/ubuntu/src/src/qt/walletmodel.cpp:203:27
    #4 0x55d5294351fd in SendCoinsDialog::PrepareSendText(QString&, QString&, QString&) /home/ubuntu/src/src/qt/sendcoinsdialog.cpp:267:28
    #5 0x55d52943a961 in SendCoinsDialog::on_sendButton_clicked() /home/ubuntu/src/src/qt/sendcoinsdialog.cpp:377:10
    #6 0x55d52957527d in SendCoinsDialog::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /home/ubuntu/src/src/qt/moc_sendcoinsdialog.cpp:203:21
    #7 0x7f6344f9d002 in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x29b002)
    #8 0x7f6344f9f47c in QMetaObject::invokeMethod(QObject*, char const*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x29d47c)
    #9 0x55d52914357c in QMetaObject::invokeMethod(QObject*, char const*, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs.h:466:16
    #10 0x55d52914357c in (anonymous namespace)::SendCoins(CWallet&, SendCoinsDialog&, boost::variant<CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown> const&, long, bool) /home/ubuntu/src/src/qt/test/wallettests.cpp:76
    #11 0x55d52913c42f in (anonymous namespace)::TestGUI(interfaces::Node&) /home/ubuntu/src/src/qt/test/wallettests.cpp:187:21
    #12 0x55d529139c98 in WalletTests::walletTests() /home/ubuntu/src/src/qt/test/wallettests.cpp:285:5
    #13 0x55d52916ba22 in WalletTests::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /home/ubuntu/src/src/qt/test/moc_wallettests.cpp:70:21
    #14 0x7f6344f9d002 in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x29b002)
    #15 0x7f6344adb799  (/usr/lib/x86_64-linux-gnu/libQt5Test.so.5+0x13799)
    #16 0x7f6344adc4ef  (/usr/lib/x86_64-linux-gnu/libQt5Test.so.5+0x144ef)
    #17 0x7f6344adca60  (/usr/lib/x86_64-linux-gnu/libQt5Test.so.5+0x14a60)
    #18 0x7f6344add02a in QTest::qExec(QObject*, int, char**) (/usr/lib/x86_64-linux-gnu/libQt5Test.so.5+0x1502a)
    #19 0x55d5290e42fc in main /home/ubuntu/src/src/qt/test/test_main.cpp:94:9
    #20 0x7f634172db96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #21 0x55d528fecd89 in _start (/home/ubuntu/src/src/qt/test/test_bitcoin-qt+0x2633d89)

SUMMARY: UndefinedBehaviorSanitizer: float-divide-by-zero wallet/wallet.cpp:3113:51 in 
FAIL qt/test/test_bitcoin-qt (exit status: 1)

@jonasschnelli
Copy link
Contributor

This triggers at least a dev-by-0 here (

WalletLogPrintf("Fee Calculation: Fee:%d Bytes:%u Needed:%d Tgt:%d (requested %d) Reason:\"%s\" Decay %.5f: Estimation: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out) Fail: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out)\n",
)

Maybe at other places?

How could this not trigger a travis error? I guess we run the qt tests there as well?

@maflcko
Copy link
Member

maflcko commented Nov 12, 2020

Yes, the qt tests did run: https://cirrus-ci.com/task/5112026252967936?command=ci#L3962

@theStack theStack deleted the 20201108-wallet-avoid_div_by_zero_on_single_block_rescan branch November 12, 2020 12:52
@practicalswift
Copy link
Contributor

@fanquake @jonasschnelli Feel free to cherry-pick in 0201cbc from #17208.

jonasschnelli added a commit that referenced this pull request Nov 13, 2020
440f8d3 fix potential devision by 0 (Jonas Schnelli)

Pull request description:

  #20344 removed the divide-by-zero sanitizer suppression in `wallet/wallet.cpp` but kept a potential devision by zero in `wallet.cpp`'s fee logging.

  Detected here https://bitcoinbuilds.org/index.php?job=ffb7d59f-379f-4f27-a273-a5595b8c5f07

ACKs for top commit:
  practicalswift:
    ACK 440f8d3
  laanwj:
    Code review ACK 440f8d3
  hebasto:
    re-ACK 440f8d3

Tree-SHA512: 9f7903d1e567497c5f972d39e9629c059151e705dbed0a6b88f7c6650c50ecf820f78e3e0f3e629c661d45a938c5d7659faae7c61e47ca8b3bdb029661bca55a
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Nov 13, 2020
…Printf

440f8d3 fix potential devision by 0 (Jonas Schnelli)

Pull request description:

  bitcoin#20344 removed the divide-by-zero sanitizer suppression in `wallet/wallet.cpp` but kept a potential devision by zero in `wallet.cpp`'s fee logging.

  Detected here https://bitcoinbuilds.org/index.php?job=ffb7d59f-379f-4f27-a273-a5595b8c5f07

ACKs for top commit:
  practicalswift:
    ACK 440f8d3
  laanwj:
    Code review ACK 440f8d3
  hebasto:
    re-ACK 440f8d3

Tree-SHA512: 9f7903d1e567497c5f972d39e9629c059151e705dbed0a6b88f7c6650c50ecf820f78e3e0f3e629c661d45a938c5d7659faae7c61e47ca8b3bdb029661bca55a
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jun 27, 2021
…Printf

440f8d3 fix potential devision by 0 (Jonas Schnelli)

Pull request description:

  bitcoin#20344 removed the divide-by-zero sanitizer suppression in `wallet/wallet.cpp` but kept a potential devision by zero in `wallet.cpp`'s fee logging.

  Detected here https://bitcoinbuilds.org/index.php?job=ffb7d59f-379f-4f27-a273-a5595b8c5f07

ACKs for top commit:
  practicalswift:
    ACK 440f8d3
  laanwj:
    Code review ACK 440f8d3
  hebasto:
    re-ACK 440f8d3

Tree-SHA512: 9f7903d1e567497c5f972d39e9629c059151e705dbed0a6b88f7c6650c50ecf820f78e3e0f3e629c661d45a938c5d7659faae7c61e47ca8b3bdb029661bca55a
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jun 28, 2021
…Printf

440f8d3 fix potential devision by 0 (Jonas Schnelli)

Pull request description:

  bitcoin#20344 removed the divide-by-zero sanitizer suppression in `wallet/wallet.cpp` but kept a potential devision by zero in `wallet.cpp`'s fee logging.

  Detected here https://bitcoinbuilds.org/index.php?job=ffb7d59f-379f-4f27-a273-a5595b8c5f07

ACKs for top commit:
  practicalswift:
    ACK 440f8d3
  laanwj:
    Code review ACK 440f8d3
  hebasto:
    re-ACK 440f8d3

Tree-SHA512: 9f7903d1e567497c5f972d39e9629c059151e705dbed0a6b88f7c6650c50ecf820f78e3e0f3e629c661d45a938c5d7659faae7c61e47ca8b3bdb029661bca55a
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jun 29, 2021
…Printf

440f8d3 fix potential devision by 0 (Jonas Schnelli)

Pull request description:

  bitcoin#20344 removed the divide-by-zero sanitizer suppression in `wallet/wallet.cpp` but kept a potential devision by zero in `wallet.cpp`'s fee logging.

  Detected here https://bitcoinbuilds.org/index.php?job=ffb7d59f-379f-4f27-a273-a5595b8c5f07

ACKs for top commit:
  practicalswift:
    ACK 440f8d3
  laanwj:
    Code review ACK 440f8d3
  hebasto:
    re-ACK 440f8d3

Tree-SHA512: 9f7903d1e567497c5f972d39e9629c059151e705dbed0a6b88f7c6650c50ecf820f78e3e0f3e629c661d45a938c5d7659faae7c61e47ca8b3bdb029661bca55a
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jul 1, 2021
…Printf

440f8d3 fix potential devision by 0 (Jonas Schnelli)

Pull request description:

  bitcoin#20344 removed the divide-by-zero sanitizer suppression in `wallet/wallet.cpp` but kept a potential devision by zero in `wallet.cpp`'s fee logging.

  Detected here https://bitcoinbuilds.org/index.php?job=ffb7d59f-379f-4f27-a273-a5595b8c5f07

ACKs for top commit:
  practicalswift:
    ACK 440f8d3
  laanwj:
    Code review ACK 440f8d3
  hebasto:
    re-ACK 440f8d3

Tree-SHA512: 9f7903d1e567497c5f972d39e9629c059151e705dbed0a6b88f7c6650c50ecf820f78e3e0f3e629c661d45a938c5d7659faae7c61e47ca8b3bdb029661bca55a
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jul 1, 2021
…Printf

440f8d3 fix potential devision by 0 (Jonas Schnelli)

Pull request description:

  bitcoin#20344 removed the divide-by-zero sanitizer suppression in `wallet/wallet.cpp` but kept a potential devision by zero in `wallet.cpp`'s fee logging.

  Detected here https://bitcoinbuilds.org/index.php?job=ffb7d59f-379f-4f27-a273-a5595b8c5f07

ACKs for top commit:
  practicalswift:
    ACK 440f8d3
  laanwj:
    Code review ACK 440f8d3
  hebasto:
    re-ACK 440f8d3

Tree-SHA512: 9f7903d1e567497c5f972d39e9629c059151e705dbed0a6b88f7c6650c50ecf820f78e3e0f3e629c661d45a938c5d7659faae7c61e47ca8b3bdb029661bca55a
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jul 15, 2021
…Printf

440f8d3 fix potential devision by 0 (Jonas Schnelli)

Pull request description:

  bitcoin#20344 removed the divide-by-zero sanitizer suppression in `wallet/wallet.cpp` but kept a potential devision by zero in `wallet.cpp`'s fee logging.

  Detected here https://bitcoinbuilds.org/index.php?job=ffb7d59f-379f-4f27-a273-a5595b8c5f07

ACKs for top commit:
  practicalswift:
    ACK 440f8d3
  laanwj:
    Code review ACK 440f8d3
  hebasto:
    re-ACK 440f8d3

Tree-SHA512: 9f7903d1e567497c5f972d39e9629c059151e705dbed0a6b88f7c6650c50ecf820f78e3e0f3e629c661d45a938c5d7659faae7c61e47ca8b3bdb029661bca55a
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jul 15, 2021
…Printf

440f8d3 fix potential devision by 0 (Jonas Schnelli)

Pull request description:

  bitcoin#20344 removed the divide-by-zero sanitizer suppression in `wallet/wallet.cpp` but kept a potential devision by zero in `wallet.cpp`'s fee logging.

  Detected here https://bitcoinbuilds.org/index.php?job=ffb7d59f-379f-4f27-a273-a5595b8c5f07

ACKs for top commit:
  practicalswift:
    ACK 440f8d3
  laanwj:
    Code review ACK 440f8d3
  hebasto:
    re-ACK 440f8d3

Tree-SHA512: 9f7903d1e567497c5f972d39e9629c059151e705dbed0a6b88f7c6650c50ecf820f78e3e0f3e629c661d45a938c5d7659faae7c61e47ca8b3bdb029661bca55a
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jul 16, 2021
…Printf

440f8d3 fix potential devision by 0 (Jonas Schnelli)

Pull request description:

  bitcoin#20344 removed the divide-by-zero sanitizer suppression in `wallet/wallet.cpp` but kept a potential devision by zero in `wallet.cpp`'s fee logging.

  Detected here https://bitcoinbuilds.org/index.php?job=ffb7d59f-379f-4f27-a273-a5595b8c5f07

ACKs for top commit:
  practicalswift:
    ACK 440f8d3
  laanwj:
    Code review ACK 440f8d3
  hebasto:
    re-ACK 440f8d3

Tree-SHA512: 9f7903d1e567497c5f972d39e9629c059151e705dbed0a6b88f7c6650c50ecf820f78e3e0f3e629c661d45a938c5d7659faae7c61e47ca8b3bdb029661bca55a
gabriel-bjg pushed a commit to gabriel-bjg/dash that referenced this pull request Jul 16, 2021
…Printf

440f8d3 fix potential devision by 0 (Jonas Schnelli)

Pull request description:

  bitcoin#20344 removed the divide-by-zero sanitizer suppression in `wallet/wallet.cpp` but kept a potential devision by zero in `wallet.cpp`'s fee logging.

  Detected here https://bitcoinbuilds.org/index.php?job=ffb7d59f-379f-4f27-a273-a5595b8c5f07

ACKs for top commit:
  practicalswift:
    ACK 440f8d3
  laanwj:
    Code review ACK 440f8d3
  hebasto:
    re-ACK 440f8d3

Tree-SHA512: 9f7903d1e567497c5f972d39e9629c059151e705dbed0a6b88f7c6650c50ecf820f78e3e0f3e629c661d45a938c5d7659faae7c61e47ca8b3bdb029661bca55a
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Sep 28, 2021
Summary:
If the blockchain is rescanned for a single block (i.e. start and stop hashes
are equal, and with that also the estimated verification progress) the progress
calculation could lead to a NaN value caused by a division by zero, resulting in
an invalid JSON result for the getwalletinfo RPC.  Fixed by setting the progress
to zero in that special case.

Co-authored-by: MarcoFalke <falke.marco@gmail.com>

This is a backport of [[bitcoin/bitcoin#20344 | core#20344]]

Test Plan:
With UBSAN:
`ninja && ninja check`

Reviewers: #bitcoin_abc, deadalnix, Fabien

Reviewed By: #bitcoin_abc, deadalnix, Fabien

Subscribers: deadalnix

Differential Revision: https://reviews.bitcoinabc.org/D10193
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Feb 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Invalid json from getwalletinfo when scanning is in progress

10 participants