Compare commits

...

23 Commits

Author SHA1 Message Date
PastaPastaPasta
79c2dbd07e
Merge 1b12e384a2 into 5bf0409eba 2024-12-17 03:01:47 +00:00
pasta
5bf0409eba
Merge #6300: backport: Merge bitcoin#23642, 22794, 23316, 24365, gui#517, 24219, 23253, 24449, 22543
3931608858 Merge bitcoin/bitcoin#22543: test: Use MiniWallet in mempool_limit.py (merge-script)
f147373a32 Merge bitcoin/bitcoin#24449: fuzz: FuzzedFileProvider::write should not return negative value (MarcoFalke)
2a2a2693d0 Merge bitcoin/bitcoin#23253: bitcoin-tx: Reject non-integral and out of range int strings (W. J. van der Laan)
11eeae2ab9 Merge bitcoin/bitcoin#24219: Fix implicit-integer-sign-change in bloom (MarcoFalke)
f16265dd50 Merge bitcoin-core/gui#517: refactor, qt: Use std::chrono for parameters of QTimer methods (Hennadii Stepanov)
b212ca0515 Merge bitcoin/bitcoin#24365: wallet: Don't generate keys for wallets with private keys disabled during upgradewallet (laanwj)
66e77f7879 Merge bitcoin/bitcoin#23316: test: make the node param explicit in init_wallet() (MarcoFalke)
995cae46af Merge bitcoin/bitcoin#22794: test: Verify if wallet is compiled in rpc_invalid_address_message.py test (MarcoFalke)
61a0140362 Merge bitcoin/bitcoin#23642: refactor: Call type-solver earlier in decodescript (MarcoFalke)

Pull request description:

  Bitcoin Backports

ACKs for top commit:
  UdjinM6:
    utACK 3931608858
  PastaPastaPasta:
    utACK 3931608858

Tree-SHA512: 38f384776002e8014b2510aeaf1f4655fea0531011eb326eb2ab546d9e7193ad9e5c4b570d9831f88bb696e06ded04259a21ddb750d7ffedfedebdbb9a951379
2024-12-16 21:01:12 -06:00
pasta
a9cfd39390
Merge #6491: ci: merge bitcoin#27314, #28954, fix multiprocess builds
27d9763b1b fix: add `linux64_multiprocess` `BUILD_TARGET` to matrix, mend C(XX) (Kittywhiskers Van Gogh)
26cc5a1c90 ci: use underscore to separate variant name from target triple (Kittywhiskers Van Gogh)
d0131a5259 trivial: sort `BUILD_TARGET` on GitHub and in `matrix.sh` alphabetically (Kittywhiskers Van Gogh)
4f1b5c165b merge bitcoin#28954: Reduce use of bash -c (Kittywhiskers Van Gogh)
a49162ffae merge bitcoin#27314: Fix handling of `CXX=clang++` when building `qt` package (Kittywhiskers Van Gogh)

Pull request description:

  ## Additional Information

  * [bitcoin#27314](https://github.com/bitcoin/bitcoin/pull/27314) has been backported in this PR as [bitcoin#25838](https://github.com/bitcoin/bitcoin/pull/25838) (backported in [dash#6384](https://github.com/dashpay/dash/pull/6384)) broke Clang depends builds.

  * [bitcoin#28954](https://github.com/bitcoin/bitcoin/pull/28954) has been backported to fix a problem associated with multiprocess runs ([build](https://gitlab.com/dashpay/dash/-/jobs/8396677312#L2921)).

  * Support for multiprocess builds were enabled _proper_ in [dash#6143](https://github.com/dashpay/dash/pull/6143) but unfortunately, the configuration params for multiprocess builds were not processed by CI as the build variant was not added to `matrix.sh` ([source](6a51ab271d/ci/dash/matrix.sh)). This is evident by comparing two variants with Boost::Process enablement (`--with-boost-process`), `linux64_fuzz` ([source](6a51ab271d/ci/test/00_setup_env_native_fuzz.sh (L19))) and `linux64_multiprocess` ([source](6a51ab271d/ci/test/00_setup_env_native_multiprocess.sh (L13))).

    Looking at a `develop` (6a51ab271d) build, the fuzz build has it enabled ([source](https://gitlab.com/dashpay/dash/-/jobs/8394892905#L737)) while the multiprocess build doesn't ([source](https://gitlab.com/dashpay/dash/-/jobs/8394892909#L1524)) despite both scripts having the enablement argument.

  ## Breaking Changes

  None expected.

  ## Checklist:

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)**
  - [x] I have added or updated relevant unit/integration/functional/e2e tests **(note: N/A)**
  - [x] I have made corresponding changes to the documentation **(note: N/A)**
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  PastaPastaPasta:
    utACK 27d9763b1b
  UdjinM6:
    utACK 27d9763b1b

Tree-SHA512: 3e2fb72d4211875a162d3aecb994c5bd43b2f6d9fea0804d7e00a38a034672730f9351ceb9256ace38e32f7ef81527c8a034a870e5099a277dfd06f9fa54b480
2024-12-16 20:42:35 -06:00
pasta
0968a0023b
Merge #6492: test: add functional tests for coinjoinsalt RPC
16c2e13fb4 test: add functional tests for `coinjoinsalt` RPC (Kittywhiskers Van Gogh)
a1b256b06f test: extend CoinJoin RPC tests to include more cases, add logging (Kittywhiskers Van Gogh)
c6dd3dd567 test: rename test functions to reflect RPC used, simplify them (Kittywhiskers Van Gogh)
ff29c62103 test: run CoinJoin RPC tests using blank wallet (Kittywhiskers Van Gogh)

Pull request description:

  ## Additional Information

  * Current suite of tests do not check if restoring salt results in restoring CoinJoin balance. This is because functional tests currently do not test CoinJoin mixing (and thus, routines for the same are not currently present).

  ## Breaking Changes

  None expected.

  ## Checklist:

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas
  - [x] I have added or updated relevant unit/integration/functional/e2e tests
  - [x] I have made corresponding changes to the documentation **(note: N/A)**
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  knst:
    utACK 16c2e13fb4
  UdjinM6:
    utACK 16c2e13fb4

Tree-SHA512: 0ce4e67f2caf0619cae42e8158cd39fba24c0a86050e061511ea23c4c0bf34a0eede72917516b6039d7ac15f85730ab36ba9ec1c42d0eb271f6cb4341389bcec
2024-12-16 20:38:11 -06:00
Kittywhiskers Van Gogh
16c2e13fb4
test: add functional tests for coinjoinsalt RPC 2024-12-16 08:33:23 +00:00
Kittywhiskers Van Gogh
a1b256b06f
test: extend CoinJoin RPC tests to include more cases, add logging 2024-12-16 08:33:22 +00:00
Kittywhiskers Van Gogh
c6dd3dd567
test: rename test functions to reflect RPC used, simplify them 2024-12-16 08:31:27 +00:00
Kittywhiskers Van Gogh
ff29c62103
test: run CoinJoin RPC tests using blank wallet 2024-12-16 08:31:27 +00:00
Kittywhiskers Van Gogh
27d9763b1b
fix: add linux64_multiprocess BUILD_TARGET to matrix, mend C(XX) 2024-12-15 13:12:30 +00:00
Kittywhiskers Van Gogh
26cc5a1c90
ci: use underscore to separate variant name from target triple 2024-12-15 13:12:25 +00:00
Kittywhiskers Van Gogh
d0131a5259
trivial: sort BUILD_TARGET on GitHub and in matrix.sh alphabetically 2024-12-15 13:12:04 +00:00
Kittywhiskers Van Gogh
4f1b5c165b
merge bitcoin#28954: Reduce use of bash -c 2024-12-15 13:08:32 +00:00
Kittywhiskers Van Gogh
a49162ffae
merge bitcoin#27314: Fix handling of CXX=clang++ when building qt package 2024-12-15 13:08:29 +00:00
merge-script
3931608858
Merge bitcoin/bitcoin#22543: test: Use MiniWallet in mempool_limit.py
08634e82c68ea1be79e1395f4f551082f497023f fix typos in logging messages (ShubhamPalriwala)
d447ded6babebe7c7948e585c9e78bf34dbef226 replace: self.nodes[0] with node (ShubhamPalriwala)
dddca3899c4738e512313a85aeb006310e34e31f test: use MiniWallet in mempool_limit.py (ShubhamPalriwala)

Pull request description:

  This is a PR proposed in #20078

  This PR enables running another non-wallet functional test even when the wallet is disabled thanks to the MiniWallet, i.e. it can be run even when bitcoin-core is compiled with --disable-wallet.

  It also includes changes in wallet.py in the form of a new method, `create_large_transactions()` for the MiniWallet to create large transactions.

  Efforts for this feature started in #20874 but were not continued and that PR was closed hence I picked this up.

  To test this PR locally, compile and build bitcoin-core without the wallet and run:
  ```
  $ test/functional/mempool_limit.py
  ```

ACKs for top commit:
  amitiuttarwar:
    ACK 08634e8, only git changes since last push (and one new line).
  Zero-1729:
    ACK 08634e82c68ea1be79e1395f4f551082f497023f 🧉

Tree-SHA512: 0f744ad26bf7a5a784aac1ed5077b59c95a36d1ff3ad0087ffd10ac8d5979f7362c63c20c2ce2bfa650fda02dfbcd60b1fceee049a2465c8d221cce51c20369f
2024-12-06 17:48:07 +05:30
MarcoFalke
f147373a32
Merge bitcoin/bitcoin#24449: fuzz: FuzzedFileProvider::write should not return negative value
fc471814dc34abb4d5479803ebb1033b572eda43 fuzz: FuzzedFileProvider::write should not return negative value (eugene)

Pull request description:

  Doing so can lead to a glibc crash (from 2005 but I think it's relevant https://sourceware.org/bugzilla/show_bug.cgi?id=2074). Also the manpage for fopencookie warns against this: https://man7.org/linux/man-pages/man3/fopencookie.3.html. This would invalidate the autofile seeds (and maybe others?) in qa-assets.

  On another note, I noticed that FuzzedFileProvider::seek has some confusing behavior with SEEK_END. It seems to me that if these handlers are supposed to mimic the real functions, that SEEK_END would use the offset from the end of the stream, rather than changing the offset with a random value between 0 and 4096. I could also open a PR to fix SEEK_END, but it would invalidate the seeds.

ACKs for top commit:
  MarcoFalke:
    cr ACK fc471814dc34abb4d5479803ebb1033b572eda43

Tree-SHA512: 9db41637f0df7f2b2407b82531cbc34f4ba9393063b63ec6786372e808fe991f7f24df45936c203fe0f9fc49686180c65ad57c2ce7d49e0c5402240616bcfede
2024-12-06 17:48:07 +05:30
W. J. van der Laan
2a2a2693d0
Merge bitcoin/bitcoin#23253: bitcoin-tx: Reject non-integral and out of range int strings
fa6f29de516c7af5206b91b59ada466032329250 bitcoin-tx: Reject non-integral and out of range multisig numbers (MarcoFalke)
fafab8ea5e6ed6b87fac57a5cd16a8135236cdd6 bitcoin-tx: Reject non-integral and out of range sequence ids (MarcoFalke)
fa53d3d8266ad0257315d07b71b4f8a711134622 test: Check that bitcoin-tx accepts whitespace around sequence id and multisig numbers (MarcoFalke)

Pull request description:

  Seems odd to silently accept arbitrary strings that don't even represent integral values.

  Fix that.

ACKs for top commit:
  practicalswift:
    cr ACK fa6f29de516c7af5206b91b59ada466032329250
  laanwj:
    Code review ACK fa6f29de516c7af5206b91b59ada466032329250
  Empact:
    Code review ACK fa6f29de51
  promag:
    Code review ACK fa6f29de516c7af5206b91b59ada466032329250.

Tree-SHA512: e31f7f21fe55ac069e755557bdbcae8d5d29e20ff82e441ebdfc65153e3a31a4edd46ad3e6dea5190ecbd1b8ea5a8f94daa5d59a3b7558e46e794e30db0e6c79
2024-12-06 17:48:07 +05:30
MarcoFalke
11eeae2ab9
Merge bitcoin/bitcoin#24219: Fix implicit-integer-sign-change in bloom
fad84a25956ec081f22aebbda309d168a3dc0004 refactor: Fixup uint64_t-cast style in touched line (MarcoFalke)
fa041878de786f5be74ec74a06ec407c99ca8656 Fix implicit-integer-sign-change in bloom (MarcoFalke)

Pull request description:

  Signed values don't really make sense when using `std::vector::operator[]`.

  Fix that and remove the suppression.

ACKs for top commit:
  PastaPastaPasta:
    utACK fad84a25956ec081f22aebbda309d168a3dc0004
  theStack:
    Code-review ACK fad84a25956ec081f22aebbda309d168a3dc0004

Tree-SHA512: 7139dd9aa098c41e4af1b6e63dd80e71a92b0a98062d1676b01fe550ffa8e21a5f84a578afa7a536d70dad1b8a5017625e3a9e2dda6f864b452ec77b130ddf2a
2024-12-05 08:43:28 +05:30
Hennadii Stepanov
f16265dd50
Merge bitcoin-core/gui#517: refactor, qt: Use std::chrono for parameters of QTimer methods
51250b0906e56b39488304208ad119c951b4ae7d refactor, qt: Use std::chrono for input_filter_delay constant (Hennadii Stepanov)
f3bdc143b67e8a5e763071a0774f6d994ca35c57 refactor, qt: Add SHUTDOWN_POLLING_DELAY constant (Hennadii Stepanov)
0e193deb523a4fa04e0ee69bd66f917895802ac9 refactor, qt: Use std::chrono for non-zero arguments in QTimer methods (Hennadii Stepanov)
6f0da958116ecc0e06332fad2f490e37b6884166 refactor, qt: Use std::chrono in ConfirmMessage parameter (Hennadii Stepanov)
33d520ac538fcd6285fd958578f1bd26295592e4 refactor, qt: Use std::chrono for MODEL_UPDATE_DELAY constant (Hennadii Stepanov)

Pull request description:

  Since Qt 5.8 `QTimer` methods have overloads that accept `std::chrono::milliseconds` arguments:
  - [`QTimer::singleShot`](https://doc.qt.io/archives/qt-5.9/qtimer.html#singleShot-8)
  - [`QTimer::start`](https://doc.qt.io/archives/qt-5.9/qtimer.html#start-2)

ACKs for top commit:
  promag:
    Code review ACK 51250b0906e56b39488304208ad119c951b4ae7d.
  shaavan:
    reACK 51250b0906e56b39488304208ad119c951b4ae7d

Tree-SHA512: aa843bb2322a84c0c2bb113d3b48d7bf02d7f09a770779dcde312c32887f973ef9445cdef42f39edaa599ff0f3d0457454f6153aa130efadd989e413d39c6062
2024-12-05 08:43:28 +05:30
laanwj
b212ca0515
Merge bitcoin/bitcoin#24365: wallet: Don't generate keys for wallets with private keys disabled during upgradewallet
c7376cc8d728f3a7c40f79bd57e7cef685def723 tests: Test upgrading wallet with privkeys disabled (Andrew Chow)
3d985d4f43b5344f998bcf6db22d02782e647a2a wallet: Don't generate keys when privkeys disabled when upgrading (Andrew Chow)

Pull request description:

  When we're upgrading a wallet, we shouldn't be trying to generate new keys for wallets where private keys are disabled.

  Fixes #23610

ACKs for top commit:
  laanwj:
    Code review ACK c7376cc8d728f3a7c40f79bd57e7cef685def723
  benthecarman:
    tACK c7376cc8d728f3a7c40f79bd57e7cef685def723 this fixed the issue for me

Tree-SHA512: fa07cf37df9196ff98671bb1ce5c9aa0bab46495066b4dab796d7e8e5d5c7adb414ff56adae4fd3e15658a610995bd19a9e1edb00c46144b0df635c5b343f3a6
2024-12-05 08:43:28 +05:30
MarcoFalke
66e77f7879
Merge bitcoin/bitcoin#23316: test: make the node param explicit in init_wallet()
7b3c9e4ee8feb552dc0fc4347db2d06e60894a9f Make explicit the node param in init_wallet() (lsilva01)

Pull request description:

  This PR changes the definition of `def init_wallet(self, i)` to `def init_wallet(self, *, node)` to make the node parameter explicit, as suggested in https://github.com/bitcoin/bitcoin/pull/22794#discussion_r713287448 .

ACKs for top commit:
  stratospher:
    tested ACK 7b3c9e4.

Tree-SHA512: 2ef036f4c2110b2f7dc893dc6eea8faa0a18edd7f8f59b25460a6c544df7238175ddd6a0d766e2bb206326b1c9afc84238c75613a0f01eeda89a8ccb7d86a4f1
2024-12-05 08:43:28 +05:30
MarcoFalke
995cae46af
Merge bitcoin/bitcoin#22794: test: Verify if wallet is compiled in rpc_invalid_address_message.py test
c2fbdca54915e85ffafe1a88858d3c70c2b1afe8 Add BECH32_INVALID_VERSION test (lsilva01)
b142f79ddb91a44f29fcb2afb7f2edf3ca17e168 skip test_getaddressinfo() if wallet is disabled (lsilva01)

Pull request description:

  Most of  `test/functional/rpc_invalid_address_message.py` does not requires wallet.
  But if the project is compiled in disable-wallet mode, the entire test will be skipped.

  This PR changes the test to run the RPC tests first and then checks if the wallet is compiled.

ACKs for top commit:
  stratospher:
    tested ACK c2fbdca

Tree-SHA512: 11fa2fedf4a15aa45e3f12490df8e22290a867d5de594247211499533c32289c68c0b60bd42dbf8305e43dbcc042789e7139317ef5c9f8cf386f2d84c91b9ac2
2024-12-05 08:43:28 +05:30
MarcoFalke
61a0140362
Merge bitcoin/bitcoin#23642: refactor: Call type-solver earlier in decodescript
33330702081f67cb05fd86e00b252f6355249513 refactor: Call type-solver earlier in decodescript (MarcoFalke)
fab0d998f4bf0f3f09afa51845d91408dd484408 style: Remove whitespace (MarcoFalke)

Pull request description:

  The current logic is a bit confusing. First creating the `UniValue` return dict, then parsing it again to get the type as `std::string`.

  Clean this up by using a strong type `TxoutType`. Also, remove whitespace.

ACKs for top commit:
  shaavan:
    ACK 33330702081f67cb05fd86e00b252f6355249513
  theStack:
    Code-review ACK 33330702081f67cb05fd86e00b252f6355249513

Tree-SHA512: 49db7bc614d2491cd3ec0177d21ad1e9924dbece1eb5635290cd7fd18cb30adf4711b891daf522e7c4f6baab3033b66393bbfcd1d4726f24f90a433124f925d6
2024-12-05 08:43:28 +05:30
pasta
1b12e384a2
ci: add aarch64 macos builds to ci 2024-11-02 22:19:13 -05:00
36 changed files with 426 additions and 181 deletions

View File

@ -114,22 +114,22 @@ jobs:
- build_target: linux64 - build_target: linux64
host: x86_64-pc-linux-gnu host: x86_64-pc-linux-gnu
depends_on: linux64 depends_on: linux64
- build_target: linux64_tsan - build_target: linux64_cxx20
host: x86_64-pc-linux-gnu
depends_on: linux64
- build_target: linux64_ubsan
host: x86_64-pc-linux-gnu host: x86_64-pc-linux-gnu
depends_on: linux64 depends_on: linux64
- build_target: linux64_fuzz - build_target: linux64_fuzz
host: x86_64-pc-linux-gnu host: x86_64-pc-linux-gnu
depends_on: linux64 depends_on: linux64
- build_target: linux64_cxx20 - build_target: linux64_nowallet
host: x86_64-pc-linux-gnu host: x86_64-pc-linux-gnu
depends_on: linux64 depends_on: linux64
- build_target: linux64_sqlite - build_target: linux64_sqlite
host: x86_64-pc-linux-gnu host: x86_64-pc-linux-gnu
depends_on: linux64 depends_on: linux64
- build_target: linux64_nowallet - build_target: linux64_tsan
host: x86_64-pc-linux-gnu
depends_on: linux64
- build_target: linux64_ubsan
host: x86_64-pc-linux-gnu host: x86_64-pc-linux-gnu
depends_on: linux64 depends_on: linux64
container: container:

View File

@ -47,7 +47,7 @@ builder-image:
before_script: before_script:
- echo HOST=$HOST - echo HOST=$HOST
- | - |
if [ "$HOST" = "x86_64-apple-darwin" ]; then if [ "$HOST" = "x86_64-apple-darwin" || "$HOST" = "aarch64-apple-darwin" ]; then
mkdir -p depends/SDKs mkdir -p depends/SDKs
mkdir -p depends/sdk-sources mkdir -p depends/sdk-sources
OSX_SDK_BASENAME="Xcode-${XCODE_VERSION}-${XCODE_BUILD_ID}-extracted-SDK-with-libcxx-headers.tar.gz" OSX_SDK_BASENAME="Xcode-${XCODE_VERSION}-${XCODE_BUILD_ID}-extracted-SDK-with-libcxx-headers.tar.gz"
@ -193,13 +193,13 @@ x86_64-w64-mingw32:
variables: variables:
HOST: x86_64-w64-mingw32 HOST: x86_64-w64-mingw32
x86_64-pc-linux-gnu-debug: x86_64-pc-linux-gnu_debug:
extends: .build-depends-template extends: .build-depends-template
variables: variables:
HOST: x86_64-pc-linux-gnu HOST: x86_64-pc-linux-gnu
DEP_OPTS: "DEBUG=1" DEP_OPTS: "DEBUG=1"
x86_64-pc-linux-gnu-nowallet: x86_64-pc-linux-gnu_nowallet:
extends: extends:
- .build-depends-template - .build-depends-template
- .skip-in-fast-mode-template - .skip-in-fast-mode-template
@ -207,13 +207,13 @@ x86_64-pc-linux-gnu-nowallet:
HOST: x86_64-pc-linux-gnu HOST: x86_64-pc-linux-gnu
DEP_OPTS: "NO_WALLET=1" DEP_OPTS: "NO_WALLET=1"
x86_64-pc-linux-gnu-multiprocess: x86_64-pc-linux-gnu_multiprocess:
extends: extends:
- .build-depends-template - .build-depends-template
- .skip-in-fast-mode-template - .skip-in-fast-mode-template
variables: variables:
HOST: x86_64-pc-linux-gnu HOST: x86_64-pc-linux-gnu
DEP_OPTS: "MULTIPROCESS=1" DEP_OPTS: "DEBUG=1 MULTIPROCESS=1"
x86_64-apple-darwin: x86_64-apple-darwin:
extends: extends:
@ -222,7 +222,12 @@ x86_64-apple-darwin:
variables: variables:
HOST: x86_64-apple-darwin HOST: x86_64-apple-darwin
### aarch64-apple-darwin:
extends:
- .build-depends-template
- .skip-in-fast-mode-template
variables:
HOST: aarch64-apple-darwin
arm-linux-build: arm-linux-build:
extends: .build-template extends: .build-template
@ -243,7 +248,7 @@ win64-build:
linux64-build: linux64-build:
extends: .build-template extends: .build-template
needs: needs:
- x86_64-pc-linux-gnu-debug - x86_64-pc-linux-gnu_debug
variables: variables:
BUILD_TARGET: linux64 BUILD_TARGET: linux64
@ -252,7 +257,7 @@ linux64_cxx20-build:
- .build-template - .build-template
- .skip-in-fast-mode-template - .skip-in-fast-mode-template
needs: needs:
- x86_64-pc-linux-gnu-debug - x86_64-pc-linux-gnu_debug
variables: variables:
BUILD_TARGET: linux64_cxx20 BUILD_TARGET: linux64_cxx20
@ -261,7 +266,7 @@ linux64_sqlite-build:
- .build-template - .build-template
- .skip-in-fast-mode-template - .skip-in-fast-mode-template
needs: needs:
- x86_64-pc-linux-gnu-debug - x86_64-pc-linux-gnu_debug
variables: variables:
BUILD_TARGET: linux64_sqlite BUILD_TARGET: linux64_sqlite
@ -270,7 +275,7 @@ linux64_fuzz-build:
- .build-template - .build-template
- .skip-in-fast-mode-template - .skip-in-fast-mode-template
needs: needs:
- x86_64-pc-linux-gnu-debug - x86_64-pc-linux-gnu_debug
variables: variables:
BUILD_TARGET: linux64_fuzz BUILD_TARGET: linux64_fuzz
@ -279,7 +284,7 @@ linux64_fuzz-build:
# - .build-template # - .build-template
# - .skip-in-fast-mode-template # - .skip-in-fast-mode-template
# needs: # needs:
# - x86_64-pc-linux-gnu-debug # - x86_64-pc-linux-gnu_debug
# variables: # variables:
# BUILD_TARGET: linux64_asan # BUILD_TARGET: linux64_asan
@ -288,7 +293,7 @@ linux64_tsan-build:
- .build-template - .build-template
- .skip-in-fast-mode-template - .skip-in-fast-mode-template
needs: needs:
- x86_64-pc-linux-gnu-debug - x86_64-pc-linux-gnu_debug
variables: variables:
BUILD_TARGET: linux64_tsan BUILD_TARGET: linux64_tsan
@ -297,7 +302,7 @@ linux64_ubsan-build:
- .build-template - .build-template
- .skip-in-fast-mode-template - .skip-in-fast-mode-template
needs: needs:
- x86_64-pc-linux-gnu-debug - x86_64-pc-linux-gnu_debug
variables: variables:
BUILD_TARGET: linux64_ubsan BUILD_TARGET: linux64_ubsan
@ -306,7 +311,7 @@ linux64_nowallet-build:
- .build-template - .build-template
- .skip-in-fast-mode-template - .skip-in-fast-mode-template
needs: needs:
- x86_64-pc-linux-gnu-nowallet - x86_64-pc-linux-gnu_nowallet
variables: variables:
BUILD_TARGET: linux64_nowallet BUILD_TARGET: linux64_nowallet
@ -315,7 +320,7 @@ linux64_multiprocess-build:
- .build-template - .build-template
- .skip-in-fast-mode-template - .skip-in-fast-mode-template
needs: needs:
- x86_64-pc-linux-gnu-multiprocess - x86_64-pc-linux-gnu_multiprocess
variables: variables:
BUILD_TARGET: linux64_multiprocess BUILD_TARGET: linux64_multiprocess
@ -324,10 +329,11 @@ linux64_multiprocess-build:
# - .build-template # - .build-template
# - .skip-in-fast-mode-template # - .skip-in-fast-mode-template
# needs: # needs:
# - x86_64-pc-linux-gnu-debug # - x86_64-pc-linux-gnu_debug
# variables: # variables:
# BUILD_TARGET: linux64_valgrind # BUILD_TARGET: linux64_valgrind
mac-build: mac-build:
extends: extends:
- .build-template - .build-template
@ -336,6 +342,14 @@ mac-build:
- x86_64-apple-darwin - x86_64-apple-darwin
variables: variables:
BUILD_TARGET: mac BUILD_TARGET: mac
arm-mac-build:
extends:
- .build-template
- .skip-in-fast-mode-template
needs:
- aarch64-apple-darwin
variables:
BUILD_TARGET: arm-mac
### ###

View File

@ -18,28 +18,32 @@ export UBSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/
if [ "$BUILD_TARGET" = "arm-linux" ]; then if [ "$BUILD_TARGET" = "arm-linux" ]; then
source ./ci/test/00_setup_env_arm.sh source ./ci/test/00_setup_env_arm.sh
elif [ "$BUILD_TARGET" = "win64" ]; then
source ./ci/test/00_setup_env_win64.sh
elif [ "$BUILD_TARGET" = "linux64" ]; then elif [ "$BUILD_TARGET" = "linux64" ]; then
source ./ci/test/00_setup_env_native_qt5.sh source ./ci/test/00_setup_env_native_qt5.sh
elif [ "$BUILD_TARGET" = "linux64_asan" ]; then elif [ "$BUILD_TARGET" = "linux64_asan" ]; then
source ./ci/test/00_setup_env_native_asan.sh source ./ci/test/00_setup_env_native_asan.sh
elif [ "$BUILD_TARGET" = "linux64_cxx20" ]; then
source ./ci/test/00_setup_env_native_cxx20.sh
elif [ "$BUILD_TARGET" = "linux64_fuzz" ]; then
source ./ci/test/00_setup_env_native_fuzz.sh
elif [ "$BUILD_TARGET" = "linux64_multiprocess" ]; then
source ./ci/test/00_setup_env_native_multiprocess.sh
elif [ "$BUILD_TARGET" = "linux64_nowallet" ]; then
source ./ci/test/00_setup_env_native_nowallet.sh
elif [ "$BUILD_TARGET" = "linux64_sqlite" ]; then
source ./ci/test/00_setup_env_native_sqlite.sh
elif [ "$BUILD_TARGET" = "linux64_tsan" ]; then elif [ "$BUILD_TARGET" = "linux64_tsan" ]; then
source ./ci/test/00_setup_env_native_tsan.sh source ./ci/test/00_setup_env_native_tsan.sh
elif [ "$BUILD_TARGET" = "linux64_ubsan" ]; then elif [ "$BUILD_TARGET" = "linux64_ubsan" ]; then
source ./ci/test/00_setup_env_native_ubsan.sh source ./ci/test/00_setup_env_native_ubsan.sh
elif [ "$BUILD_TARGET" = "linux64_fuzz" ]; then
source ./ci/test/00_setup_env_native_fuzz.sh
elif [ "$BUILD_TARGET" = "linux64_cxx20" ]; then
source ./ci/test/00_setup_env_native_cxx20.sh
elif [ "$BUILD_TARGET" = "linux64_sqlite" ]; then
source ./ci/test/00_setup_env_native_sqlite.sh
elif [ "$BUILD_TARGET" = "linux64_nowallet" ]; then
source ./ci/test/00_setup_env_native_nowallet.sh
elif [ "$BUILD_TARGET" = "linux64_valgrind" ]; then elif [ "$BUILD_TARGET" = "linux64_valgrind" ]; then
source ./ci/test/00_setup_env_native_valgrind.sh source ./ci/test/00_setup_env_native_valgrind.sh
elif [ "$BUILD_TARGET" = "mac" ]; then elif [ "$BUILD_TARGET" = "mac" ]; then
source ./ci/test/00_setup_env_mac.sh source ./ci/test/00_setup_env_mac.sh
elif [ "$BUILD_TARGET" = "arm-mac" ]; then
source ./ci/test/00_setup_env_mac.sh
elif [ "$BUILD_TARGET" = "s390x" ]; then elif [ "$BUILD_TARGET" = "s390x" ]; then
source ./ci/test/00_setup_env_s390x.sh source ./ci/test/00_setup_env_s390x.sh
elif [ "$BUILD_TARGET" = "win64" ]; then
source ./ci/test/00_setup_env_win64.sh
fi fi

View File

@ -42,7 +42,7 @@ echo "Using socketevents mode: $SOCKETEVENTS"
EXTRA_ARGS="--dashd-arg=-socketevents=$SOCKETEVENTS" EXTRA_ARGS="--dashd-arg=-socketevents=$SOCKETEVENTS"
set +e set +e
LD_LIBRARY_PATH=$DEPENDS_DIR/$HOST/lib ${TEST_RUNNER_ENV} ./test/functional/test_runner.py --ci --attempts=3 --ansi --combinedlogslen=4000 --timeout-factor=${TEST_RUNNER_TIMEOUT_FACTOR} ${TEST_RUNNER_EXTRA} --failfast --nocleanup --tmpdir=$(pwd)/testdatadirs $PASS_ARGS $EXTRA_ARGS LD_LIBRARY_PATH=$DEPENDS_DIR/$HOST/lib ./test/functional/test_runner.py --ci --attempts=3 --ansi --combinedlogslen=4000 --timeout-factor=${TEST_RUNNER_TIMEOUT_FACTOR} ${TEST_RUNNER_EXTRA} --failfast --nocleanup --tmpdir=$(pwd)/testdatadirs $PASS_ARGS $EXTRA_ARGS
RESULT=$? RESULT=$?
set -e set -e

View File

@ -29,8 +29,8 @@ if [ "$DIRECT_WINE_EXEC_TESTS" = "true" ]; then
wine ./src/test/test_dash.exe wine ./src/test/test_dash.exe
else else
if [ "$RUN_UNIT_TESTS_SEQUENTIAL" = "true" ]; then if [ "$RUN_UNIT_TESTS_SEQUENTIAL" = "true" ]; then
${TEST_RUNNER_ENV} ./src/test/test_dash --catch_system_errors=no -l test_suite ./src/test/test_dash --catch_system_errors=no -l test_suite
else else
${TEST_RUNNER_ENV} make $MAKEJOBS check VERBOSE=1 make $MAKEJOBS check VERBOSE=1
fi fi
fi fi

View File

@ -43,7 +43,6 @@ export RUN_SECURITY_TESTS=${RUN_SECURITY_TESTS:-false}
# This is needed because some ci machines have slow CPU or disk, so sanitizers # This is needed because some ci machines have slow CPU or disk, so sanitizers
# might be slow or a reindex might be waiting on disk IO. # might be slow or a reindex might be waiting on disk IO.
export TEST_RUNNER_TIMEOUT_FACTOR=${TEST_RUNNER_TIMEOUT_FACTOR:-4} export TEST_RUNNER_TIMEOUT_FACTOR=${TEST_RUNNER_TIMEOUT_FACTOR:-4}
export TEST_RUNNER_ENV=${TEST_RUNNER_ENV:-}
export RUN_FUZZ_TESTS=${RUN_FUZZ_TESTS:-false} export RUN_FUZZ_TESTS=${RUN_FUZZ_TESTS:-false}
export EXPECTED_TESTS_DURATION_IN_SECONDS=${EXPECTED_TESTS_DURATION_IN_SECONDS:-1000} export EXPECTED_TESTS_DURATION_IN_SECONDS=${EXPECTED_TESTS_DURATION_IN_SECONDS:-1000}

17
ci/test/00_setup_env_arm_mac.sh Executable file
View File

@ -0,0 +1,17 @@
#!/usr/bin/env bash
#
# Copyright (c) 2019-2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
export LC_ALL=C.UTF-8
export CONTAINER_NAME=ci_arm-macos_cross
export HOST=aarch64-apple-darwin
export PACKAGES="cmake libcap-dev libz-dev libbz2-dev python3-dev python3-setuptools"
export XCODE_VERSION=12.2
export XCODE_BUILD_ID=12B45b
export RUN_UNIT_TESTS=false
export RUN_INTEGRATION_TESTS=false
export GOAL="all deploy"
export BITCOIN_CONFIG="--enable-gui --enable-reduce-exports --disable-miner --enable-werror"

View File

@ -0,0 +1,19 @@
#!/usr/bin/env bash
#
# Copyright (c) 2019-2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
export LC_ALL=C.UTF-8
export CONTAINER_NAME=ci_arm-macos
export HOST=aarch64-apple-darwin
export PIP_PACKAGES="zmq lief"
export RUN_UNIT_TESTS=true
export RUN_INTEGRATION_TESTS=false
export RUN_SECURITY_TESTS="true"
export GOAL="install"
export BITCOIN_CONFIG="--enable-gui --enable-reduce-exports --disable-miner --enable-werror"
# Run without depends
export NO_DEPENDS=1
export OSX_SDK=""

View File

@ -11,5 +11,5 @@ export PACKAGES="cmake python3 llvm clang"
export DEP_OPTS="DEBUG=1 MULTIPROCESS=1" export DEP_OPTS="DEBUG=1 MULTIPROCESS=1"
export GOAL="install" export GOAL="install"
export TEST_RUNNER_EXTRA="--v2transport" export TEST_RUNNER_EXTRA="--v2transport"
export BITCOIN_CONFIG="--with-boost-process --enable-debug CC=clang CXX=clang++" # Use clang to avoid OOM export BITCOIN_CONFIG="--with-boost-process --enable-debug CC=clang-16 CXX=clang++-16" # Use clang to avoid OOM
export TEST_RUNNER_ENV="BITCOIND=dash-node" export BITCOIND=dash-node # Used in functional tests

View File

@ -19,7 +19,6 @@ fi
# Use debian to avoid 404 apt errors # Use debian to avoid 404 apt errors
export CONTAINER_NAME=ci_s390x export CONTAINER_NAME=ci_s390x
export RUN_UNIT_TESTS=true export RUN_UNIT_TESTS=true
export TEST_RUNNER_ENV="LC_ALL=C"
export RUN_FUNCTIONAL_TESTS=true export RUN_FUNCTIONAL_TESTS=true
export GOAL="install" export GOAL="install"
export BITCOIN_CONFIG="--enable-reduce-exports --disable-gui-tests --with-boost-process" # GUI tests disabled for now, see https://github.com/bitcoin/bitcoin/issues/23730 export BITCOIN_CONFIG="--enable-reduce-exports --disable-gui-tests --with-boost-process" # GUI tests disabled for now, see https://github.com/bitcoin/bitcoin/issues/23730

View File

@ -159,9 +159,15 @@ $(package)_config_opts_linux += -dbus-runtime
ifneq ($(LTO),) ifneq ($(LTO),)
$(package)_config_opts_linux += -ltcg $(package)_config_opts_linux += -ltcg
endif endif
$(package)_config_opts_linux += -platform linux-g++ -xplatform bitcoin-linux-g++
ifneq (,$(findstring -stdlib=libc++,$($(1)_cxx))) ifneq (,$(findstring clang,$($(package)_cxx)))
$(package)_config_opts_x86_64_linux = -xplatform linux-clang-libc++ ifneq (,$(findstring -stdlib=libc++,$($(package)_cxx)))
$(package)_config_opts_linux += -platform linux-clang-libc++ -xplatform linux-clang-libc++
else
$(package)_config_opts_linux += -platform linux-clang -xplatform linux-clang
endif
else
$(package)_config_opts_linux += -platform linux-g++ -xplatform bitcoin-linux-g++
endif endif
$(package)_config_opts_mingw32 = -no-opengl $(package)_config_opts_mingw32 = -no-opengl

View File

@ -220,6 +220,16 @@ static void MutateTxLocktime(CMutableTransaction& tx, const std::string& cmdVal)
tx.nLockTime = (unsigned int) newLocktime; tx.nLockTime = (unsigned int) newLocktime;
} }
template <typename T>
static T TrimAndParse(const std::string& int_str, const std::string& err)
{
const auto parsed{ToIntegral<T>(TrimString(int_str))};
if (!parsed.has_value()) {
throw std::runtime_error(err + " '" + int_str + "'");
}
return parsed.value();
}
static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInput) static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInput)
{ {
std::vector<std::string> vStrInputParts = SplitString(strInput, ':'); std::vector<std::string> vStrInputParts = SplitString(strInput, ':');
@ -245,8 +255,9 @@ static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInpu
// extract the optional sequence number // extract the optional sequence number
uint32_t nSequenceIn = CTxIn::SEQUENCE_FINAL; uint32_t nSequenceIn = CTxIn::SEQUENCE_FINAL;
if (vStrInputParts.size() > 2) if (vStrInputParts.size() > 2) {
nSequenceIn = std::stoul(vStrInputParts[2]); nSequenceIn = TrimAndParse<uint32_t>(vStrInputParts.at(2), "invalid TX sequence id");
}
// append to transaction input list // append to transaction input list
CTxIn txin(txid, vout, CScript(), nSequenceIn); CTxIn txin(txid, vout, CScript(), nSequenceIn);
@ -324,10 +335,10 @@ static void MutateTxAddOutMultiSig(CMutableTransaction& tx, const std::string& s
CAmount value = ExtractAndValidateValue(vStrInputParts[0]); CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
// Extract REQUIRED // Extract REQUIRED
uint32_t required = stoul(vStrInputParts[1]); const uint32_t required{TrimAndParse<uint32_t>(vStrInputParts.at(1), "invalid multisig required number")};
// Extract NUMKEYS // Extract NUMKEYS
uint32_t numkeys = stoul(vStrInputParts[2]); const uint32_t numkeys{TrimAndParse<uint32_t>(vStrInputParts.at(2), "invalid multisig total number")};
// Validate there are the correct number of pubkeys // Validate there are the correct number of pubkeys
if (vStrInputParts.size() < numkeys + 3) if (vStrInputParts.size() < numkeys + 3)

View File

@ -314,8 +314,8 @@ void CRollingBloomFilter::insert(Span<const unsigned char> vKey)
/* FastMod works with the upper bits of h, so it is safe to ignore that the lower bits of h are already used for bit. */ /* FastMod works with the upper bits of h, so it is safe to ignore that the lower bits of h are already used for bit. */
uint32_t pos = FastRange32(h, data.size()); uint32_t pos = FastRange32(h, data.size());
/* The lowest bit of pos is ignored, and set to zero for the first bit, and to one for the second. */ /* The lowest bit of pos is ignored, and set to zero for the first bit, and to one for the second. */
data[pos & ~1] = (data[pos & ~1] & ~(((uint64_t)1) << bit)) | ((uint64_t)(nGeneration & 1)) << bit; data[pos & ~1U] = (data[pos & ~1U] & ~(uint64_t{1} << bit)) | (uint64_t(nGeneration & 1)) << bit;
data[pos | 1] = (data[pos | 1] & ~(((uint64_t)1) << bit)) | ((uint64_t)(nGeneration >> 1)) << bit; data[pos | 1] = (data[pos | 1] & ~(uint64_t{1} << bit)) | (uint64_t(nGeneration >> 1)) << bit;
} }
} }
@ -326,7 +326,7 @@ bool CRollingBloomFilter::contains(Span<const unsigned char> vKey) const
int bit = h & 0x3F; int bit = h & 0x3F;
uint32_t pos = FastRange32(h, data.size()); uint32_t pos = FastRange32(h, data.size());
/* If the relevant bit is not set in either data[pos & ~1] or data[pos | 1], the filter does not contain vKey */ /* If the relevant bit is not set in either data[pos & ~1] or data[pos | 1], the filter does not contain vKey */
if (!(((data[pos & ~1] | data[pos | 1]) >> bit) & 1)) { if (!(((data[pos & ~1U] | data[pos | 1]) >> bit) & 1)) {
return false; return false;
} }
} }

View File

@ -44,6 +44,7 @@
#endif // ENABLE_WALLET #endif // ENABLE_WALLET
#include <boost/signals2/connection.hpp> #include <boost/signals2/connection.hpp>
#include <chrono>
#include <memory> #include <memory>
#include <QApplication> #include <QApplication>
@ -397,10 +398,10 @@ void BitcoinApplication::initializeResult(bool success, interfaces::BlockAndHead
connect(paymentServer, &PaymentServer::message, [this](const QString& title, const QString& message, unsigned int style) { connect(paymentServer, &PaymentServer::message, [this](const QString& title, const QString& message, unsigned int style) {
window->message(title, message, style); window->message(title, message, style);
}); });
QTimer::singleShot(100, paymentServer, &PaymentServer::uiReady); QTimer::singleShot(100ms, paymentServer, &PaymentServer::uiReady);
} }
#endif #endif
pollShutdownTimer->start(200); pollShutdownTimer->start(SHUTDOWN_POLLING_DELAY);
} else { } else {
Q_EMIT splashFinished(); // Make sure splash screen doesn't stick around during shutdown Q_EMIT splashFinished(); // Make sure splash screen doesn't stick around during shutdown
quit(); // Exit first main loop invocation quit(); // Exit first main loop invocation

View File

@ -21,6 +21,7 @@
#include <netbase.h> #include <netbase.h>
#include <util/system.h> #include <util/system.h>
#include <util/threadnames.h> #include <util/threadnames.h>
#include <util/time.h>
#include <validation.h> #include <validation.h>
#include <stdint.h> #include <stdint.h>
@ -323,7 +324,7 @@ static void BlockTipChanged(ClientModel* clientmodel, SynchronizationState sync_
const bool throttle = (sync_state != SynchronizationState::POST_INIT && !fHeader) || sync_state == SynchronizationState::INIT_REINDEX; const bool throttle = (sync_state != SynchronizationState::POST_INIT && !fHeader) || sync_state == SynchronizationState::INIT_REINDEX;
const int64_t now = throttle ? GetTimeMillis() : 0; const int64_t now = throttle ? GetTimeMillis() : 0;
int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification; int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;
if (throttle && now < nLastUpdateNotification + MODEL_UPDATE_DELAY) { if (throttle && now < nLastUpdateNotification + count_milliseconds(MODEL_UPDATE_DELAY)) {
return; return;
} }

View File

@ -6,10 +6,16 @@
#ifndef BITCOIN_QT_GUICONSTANTS_H #ifndef BITCOIN_QT_GUICONSTANTS_H
#define BITCOIN_QT_GUICONSTANTS_H #define BITCOIN_QT_GUICONSTANTS_H
#include <chrono>
#include <cstdint> #include <cstdint>
/* Milliseconds between model updates */ using namespace std::chrono_literals;
static const int MODEL_UPDATE_DELAY = 250;
/* A delay between model updates */
static constexpr auto MODEL_UPDATE_DELAY{250ms};
/* A delay between shutdown pollings */
static constexpr auto SHUTDOWN_POLLING_DELAY{200ms};
/* AskPassphraseDialog -- Maximum passphrase length */ /* AskPassphraseDialog -- Maximum passphrase length */
static const int MAX_PASSPHRASE_SIZE = 1024; static const int MAX_PASSPHRASE_SIZE = 1024;

View File

@ -24,6 +24,8 @@
#include <util/underlying.h> #include <util/underlying.h>
#include <QButtonGroup> #include <QButtonGroup>
#include <chrono>
#include <QDataWidgetMapper> #include <QDataWidgetMapper>
#include <QDir> #include <QDir>
#include <QIntValidator> #include <QIntValidator>
@ -457,7 +459,7 @@ void OptionsDialog::showRestartWarning(bool fPersistent)
ui->statusLabel->setText(tr("This change would require a client restart.")); ui->statusLabel->setText(tr("This change would require a client restart."));
// clear non-persistent status label after 10 seconds // clear non-persistent status label after 10 seconds
// Todo: should perhaps be a class attribute, if we extend the use of statusLabel // Todo: should perhaps be a class attribute, if we extend the use of statusLabel
QTimer::singleShot(10000, this, &OptionsDialog::clearStatusLabel); QTimer::singleShot(10s, this, &OptionsDialog::clearStatusLabel);
} }
} }

View File

@ -24,10 +24,11 @@
#include <node/interface_ui.h> #include <node/interface_ui.h>
#include <policy/fees.h> #include <policy/fees.h>
#include <txmempool.h> #include <txmempool.h>
#include <validation.h>
#include <wallet/coincontrol.h> #include <wallet/coincontrol.h>
#include <wallet/fees.h> #include <wallet/fees.h>
#include <wallet/wallet.h> #include <wallet/wallet.h>
#include <validation.h> #include <chrono>
#include <array> #include <array>
#include <fstream> #include <fstream>
@ -1080,7 +1081,7 @@ SendConfirmationDialog::SendConfirmationDialog(const QString& title, const QStri
int SendConfirmationDialog::exec() int SendConfirmationDialog::exec()
{ {
updateYesButton(); updateYesButton();
countDownTimer.start(1000); countDownTimer.start(1s);
return QMessageBox::exec(); return QMessageBox::exec();
} }

View File

@ -19,6 +19,8 @@
#include <wallet/wallet.h> #include <wallet/wallet.h>
#include <walletinitinterface.h> #include <walletinitinterface.h>
#include <chrono>
#include <QApplication> #include <QApplication>
#include <QTimer> #include <QTimer>
#include <QMessageBox> #include <QMessageBox>
@ -39,7 +41,7 @@ void EditAddressAndSubmit(
dialog->findChild<QLineEdit*>("labelEdit")->setText(label); dialog->findChild<QLineEdit*>("labelEdit")->setText(label);
dialog->findChild<QValidatedLineEdit*>("addressEdit")->setText(address); dialog->findChild<QValidatedLineEdit*>("addressEdit")->setText(address);
ConfirmMessage(&warning_text, 5); ConfirmMessage(&warning_text, 5ms);
dialog->accept(); dialog->accept();
QCOMPARE(warning_text, expected_msg); QCOMPARE(warning_text, expected_msg);
} }

View File

@ -2,6 +2,8 @@
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <chrono>
#include <QApplication> #include <QApplication>
#include <QMessageBox> #include <QMessageBox>
#include <QPushButton> #include <QPushButton>
@ -9,7 +11,7 @@
#include <QTimer> #include <QTimer>
#include <QWidget> #include <QWidget>
void ConfirmMessage(QString* text, int msec) void ConfirmMessage(QString* text, std::chrono::milliseconds msec)
{ {
QTimer::singleShot(msec, [text]() { QTimer::singleShot(msec, [text]() {
for (QWidget* widget : QApplication::topLevelWidgets()) { for (QWidget* widget : QApplication::topLevelWidgets()) {

View File

@ -5,7 +5,11 @@
#ifndef BITCOIN_QT_TEST_UTIL_H #ifndef BITCOIN_QT_TEST_UTIL_H
#define BITCOIN_QT_TEST_UTIL_H #define BITCOIN_QT_TEST_UTIL_H
#include <QString> #include <chrono>
QT_BEGIN_NAMESPACE
class QString;
QT_END_NAMESPACE
/** /**
* Press "Ok" button in message box dialog. * Press "Ok" button in message box dialog.
@ -13,6 +17,6 @@
* @param text - Optionally store dialog text. * @param text - Optionally store dialog text.
* @param msec - Number of milliseconds to pause before triggering the callback. * @param msec - Number of milliseconds to pause before triggering the callback.
*/ */
void ConfirmMessage(QString* text = nullptr, int msec = 0); void ConfirmMessage(QString* text, std::chrono::milliseconds msec);
#endif // BITCOIN_QT_TEST_UTIL_H #endif // BITCOIN_QT_TEST_UTIL_H

View File

@ -25,6 +25,7 @@
#include <qt/recentrequeststablemodel.h> #include <qt/recentrequeststablemodel.h>
#include <qt/receiverequestdialog.h> #include <qt/receiverequestdialog.h>
#include <chrono>
#include <memory> #include <memory>
#include <QAbstractButton> #include <QAbstractButton>

View File

@ -23,6 +23,7 @@
#include <optional> #include <optional>
#include <QCalendarWidget> #include <QCalendarWidget>
#include <chrono>
#include <QComboBox> #include <QComboBox>
#include <QDateTimeEdit> #include <QDateTimeEdit>
#include <QDesktopServices> #include <QDesktopServices>
@ -114,8 +115,8 @@ TransactionView::TransactionView(QWidget* parent) :
amountWidget->setObjectName("amountWidget"); amountWidget->setObjectName("amountWidget");
hlayout->addWidget(amountWidget); hlayout->addWidget(amountWidget);
// Delay before filtering transactions in ms // Delay before filtering transactions
static const int input_filter_delay = 200; static constexpr auto input_filter_delay{200ms};
QTimer* amount_typing_delay = new QTimer(this); QTimer* amount_typing_delay = new QTimer(this);
amount_typing_delay->setSingleShot(true); amount_typing_delay->setSingleShot(true);

View File

@ -21,6 +21,7 @@
#include <wallet/wallet.h> #include <wallet/wallet.h>
#include <algorithm> #include <algorithm>
#include <chrono>
#include <QApplication> #include <QApplication>
#include <QMessageBox> #include <QMessageBox>
@ -271,12 +272,12 @@ void CreateWalletActivity::createWallet()
flags |= WALLET_FLAG_DESCRIPTORS; flags |= WALLET_FLAG_DESCRIPTORS;
} }
QTimer::singleShot(500, worker(), [this, name, flags] { QTimer::singleShot(500ms, worker(), [this, name, flags] {
std::unique_ptr<interfaces::Wallet> wallet = node().walletLoader().createWallet(name, m_passphrase, flags, m_error_message, m_warning_message); std::unique_ptr<interfaces::Wallet> wallet = node().walletLoader().createWallet(name, m_passphrase, flags, m_error_message, m_warning_message);
if (wallet) m_wallet_model = m_wallet_controller->getOrCreateWallet(std::move(wallet)); if (wallet) m_wallet_model = m_wallet_controller->getOrCreateWallet(std::move(wallet));
QTimer::singleShot(500, this, &CreateWalletActivity::finish); QTimer::singleShot(500ms, this, &CreateWalletActivity::finish);
}); });
} }

View File

@ -874,29 +874,30 @@ static RPCHelpMan decoderawtransaction()
static RPCHelpMan decodescript() static RPCHelpMan decodescript()
{ {
return RPCHelpMan{"decodescript", return RPCHelpMan{
"\nDecode a hex-encoded script.\n", "decodescript",
{ "\nDecode a hex-encoded script.\n",
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded script"}, {
}, {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded script"},
RPCResult{ },
RPCResult::Type::OBJ, "", "", RPCResult{
RPCResult::Type::OBJ, "", "",
{
{RPCResult::Type::STR, "asm", "Script public key"},
{RPCResult::Type::STR, "type", "The output type (e.g. " + GetAllOutputTypes() + ")"},
{RPCResult::Type::STR, "address", /* optional */ true, "Dash address (only if a well-defined address exists)"},
{RPCResult::Type::NUM, "reqSigs", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Number of required signatures"},
{RPCResult::Type::ARR, "addresses", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Array of Dash addresses",
{ {
{RPCResult::Type::STR, "asm", "Script public key"}, {RPCResult::Type::STR, "address", "Dash address"},
{RPCResult::Type::STR, "type", "The output type (e.g. "+GetAllOutputTypes()+")"}, }},
{RPCResult::Type::STR, "address", /* optional */ true, "Dash address (only if a well-defined address exists)"}, {RPCResult::Type::STR, "p2sh", "address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH)"},
{RPCResult::Type::NUM, "reqSigs", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Number of required signatures"}, },
{RPCResult::Type::ARR, "addresses", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Array of Dash addresses", },
{ RPCExamples{
{RPCResult::Type::STR, "address", "Dash address"}, HelpExampleCli("decodescript", "\"hexstring\"")
}}, + HelpExampleRpc("decodescript", "\"hexstring\"")
{RPCResult::Type::STR, "p2sh", "address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH)"}, },
}
},
RPCExamples{
HelpExampleCli("decodescript", "\"hexstring\"")
+ HelpExampleRpc("decodescript", "\"hexstring\"")
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{ {
RPCTypeCheck(request.params, {UniValue::VSTR}); RPCTypeCheck(request.params, {UniValue::VSTR});
@ -911,11 +912,10 @@ static RPCHelpMan decodescript()
} }
ScriptPubKeyToUniv(script, r, /* fIncludeHex */ false); ScriptPubKeyToUniv(script, r, /* fIncludeHex */ false);
UniValue type; std::vector<std::vector<unsigned char>> solutions_data;
const TxoutType which_type{Solver(script, solutions_data)};
type = find_value(r, "type"); if (which_type != TxoutType::SCRIPTHASH) {
if (type.isStr() && type.get_str() != "scripthash") {
// P2SH cannot be wrapped in a P2SH. If this script is already a P2SH, // P2SH cannot be wrapped in a P2SH. If this script is already a P2SH,
// don't return the address for a P2SH of the P2SH. // don't return the address for a P2SH of the P2SH.
r.pushKV("p2sh", EncodeDestination(ScriptHash(script))); r.pushKV("p2sh", EncodeDestination(ScriptHash(script)));

View File

@ -461,7 +461,7 @@ ssize_t FuzzedFileProvider::write(void* cookie, const char* buf, size_t size)
SetFuzzedErrNo(fuzzed_file->m_fuzzed_data_provider); SetFuzzedErrNo(fuzzed_file->m_fuzzed_data_provider);
const ssize_t n = fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<ssize_t>(0, size); const ssize_t n = fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<ssize_t>(0, size);
if (AdditionOverflow(fuzzed_file->m_offset, (int64_t)n)) { if (AdditionOverflow(fuzzed_file->m_offset, (int64_t)n)) {
return fuzzed_file->m_fuzzed_data_provider.ConsumeBool() ? 0 : -1; return 0;
} }
fuzzed_file->m_offset += n; fuzzed_file->m_offset += n;
return n; return n;

View File

@ -6,8 +6,11 @@
from decimal import Decimal from decimal import Decimal
from test_framework.blocktools import COINBASE_MATURITY
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, assert_greater_than, assert_raises_rpc_error, create_confirmed_utxos, create_lots_of_big_transactions, gen_return_txouts from test_framework.util import assert_equal, assert_greater_than, assert_raises_rpc_error, gen_return_txouts
from test_framework.wallet import MiniWallet
class MempoolLimitTest(BitcoinTestFramework): class MempoolLimitTest(BitcoinTestFramework):
def set_test_params(self): def set_test_params(self):
@ -20,55 +23,59 @@ class MempoolLimitTest(BitcoinTestFramework):
]] ]]
self.supports_cli = False self.supports_cli = False
def skip_test_if_missing_module(self): def send_large_txs(self, node, miniwallet, txouts, fee_rate, tx_batch_size):
self.skip_if_no_wallet() for _ in range(tx_batch_size):
tx = miniwallet.create_self_transfer(from_node=node, fee_rate=fee_rate)['tx']
for txout in txouts:
tx.vout.append(txout)
miniwallet.sendrawtransaction(from_node=node, tx_hex=tx.serialize().hex())
def run_test(self): def run_test(self):
txouts = gen_return_txouts() txouts = gen_return_txouts()
relayfee = self.nodes[0].getnetworkinfo()['relayfee'] node=self.nodes[0]
miniwallet = MiniWallet(node)
relayfee = node.getnetworkinfo()['relayfee']
self.log.info('Check that mempoolminfee is minrelytxfee') self.log.info('Check that mempoolminfee is minrelaytxfee')
assert_equal(self.nodes[0].getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000')) assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000'))
assert_equal(self.nodes[0].getmempoolinfo()['mempoolminfee'], Decimal('0.00001000')) assert_equal(node.getmempoolinfo()['mempoolminfee'], Decimal('0.00001000'))
txids = [] tx_batch_size = 25
utxos = create_confirmed_utxos(self, relayfee, self.nodes[0], 491) num_of_batches = 3
# Generate UTXOs to flood the mempool
# 1 to create a tx initially that will be evicted from the mempool later
# 3 batches of multiple transactions with a fee rate much higher than the previous UTXO
# And 1 more to verify that this tx does not get added to the mempool with a fee rate less than the mempoolminfee
self.generate(miniwallet, 1 + (num_of_batches * tx_batch_size) + 1)
# Mine 99 blocks so that the UTXOs are allowed to be spent
self.generate(node, COINBASE_MATURITY - 1)
self.log.info('Create a mempool tx that will be evicted') self.log.info('Create a mempool tx that will be evicted')
us0 = utxos.pop() tx_to_be_evicted_id = miniwallet.send_self_transfer(from_node=node, fee_rate=relayfee)["txid"]
inputs = [{ "txid" : us0["txid"], "vout" : us0["vout"]}]
outputs = {self.nodes[0].getnewaddress() : 0.0001}
tx = self.nodes[0].createrawtransaction(inputs, outputs)
self.nodes[0].settxfee(relayfee) # specifically fund this tx with low fee
txF = self.nodes[0].fundrawtransaction(tx)
self.nodes[0].settxfee(0) # return to automatic fee selection
txFS = self.nodes[0].signrawtransactionwithwallet(txF['hex'])
txid = self.nodes[0].sendrawtransaction(txFS['hex'])
relayfee = self.nodes[0].getnetworkinfo()['relayfee'] # Increase the tx fee rate massively to give the subsequent transactions a higher priority in the mempool
base_fee = relayfee*100 base_fee = relayfee * 1000
for i in range (3):
txids.append([]) self.log.info("Fill up the mempool with txs with higher fee rate")
txids[i] = create_lots_of_big_transactions(self.nodes[0], txouts, utxos[30*i:30*i+30], 30, (i+1)*base_fee) for batch_of_txid in range(num_of_batches):
fee_rate=(batch_of_txid + 1) * base_fee
self.send_large_txs(node, miniwallet, txouts, fee_rate, tx_batch_size)
self.log.info('The tx should be evicted by now') self.log.info('The tx should be evicted by now')
assert txid not in self.nodes[0].getrawmempool() # The number of transactions created should be greater than the ones present in the mempool
txdata = self.nodes[0].gettransaction(txid) assert_greater_than(tx_batch_size * num_of_batches, len(node.getrawmempool()))
assert txdata['confirmations'] == 0 #confirmation should still be 0 # Initial tx created should not be present in the mempool anymore as it had a lower fee rate
assert tx_to_be_evicted_id not in node.getrawmempool()
self.log.info('Check that mempoolminfee is larger than minrelytxfee') self.log.info('Check that mempoolminfee is larger than minrelaytxfee')
assert_equal(self.nodes[0].getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000')) assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000'))
assert_greater_than(self.nodes[0].getmempoolinfo()['mempoolminfee'], Decimal('0.00001000')) assert_greater_than(node.getmempoolinfo()['mempoolminfee'], Decimal('0.00001000'))
# Deliberately try to create a tx with a fee less than the minimum mempool fee to assert that it does not get added to the mempool
self.log.info('Create a mempool tx that will not pass mempoolminfee') self.log.info('Create a mempool tx that will not pass mempoolminfee')
us0 = utxos.pop() assert_raises_rpc_error(-26, "mempool min fee not met", miniwallet.send_self_transfer, from_node=node, fee_rate=relayfee, mempool_valid=False)
inputs = [{ "txid" : us0["txid"], "vout" : us0["vout"]}]
outputs = {self.nodes[0].getnewaddress() : 0.0001}
tx = self.nodes[0].createrawtransaction(inputs, outputs)
# specifically fund this tx with a fee < mempoolminfee, >= than minrelaytxfee
txF = self.nodes[0].fundrawtransaction(tx, {'feeRate': relayfee})
txFS = self.nodes[0].signrawtransactionwithwallet(txF['hex'])
assert_raises_rpc_error(-26, "mempool min fee not met", self.nodes[0].sendrawtransaction, txFS['hex'])
if __name__ == '__main__': if __name__ == '__main__':
MempoolLimitTest().main() MempoolLimitTest().main()

View File

@ -3,14 +3,26 @@
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
import random
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal from test_framework.messages import (
COIN,
MAX_MONEY,
uint256_to_string,
)
from test_framework.util import (
assert_equal,
assert_is_hex_string,
assert_raises_rpc_error,
)
''' # See coinjoin/options.h
rpc_coinjoin.py COINJOIN_ROUNDS_DEFAULT = 4
COINJOIN_ROUNDS_MAX = 16
Tests CoinJoin basic RPC COINJOIN_ROUNDS_MIN = 2
''' COINJOIN_TARGET_MAX = int(MAX_MONEY / COIN)
COINJOIN_TARGET_MIN = 2
class CoinJoinTest(BitcoinTestFramework): class CoinJoinTest(BitcoinTestFramework):
def set_test_params(self): def set_test_params(self):
@ -19,45 +31,128 @@ class CoinJoinTest(BitcoinTestFramework):
def skip_test_if_missing_module(self): def skip_test_if_missing_module(self):
self.skip_if_no_wallet() self.skip_if_no_wallet()
def run_test(self): def setup_nodes(self):
self.test_coinjoin_start_stop() self.add_nodes(self.num_nodes)
self.test_coinjoin_setamount() self.start_nodes()
self.test_coinjoin_setrounds()
def test_coinjoin_start_stop(self): def run_test(self):
# Start Mixing node = self.nodes[0]
self.nodes[0].coinjoin("start")
# Get CoinJoin info node.createwallet(wallet_name='w1', blank=True, disable_private_keys=False)
cj_info = self.nodes[0].getcoinjoininfo() w1 = node.get_wallet_rpc('w1')
# Ensure that it started properly self.test_salt_presence(w1)
self.test_coinjoin_start_stop(w1)
self.test_setcoinjoinamount(w1)
self.test_setcoinjoinrounds(w1)
self.test_coinjoinsalt(w1)
w1.unloadwallet()
node.createwallet(wallet_name='w2', blank=True, disable_private_keys=True)
w2 = node.get_wallet_rpc('w2')
self.test_coinjoinsalt_disabled(w2)
w2.unloadwallet()
def test_salt_presence(self, node):
self.log.info('Salt should be automatically generated in new wallet')
# Will raise exception if no salt generated
assert_is_hex_string(node.coinjoinsalt('get'))
def test_coinjoin_start_stop(self, node):
self.log.info('"coinjoin" subcommands should update mixing status')
# Start mix session and ensure it's reported
node.coinjoin('start')
cj_info = node.getcoinjoininfo()
assert_equal(cj_info['enabled'], True) assert_equal(cj_info['enabled'], True)
assert_equal(cj_info['running'], True) assert_equal(cj_info['running'], True)
# Repeated start should yield error
assert_raises_rpc_error(-32603, 'Mixing has been started already.', node.coinjoin, 'start')
# Stop mixing # Stop mix session and ensure it's reported
self.nodes[0].coinjoin("stop") node.coinjoin('stop')
# Get CoinJoin info cj_info = node.getcoinjoininfo()
cj_info = self.nodes[0].getcoinjoininfo()
# Ensure that it stopped properly
assert_equal(cj_info['enabled'], True) assert_equal(cj_info['enabled'], True)
assert_equal(cj_info['running'], False) assert_equal(cj_info['running'], False)
# Repeated stop should yield error
assert_raises_rpc_error(-32603, 'No mix session to stop', node.coinjoin, 'stop')
def test_coinjoin_setamount(self): # Reset mix session
# Try normal values assert_equal(node.coinjoin('reset'), "Mixing was reset")
self.nodes[0].setcoinjoinamount(50)
cj_info = self.nodes[0].getcoinjoininfo()
assert_equal(cj_info['max_amount'], 50)
# Try large values def test_setcoinjoinamount(self, node):
self.nodes[0].setcoinjoinamount(1200000) self.log.info('"setcoinjoinamount" should update mixing target')
cj_info = self.nodes[0].getcoinjoininfo() # Test normal and large values
assert_equal(cj_info['max_amount'], 1200000) for value in [COINJOIN_TARGET_MIN, 50, 1200000, COINJOIN_TARGET_MAX]:
node.setcoinjoinamount(value)
assert_equal(node.getcoinjoininfo()['max_amount'], value)
# Test values below minimum and above maximum
for value in [COINJOIN_TARGET_MIN - 1, COINJOIN_TARGET_MAX + 1]:
assert_raises_rpc_error(-8, "Invalid amount of DASH as mixing goal amount", node.setcoinjoinamount, value)
def test_coinjoin_setrounds(self): def test_setcoinjoinrounds(self, node):
# Try normal values self.log.info('"setcoinjoinrounds" should update mixing rounds')
self.nodes[0].setcoinjoinrounds(5) # Test acceptable values
cj_info = self.nodes[0].getcoinjoininfo() for value in [COINJOIN_ROUNDS_MIN, COINJOIN_ROUNDS_DEFAULT, COINJOIN_ROUNDS_MAX]:
assert_equal(cj_info['max_rounds'], 5) node.setcoinjoinrounds(value)
assert_equal(node.getcoinjoininfo()['max_rounds'], value)
# Test values below minimum and above maximum
for value in [COINJOIN_ROUNDS_MIN - 1, COINJOIN_ROUNDS_MAX + 1]:
assert_raises_rpc_error(-8, "Invalid number of rounds", node.setcoinjoinrounds, value)
def test_coinjoinsalt(self, node):
self.log.info('"coinjoinsalt generate" should fail if salt already present')
assert_raises_rpc_error(-32600, 'Wallet "w1" already has set CoinJoin salt!', node.coinjoinsalt, 'generate')
self.log.info('"coinjoinsalt" subcommands should succeed if no balance and not mixing')
# 'coinjoinsalt generate' should return a new salt if overwrite enabled
s1 = node.coinjoinsalt('get')
assert_equal(node.coinjoinsalt('generate', True), True)
s2 = node.coinjoinsalt('get')
assert s1 != s2
# 'coinjoinsalt get' should fetch newly generated value (i.e. new salt should persist)
node.unloadwallet('w1')
node.loadwallet('w1')
node = self.nodes[0].get_wallet_rpc('w1')
assert_equal(s2, node.coinjoinsalt('get'))
# 'coinjoinsalt set' should work with random hashes
s1 = uint256_to_string(random.getrandbits(256))
node.coinjoinsalt('set', s1)
assert_equal(s1, node.coinjoinsalt('get'))
assert s1 != s2
# 'coinjoinsalt set' shouldn't work with nonsense values
s2 = format(0, '064x')
assert_raises_rpc_error(-8, "Invalid CoinJoin salt value", node.coinjoinsalt, 'set', s2, True)
s2 = s2[0:63] + 'h'
assert_raises_rpc_error(-8, "salt must be hexadecimal string (not '%s')" % s2, node.coinjoinsalt, 'set', s2, True)
self.log.info('"coinjoinsalt generate" and "coinjoinsalt set" should fail if mixing')
# Start mix session
node.coinjoin('start')
assert_equal(node.getcoinjoininfo()['running'], True)
# 'coinjoinsalt generate' and 'coinjoinsalt set' should fail when mixing
assert_raises_rpc_error(-4, 'Wallet "w1" is currently mixing, cannot change salt!', node.coinjoinsalt, 'generate', True)
assert_raises_rpc_error(-4, 'Wallet "w1" is currently mixing, cannot change salt!', node.coinjoinsalt, 'set', s1, True)
# 'coinjoinsalt get' should still work
assert_equal(node.coinjoinsalt('get'), s1)
# Stop mix session
node.coinjoin('stop')
assert_equal(node.getcoinjoininfo()['running'], False)
# 'coinjoinsalt generate' and 'coinjoinsalt set' should start working again
assert_equal(node.coinjoinsalt('generate', True), True)
assert_equal(node.coinjoinsalt('set', s1, True), True)
def test_coinjoinsalt_disabled(self, node):
self.log.info('"coinjoinsalt" subcommands should fail if private keys disabled')
for subcommand in ['generate', 'get']:
assert_raises_rpc_error(-32600, 'Wallet "w2" has private keys disabled, cannot perform CoinJoin!', node.coinjoinsalt, subcommand)
s1 = uint256_to_string(random.getrandbits(256))
assert_raises_rpc_error(-32600, 'Wallet "w2" has private keys disabled, cannot perform CoinJoin!', node.coinjoinsalt, 'set', s1)
if __name__ == '__main__': if __name__ == '__main__':
CoinJoinTest().main() CoinJoinTest().main()

View File

@ -22,9 +22,6 @@ class InvalidAddressErrorMessageTest(BitcoinTestFramework):
self.setup_clean_chain = True self.setup_clean_chain = True
self.num_nodes = 1 self.num_nodes = 1
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
def test_validateaddress(self): def test_validateaddress(self):
node = self.nodes[0] node = self.nodes[0]
@ -50,7 +47,10 @@ class InvalidAddressErrorMessageTest(BitcoinTestFramework):
def run_test(self): def run_test(self):
self.test_validateaddress() self.test_validateaddress()
self.test_getaddressinfo()
if self.is_wallet_compiled():
self.init_wallet(node=0)
self.test_getaddressinfo()
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -473,12 +473,12 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
def import_deterministic_coinbase_privkeys(self): def import_deterministic_coinbase_privkeys(self):
for i in range(len(self.nodes)): for i in range(len(self.nodes)):
self.init_wallet(i) self.init_wallet(node=i)
def init_wallet(self, i): def init_wallet(self, *, node):
wallet_name = self.default_wallet_name if self.wallet_names is None else self.wallet_names[i] if i < len(self.wallet_names) else False wallet_name = self.default_wallet_name if self.wallet_names is None else self.wallet_names[node] if node < len(self.wallet_names) else False
if wallet_name is not False: if wallet_name is not False:
n = self.nodes[i] n = self.nodes[node]
if wallet_name is not None: if wallet_name is not None:
n.createwallet(wallet_name=wallet_name, descriptors=self.options.descriptors, load_on_startup=True) n.createwallet(wallet_name=wallet_name, descriptors=self.options.descriptors, load_on_startup=True)
n.importprivkey(privkey=n.get_deterministic_priv_key().key, label='coinbase', rescan=True) n.importprivkey(privkey=n.get_deterministic_priv_key().key, label='coinbase', rescan=True)

View File

@ -892,8 +892,6 @@ class RPCCoverage():
# Consider RPC generate covered, because it is overloaded in # Consider RPC generate covered, because it is overloaded in
# test_framework/test_node.py and not seen by the coverage check. # test_framework/test_node.py and not seen by the coverage check.
covered_cmds = set({'generate'}) covered_cmds = set({'generate'})
# TODO: implement functional tests for coinjoinsalt
covered_cmds.add('coinjoinsalt')
# TODO: implement functional tests for voteraw # TODO: implement functional tests for voteraw
covered_cmds.add('voteraw') covered_cmds.add('voteraw')
# TODO: implement functional tests for getmerkleblocks # TODO: implement functional tests for getmerkleblocks

View File

@ -135,9 +135,9 @@ class WalletBackupTest(BitcoinTestFramework):
assert os.path.exists(wallet_file) assert os.path.exists(wallet_file)
def init_three(self): def init_three(self):
self.init_wallet(0) self.init_wallet(node=0)
self.init_wallet(1) self.init_wallet(node=1)
self.init_wallet(2) self.init_wallet(node=2)
def run_test(self): def run_test(self):
self.log.info("Generating initial blockchain") self.log.info("Generating initial blockchain")

View File

@ -23,7 +23,7 @@ class ListDescriptorsTest(BitcoinTestFramework):
self.skip_if_no_sqlite() self.skip_if_no_sqlite()
# do not create any wallet by default # do not create any wallet by default
def init_wallet(self, i): def init_wallet(self, *, node):
return return
def run_test(self): def run_test(self):

View File

@ -239,5 +239,16 @@ class UpgradeWalletTest(BitcoinTestFramework):
desc_wallet = self.nodes[0].get_wallet_rpc("desc_upgrade") desc_wallet = self.nodes[0].get_wallet_rpc("desc_upgrade")
self.test_upgradewallet(desc_wallet, previous_version=120200, expected_version=120200) self.test_upgradewallet(desc_wallet, previous_version=120200, expected_version=120200)
self.log.info("Checking that descriptor wallets without privkeys do nothing, successfully")
self.nodes[0].createwallet(wallet_name="desc_upgrade_nopriv", descriptors=True, disable_private_keys=True)
desc_wallet = self.nodes[0].get_wallet_rpc("desc_upgrade_nopriv")
self.test_upgradewallet(desc_wallet, previous_version=120200, expected_version=120200)
if self.is_bdb_compiled():
self.log.info("Upgrading a wallet with private keys disabled")
self.nodes[0].createwallet(wallet_name="privkeys_disabled_upgrade", disable_private_keys=True, descriptors=False)
disabled_wallet = self.nodes[0].get_wallet_rpc("privkeys_disabled_upgrade")
self.test_upgradewallet(disabled_wallet, previous_version=120200, expected_version=120200)
if __name__ == '__main__': if __name__ == '__main__':
UpgradeWalletTest().main() UpgradeWalletTest().main()

View File

@ -48,7 +48,6 @@ implicit-integer-sign-change:*/include/c++/
implicit-integer-sign-change:*/new_allocator.h implicit-integer-sign-change:*/new_allocator.h
implicit-integer-sign-change:addrman.h implicit-integer-sign-change:addrman.h
implicit-integer-sign-change:bech32.cpp implicit-integer-sign-change:bech32.cpp
implicit-integer-sign-change:common/bloom.cpp
implicit-integer-sign-change:chain.cpp implicit-integer-sign-change:chain.cpp
implicit-integer-sign-change:chain.h implicit-integer-sign-change:chain.h
implicit-integer-sign-change:compat/stdin.cpp implicit-integer-sign-change:compat/stdin.cpp

View File

@ -425,6 +425,30 @@
"output_cmp": "txcreatedata2.json", "output_cmp": "txcreatedata2.json",
"description": "Creates a new transaction with one input, one address output and one data (zero value) output (output in json)" "description": "Creates a new transaction with one input, one address output and one data (zero value) output (output in json)"
}, },
{ "exec": "./dash-tx",
"args":
["-create",
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:11aa"],
"return_code": 1,
"error_txt": "error: invalid TX sequence id '11aa'",
"description": "Try to parse a sequence number outside the allowed range"
},
{ "exec": "./dash-tx",
"args":
["-create",
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:-1"],
"return_code": 1,
"error_txt": "error: invalid TX sequence id '-1'",
"description": "Try to parse a sequence number outside the allowed range"
},
{ "exec": "./dash-tx",
"args":
["-create",
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:4294967296"],
"return_code": 1,
"error_txt": "error: invalid TX sequence id '4294967296'",
"description": "Try to parse a sequence number outside the allowed range"
},
{ "exec": "./dash-tx", { "exec": "./dash-tx",
"args": "args":
["-create", ["-create",
@ -433,6 +457,14 @@
"output_cmp": "txcreatedata_seq0.hex", "output_cmp": "txcreatedata_seq0.hex",
"description": "Creates a new transaction with one input with sequence number and one address output" "description": "Creates a new transaction with one input with sequence number and one address output"
}, },
{ "exec": "./dash-tx",
"args":
["-create",
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0: 4294967293 ",
"outaddr=0.18:XijDvbYpPmznwgpWD3DkdYNfGmRP2KoVSk"],
"output_cmp": "txcreatedata_seq0.hex",
"description": "Creates a new transaction with one input with sequence number (+whitespace) and one address output"
},
{ "exec": "./dash-tx", { "exec": "./dash-tx",
"args": "args":
["-json", ["-json",
@ -457,15 +489,27 @@
"output_cmp": "txcreatedata_seq1.json", "output_cmp": "txcreatedata_seq1.json",
"description": "Adds a new input with sequence number to a transaction (output in json)" "description": "Adds a new input with sequence number to a transaction (output in json)"
}, },
{ "exec": "./dash-tx",
"args": ["-create", "outmultisig=1:-2:3:02a5:021:02df", "nversion=1"],
"return_code": 1,
"error_txt": "error: invalid multisig required number '-2'",
"description": "Try to parse a multisig number outside the allowed range"
},
{ "exec": "./dash-tx",
"args": ["-create", "outmultisig=1:2:3a:02a5:021:02df", "nversion=1"],
"return_code": 1,
"error_txt": "error: invalid multisig total number '3a'",
"description": "Try to parse a multisig number outside the allowed range"
},
{ "exec": "./dash-tx", { "exec": "./dash-tx",
"args": ["-create", "outmultisig=1:2:3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485", "nversion=1"], "args": ["-create", "outmultisig=1:2:3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485", "nversion=1"],
"output_cmp": "txcreatemultisig1.hex", "output_cmp": "txcreatemultisig1.hex",
"description": "Creates a new transaction with a single 2-of-3 multisig output" "description": "Creates a new transaction with a single 2-of-3 multisig output"
}, },
{ "exec": "./dash-tx", { "exec": "./dash-tx",
"args": ["-json", "-create", "outmultisig=1:2:3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485", "nversion=1"], "args": ["-json", "-create", "outmultisig=1: 2: 3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485", "nversion=1"],
"output_cmp": "txcreatemultisig1.json", "output_cmp": "txcreatemultisig1.json",
"description": "Creates a new transaction with a single 2-of-3 multisig output (output in json)" "description": "Creates a new transaction with a single 2-of-3 multisig output (with whitespace, output in json)"
}, },
{ "exec": "./dash-tx", { "exec": "./dash-tx",
"args": ["-create", "outmultisig=1:2:3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485:S", "nversion=1"], "args": ["-create", "outmultisig=1:2:3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485:S", "nversion=1"],