Compare commits

..

12 Commits

Author SHA1 Message Date
dan_s
72b287e467 qa: Port RPC tests to Python 3, add comprehensive test runner
Migrate all 92 Python files in qa/ from Python 2 to Python 3:
- Update shebangs from python2 to python3
- Replace print statements with print() calls
- Fix imports (http.client, urllib.parse, queue, io, functools)
- Convert xrange→range, 0L→0, long→int, cmp→key functions
- Fix except/as syntax, bytes/str handling, integer division
- Use relative imports in test_framework/ package

Add qa/run-tests.sh: multi-stage test runner (1183 lines)
- Stage 1: Build/binary verification
- Stage 2: Security hardening (PIE, NX, RELRO, canary, FORTIFY)
- Stage 3-4: Boost/Google test binaries
- Stage 5: Library tests (secp256k1, univalue)
- Stage 6: RandomX validation (live chain mining + block checks)
- Stage 7: RPC integration (skipped: regtest mining incompatible)
- Stage 8: Source code invariant checks
- Stage 8b: DragonX-specific source checks (11 tests)
- Flags: --chain=dragonx, --live-dragonx, --save-release, --quick
- Timestamped reports with release archiving to qa/release-reports/

Add qa/clean-test-reports.sh for housekeeping (--keep=N, --dry-run)

Fix test build infrastructure:
- src/Makefile.gtest.include: fix zcash_gtest→hush_gtest refs,
  remove 17 stale source files, add LIBZCASH/LIBHUSH/LIBRANDOMX
- src/Makefile.test.include: remove stale sources, deduplicate
  LDADD/CXXFLAGS, add missing libraries
- src/gtest/test_checkblock.cpp: add height param to ContextualCheckBlock
- src/test/test_bitcoin.cpp: remove JoinSplitTestingSetup (dead code)

Add qa/test-reports/ to .gitignore for transient output.
2026-02-27 22:38:43 -06:00
dan_s
20aeebb83f Fix 7 stale references in docs and comments after codebase restructuring
- doc/DEVELOPING.md: src/main.cpp → src/tx_validation.cpp / block_processing.cpp
- doc/CHANGELOG-randomx-validation.md: src/main.cpp → src/block_processing.cpp (×2)
- doc/release-process.md: checkpoint instructions now reference
  src/chainparams_checkpoints_hush3.h instead of src/chainparams.cpp
- src/hush_defs.h: ./contrib/block_time.pl → ./contrib/scripts/block_time.pl (×3)
- src/cc/dapps/dappstd.c: commented hush_cJSON.c → hush_cJSON.cpp
2026-02-27 14:19:08 -06:00
dan_s
a2647b106f Move 15 loose scripts from contrib/ root to contrib/scripts/
Consolidate all standalone utility scripts into contrib/scripts/:
- Perl: avg_blocktime.pl, block_time.pl, gen-zaddrs.pl, sda_checkpoints.pl,
  sdl_checkpoints.pl, hush_block_subsidy_per_halving, hush_halvings,
  hush_scanner, hush_supply, hush_supply_old
- Shell: fresh_clone_compile_and_run.sh, tidy_datadir.sh, dragonx_scanner
- Python: convert_address.py
- BAT: hush-uri.bat

Update path references in contrib/README.md, doc/OLD_WALLETS.md,
doc/relnotes/README.md, and sdl_checkpoints.pl.
2026-02-27 12:00:46 -06:00
dan_s
ab6a3a05d7 Deduplicate cJSON: consolidate 4 copies into a single canonical pair
- Compile cJSON.c as a standalone C translation unit (added stdbool.h)
- Rename hush_cJSON.c → hush_cJSON.cpp and compile as standalone C++ unit
  with forward declarations for external deps (_stripwhite, clonestr, etc.)
- Remove #include "cJSON.c" unity-build from hush_cJSON
- Change hush.h from #include "hush_cJSON.c" to #include "hush_cJSON.h"
- Add both files to libbitcoin_server_a_SOURCES in Makefile.am
- Delete cc/dapps/cJSON.c (old 2009 fork, 1201 lines removed)
- Replace cc/includes/cJSON.h with thin redirect to canonical headers
- Update dapp includes to reference canonical cJSON.c
2026-02-27 09:39:48 -06:00
dan_s
f565b2920d Split wallet.cpp: extract key management into wallet_keys.cpp
Separate key management from transaction logic in wallet.cpp (5,059 lines):
- wallet.cpp: 5,059 → 4,143 lines (transaction tracking, coin selection, balances)
- wallet_keys.cpp: 975 lines (key generation, encryption, HD seed, keypool)

Extracted functions include key generation (GenerateNewKey, GenerateNewSaplingZKey),
cryptographic key storage (AddKeyPubKey, AddCryptedKey, AddCryptedSaplingSpendingKey),
wallet encryption (Unlock, ChangeWalletPassphrase, EncryptWallet), HD seed management,
keypool operations, CReserveKey methods, and shielded key visitor operators.
2026-02-27 01:51:24 -06:00
dan_s
0083cd26bb Split main.cpp (8,217 lines) into four focused translation units
- tx_validation.cpp (1,012 lines): transaction validation functions
  (IsStandardTx, CheckTransaction, ContextualCheckInputs, etc.)
- mempool_accept.cpp (524 lines): mempool acceptance and orphan management
  (AcceptToMemoryPool, AddOrphanTx, GetMinRelayFee, etc.)
- block_processing.cpp (4,064 lines): block processing, chain management,
  and disk I/O (ConnectBlock, DisconnectBlock, ActivateBestChain, CheckBlock,
  LoadBlockIndex, FlushStateToDisk, etc.)
- main_internal.h (83 lines): shared internal state declarations formerly in
  anonymous namespace (CBlockIndexWorkComparator, setBlockIndexCandidates,
  vinfoBlockFile, setDirtyBlockIndex, etc.)

main.cpp retains NET message handling (ProcessMessage, SendMessages),
peer state management, and utility functions (2,821 lines).
2026-02-27 01:51:24 -06:00
dan_s
a918136a7c Split chainparams.cpp and rpcwallet.cpp into smaller files
chainparams.cpp: 5420 -> 593 lines
  - Extract HUSH3 checkpoint data to chainparams_checkpoints_hush3.h
  - Extract DRAGONX checkpoint data to chainparams_checkpoints_dragonx.h

rpcwallet.cpp: 6392 -> 4099 lines
  - Extract z-index query RPCs to rpcwallet_zindex.cpp
  - Extract shielded async operation RPCs to rpcwallet_zops.cpp
  - Create rpcwallet_internal.h for shared declarations
2026-02-27 01:51:24 -06:00
dan_s
3d4e25e429 Split hush unity build: move ~14k lines of implementation from headers into hush_impl.cpp and hush_nSPV_impl.cpp
- Add HUSH_PRIVATE_IMPLEMENTATION guard to hush.h separating implementation from declarations
- Create hush_impl.cpp to compile all hush_*.h implementation as a separate translation unit
- Create hush_nSPV_impl.cpp to compile all hush_nSPV_*.h headers separately
- main.cpp now includes declarations only, no longer a unity build for hush code
- Add both new compilation units to Makefile.am
2026-02-26 20:55:12 -06:00
dan_s
896fa9c107 Reorganize repo: move scripts to contrib/scripts/, clean up .gitignore, untrack backup files 2026-02-26 19:42:28 -06:00
dan_s
10a1b27de1 reorganizing release ouput to cleaner directory structure 2026-02-25 23:50:14 -06:00
dan_s
3cf6c37bf6 updated dragonx checkpoints 2026-02-25 14:41:10 -06:00
dan_s
b25bd2838c fix native linux build script 2026-02-25 14:09:26 -06:00
181 changed files with 16787 additions and 33051 deletions

274
.gitignore vendored
View File

@@ -1,13 +1,43 @@
# ==========================
# Editor & IDE files
# ==========================
.*.sw?
*.*~*
*~
*.bak
*.rej
*.orig
.idea
.vscode
# ==========================
# Compiled objects & libraries
# ==========================
*.o
*.o-*
*.a
*.lo
*.la
*.so
*.dll
*.pyc
*.pb.cc
*.pb.h
*.json.h
*.raw.h
*.dSYM
# ==========================
# Archives & packages
# ==========================
*.tar.gz
*.deb
src/bitcoin
src/test/test_bitcoin
src/core
*.zip
*.dmg
*zcashTest.pk
*zcashTest.vk
# autoreconf
# ==========================
# Autotools / configure
# ==========================
#Makefile.in
aclocal.m4
autom4te.cache/
@@ -28,58 +58,74 @@ config.log
config.status
configure
libtool
Makefile
Makefile.in
src/Makefile.in
doc/man/Makefile.in
src/config/bitcoin-config.h
src/config/bitcoin-config.h.in
src/config/stamp-h1
libzcashconsensus.pc
cache/
venv-mnf/
src/univalue/gen
# ==========================
# Build outputs & artifacts
# ==========================
src/.build_target
.deps
.dirstamp
.idea
.libs
.*.sw?
*.*~*
*.bak
*.rej
*.orig
*.pyc
*.o
*.o-*
.zcash
*.a
*.pb.cc
*.pb.h
.vscode
# Hush binaries
src/hush-cli
src/hushd
src/hush-tx
src/hush-test
src/hush-cli.exe
src/hushd.exe
src/hush-tx.exe
src/wallet-utility
src/wallet-utility.exe
# Legacy bitcoin binaries
src/bitcoin
src/test/test_bitcoin
src/core
# Shared libraries
src/libcc.so
src/libcc.dll
src/cc/customcc.so
src/cc/customcc.dll
src/cc/librogue.so
# RandomX build dirs
src/RandomX/build-linux/
src/RandomX/build-win64/
# Release directories
release/
release-win64/
release-linux/
# ==========================
# Depends build system
# ==========================
depends/built/
depends/work/
depends/x86_64-*/
# ==========================
# Zcash / Sapling test keys
# ==========================
*zcashTest.pk
*zcashTest.vk
.zcash
# ==========================
# Test & coverage
# ==========================
*.log
*.trs
*.dmg
*.json.h
*.raw.h
#libtool object files
*.lo
*.la
# Compilation
Makefile
# Unit-tests
Makefile.test
src/test/buildenv.py
# Resources cpp
qrc_*.cpp
# Mac specific
.DS_Store
build
#lcov
*.gcno
*.gcda
/*.info
@@ -87,8 +133,8 @@ test_bitcoin.coverage/
zcash-gtest.coverage/
total.coverage/
coverage_percent.txt
#build tests
Makefile.test
src/test/buildenv.py
linux-coverage-build
linux-build
win32-build
@@ -97,84 +143,66 @@ qa/pull-tester/tests-config.sh
qa/pull-tester/cache/*
qa/pull-tester/test.*/*
!src/leveldb*/Makefile
# ==========================
# Generated / misc source
# ==========================
qrc_*.cpp
src/univalue/gen
src/cryptoconditions/compile
src/fiat/-usd
/doc/doxygen/
libzcashconsensus.pc
# ==========================
# CC / games (legacy)
# ==========================
src/cc/rogue/rogue
src/cc/rogue/rogue.so
src/cc/rogue/test.zip
src/cc/rogue/config.h
src/cc/rogue/confdefs.h
src/cc/rogue/x64
src/cc/dapps/a.out
src/cc/games/prices
src/cc/games/tetris
src/ROGUE.conf
src/rogue.scr
src/rogue.*.*
src/fiat/-usd
# ==========================
# Misc runtime / temp files
# ==========================
src/checkfile
src/foo.zip
src/log
src/HUSH3_7776
REGTEST_7776
src/rpcmisc~.cpp
cache/
venv-mnf/
# ==========================
# Debian packaging
# ==========================
contrib/debian/files
contrib/debian/substvars
src/rpcmisc~.cpp
src/wallet-utility
# ==========================
# Platform specific
# ==========================
.DS_Store
build
src/hush-cli
src/hushd
src/hush-tx
src/hush-test
src/hush-cli.exe
src/hushd.exe
src/hush-tx.exe
# ==========================
# Bundled repos (use separately)
# ==========================
repos/
#output during builds, symbol tables?
*.dSYM
# ==========================
# Leveldb Makefile exception
# ==========================
src/cryptoconditions/compile
src/cc/rogue/rogue
src/cc/rogue/rogue.so
src/cc/rogue/test.zip
src/cc/dapps/a.out
src/checkfile
src/foo.zip
src/log
src/rogue.530623577502174316.0
src/rogue.530623577502174316.pack
src/rogue.530623577502174316.player
src/cc/rogue/config.h
src/ROGUE.conf
src/rogue.scr
src/cc/rogue/confdefs.h
src/cc/rogue/x64
src/cc/dapps/a.out
src/Makefile.in
doc/man/Makefile.in
Makefile.in
src/libcc.so
src/libcc.dll
src/cc/customcc.so
src/cc/customcc.dll
src/HUSH3_7776
REGTEST_7776
src/cc/librogue.so
src/cc/games/prices
src/cc/games/tetris
# Build artifacts
*~
*.zip
release-win64/
release-linux/
src/RandomX/build-linux/
src/RandomX/build-win64/
src/wallet-utility.exe
src/.build_target
# other
repos/
# ==========================
# Test reports (transient)
# ==========================
qa/test-reports/
!src/leveldb*/Makefile

View File

@@ -11,38 +11,43 @@ make clean 2>/dev/null || true
rm -rf depends/built depends/x86_64-unknown-linux-gnu depends/work
make -C depends clean 2>/dev/null || true
# Limit parallelism to avoid OOM kills inside Docker.
# Each C++ compilation can use 1-2 GB RAM; cap at ~half of nproc.
JOBS=$(( $(nproc) / 2 ))
[ "$JOBS" -lt 1 ] && JOBS=1
# Build RandomX for Linux (clean, since host build is different arch/libc)
cd src/RandomX
rm -rf build-linux
mkdir -p build-linux && cd build-linux
cmake -DARCH=native ..
make -j$(nproc)
make -j"$JOBS"
cd /hush3
# Run the normal build
./util/build.sh --disable-tests -j$(nproc)
./util/build.sh --disable-tests -j"$JOBS"
# Package release
echo "Creating Linux release package..."
VERSION=$(grep -oP 'define\(_CLIENT_VERSION.*?,\s*\K[0-9]+' configure.ac | head -3 | tr '\n' '.' | sed 's/\.$//')
VERSION=${VERSION:-3.10.5}
RELEASE_DIR="release-linux"
RELEASE_DIR="release/${VERSION}-linux-amd64"
mkdir -p "$RELEASE_DIR"
strip -s src/hushd src/hush-cli src/hush-tx
cp src/hushd src/hush-cli src/hush-tx "$RELEASE_DIR/"
cp asmap.dat sapling-spend.params sapling-output.params "$RELEASE_DIR/" 2>/dev/null || true
cp src/hush-arrakis-chain src/dragonxd src/dragonx-cli "$RELEASE_DIR/"
cp contrib/scripts/hush-arrakis-chain contrib/scripts/dragonxd contrib/scripts/dragonx-cli "$RELEASE_DIR/"
cp contrib/bootstrap/bootstrap-dragonx.sh "$RELEASE_DIR/"
# Create ZIP inside release dir (matches --win-release layout)
rm -f "$RELEASE_DIR/hush-${VERSION}-linux64.zip"
rm -f "$RELEASE_DIR/${VERSION}-linux-amd64.zip"
cd "$RELEASE_DIR"
zip -9 "hush-${VERSION}-linux64.zip" *
cd ..
zip -9 "${VERSION}-linux-amd64.zip" *
cd ../..
echo "Release package created: $RELEASE_DIR/hush-${VERSION}-linux64.zip"
ls -lh "$RELEASE_DIR/hush-${VERSION}-linux64.zip"
echo "Release package created: $RELEASE_DIR/${VERSION}-linux-amd64.zip"
ls -lh "$RELEASE_DIR/${VERSION}-linux-amd64.zip"
# Fix ownership of all files created by root so host user can access them
if [ -n "${HOST_UID:-}" ] && [ -n "${HOST_GID:-}" ]; then

View File

@@ -26,6 +26,26 @@ check_and_clean_target() {
if [[ -d src/leveldb ]]; then
make -C src/leveldb clean 2>/dev/null || true
fi
# Clean depends when switching between Docker and native builds,
# since Docker builds bake container paths into .la files
local TRIPLET
TRIPLET=$(./depends/config.guess 2>/dev/null || true)
if [[ -n "$TRIPLET" && -d "depends/$TRIPLET" ]]; then
echo "Cleaning depends/$TRIPLET to avoid path contamination..."
# Use sudo if files are root-owned (from Docker builds)
if [[ "$(stat -c '%u' "depends/$TRIPLET" 2>/dev/null)" == "0" ]]; then
sudo rm -rf "depends/$TRIPLET" "depends/built/$TRIPLET"
else
rm -rf "depends/$TRIPLET" "depends/built/$TRIPLET"
fi
elif [[ -n "$TRIPLET" && -d "depends/built/$TRIPLET" ]]; then
echo "Cleaning depends/built/$TRIPLET to avoid path contamination..."
if [[ "$(stat -c '%u' "depends/built/$TRIPLET" 2>/dev/null)" == "0" ]]; then
sudo rm -rf "depends/built/$TRIPLET"
else
rm -rf "depends/built/$TRIPLET"
fi
fi
echo "Clean complete."
fi
@@ -48,7 +68,9 @@ if [[ "${1:-}" == "--linux-release" ]]; then
echo "Building Linux release inside Ubuntu 20.04 Docker container..."
sudo docker build -t hush-builder -f Dockerfile.build .
sudo docker run --rm -e HOST_UID=$(id -u) -e HOST_GID=$(id -g) -v "$SCRIPT_DIR:/hush3" hush-builder "$@"
echo "Docker build complete. Release is in release-linux/"
VERSION=$(grep -oP 'define\(_CLIENT_VERSION.*?,\s*\K[0-9]+' configure.ac | head -3 | tr '\n' '.' | sed 's/\.$//')
VERSION=${VERSION:-3.10.5}
echo "Docker build complete. Release is in release/${VERSION}-linux-amd64/"
exit $?
fi

View File

@@ -14,7 +14,7 @@ Estimate when a Hush block will happen.
Example:
./contrib/block_time.pl 123456 # Print out datetime of when block height 123456 happens
./contrib/scripts/block_time.pl 123456 # Print out datetime of when block height 123456 happens
## gen-zaddrs.pl
@@ -22,8 +22,8 @@ Generate zaddrs in bulk, by default 50 at a time. Prints out a zaddr one per lin
Example:
./contrib/gen-zaddrs.pl # generate 50 zaddrs
./contrib/gen-zaddrs.pl 500 # generate 500 zaddrs
./contrib/scripts/gen-zaddrs.pl # generate 50 zaddrs
./contrib/scripts/gen-zaddrs.pl 500 # generate 500 zaddrs
## Wallet Tools

View File

@@ -0,0 +1,19 @@
#!/usr/bin/env bash
# Copyright (c) 2016-2024 The Hush developers
set -eo pipefail
# Resolve binary directory
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ -f "$SCRIPTDIR/hush-cli" ] || [ -f "$SCRIPTDIR/hushd" ]; then
BINDIR="$SCRIPTDIR"
else
BINDIR="$SCRIPTDIR/../../src"
fi
cd "$BINDIR"
hush_cli='./hush-cli'
"$SCRIPTDIR/listassetchains" | while read chain; do
$hush_cli --ac_name=$chain stop
done

15
contrib/scripts/dragonx-cli Executable file
View File

@@ -0,0 +1,15 @@
#!/usr/bin/env bash
# Copyright 2016-2024 The Hush Developers
# Copyright 2022 The DragonX Developers
# Released under the GPLv3
# Resolve binary directory
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ -f "$SCRIPTDIR/hush-cli" ] || [ -f "$SCRIPTDIR/hushd" ]; then
BINDIR="$SCRIPTDIR"
else
BINDIR="$SCRIPTDIR/../../src"
fi
cd "$BINDIR"
./hush-cli -ac_name=DRAGONX "$@"

View File

@@ -3,12 +3,14 @@
# Copyright 2022 The DragonX Developers
# Released under the GPLv3
# set working directory to the location of this script
# readlink -f does not always exist
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )"
cd $DIR
# Resolve binary directory
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ -f "$SCRIPTDIR/hush-cli" ] || [ -f "$SCRIPTDIR/hushd" ]; then
BINDIR="$SCRIPTDIR"
else
BINDIR="$SCRIPTDIR/../../src"
fi
cd "$BINDIR"
SEEDNODE=176.126.87.241

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
# Copyright (c) 2016-2024 The Hush developers
# Resolve binary directory
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ -f "$SCRIPTDIR/hush-cli" ] || [ -f "$SCRIPTDIR/hushd" ]; then
BINDIR="$SCRIPTDIR"
else
BINDIR="$SCRIPTDIR/../../src"
fi
cd "$BINDIR"
DEFAULTS=""
# People can just use hushd going forward, but this script makes it
# more clear what is going on
HUSH="./hushd"
$HUSH $DEFAULTS "$@"

View File

@@ -5,8 +5,12 @@ import json
def format_param(param, value):
return '-' + param + '=' + value
script_dir = os.path.dirname(__file__)
with open(script_dir + '/assetchains.json') as file:
script_dir = os.path.dirname(os.path.abspath(__file__))
# Look for assetchains.json in same dir first, then in src/
json_path = os.path.join(script_dir, 'assetchains.json')
if not os.path.exists(json_path):
json_path = os.path.join(script_dir, '..', '..', 'src', 'assetchains.json')
with open(json_path) as file:
assetchains = json.load(file)
for chain in assetchains:

14
contrib/scripts/listassetchains Executable file
View File

@@ -0,0 +1,14 @@
#!/usr/bin/env python2
import os
import json
script_dir = os.path.dirname(os.path.abspath(__file__))
# Look for assetchains.json in same dir first, then in src/
json_path = os.path.join(script_dir, 'assetchains.json')
if not os.path.exists(json_path):
json_path = os.path.join(script_dir, '..', '..', 'src', 'assetchains.json')
with open(json_path) as file:
assetchains = json.load(file)
for chain in assetchains:
print(chain['ac_name'])

View File

@@ -10,7 +10,7 @@ use warnings;
use strict;
# call this script like this to generate checkpoints for a HAC such as DragonX:
# CLI=./src/dragonx-cli ./contrib/sdl_checkpoints.pl ...
# CLI=./src/dragonx-cli ./contrib/scripts/sdl_checkpoints.pl ...
my $hush = $ENV{CLI} || "./src/hush-cli";
my $gethash = "$hush getblockhash";

View File

@@ -2,15 +2,24 @@
# Copyright (c) 2018-2024 The Hush developers
set -eo pipefail
# Resolve binary directory
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ -f "$SCRIPTDIR/hush-cli" ] || [ -f "$SCRIPTDIR/hushd" ]; then
BINDIR="$SCRIPTDIR"
else
BINDIR="$SCRIPTDIR/../../src"
fi
cd "$BINDIR"
# You can now add delay line to pubkey.txt file
source pubkey.txt
overide_args="$@"
override_args="$@"
seed_ip=$(SEEDNODE)
hsc='./hush-arrakis-chain'
if [ -z "$delay" ]; then delay=20; fi
./listassetchainparams | while read args; do
"$SCRIPTDIR/listassetchainparams" | while read args; do
gen=""
if [ $[RANDOM % 10] == 1 ]; then
gen=" -gen -genproclimit=1"

15
contrib/scripts/testdragonx-cli Executable file
View File

@@ -0,0 +1,15 @@
#!/usr/bin/env bash
# Copyright 2016-2024 The Hush Developers
# Copyright 2022 The DragonX Developers
# Released under the GPLv3
# Resolve binary directory
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ -f "$SCRIPTDIR/hush-cli" ] || [ -f "$SCRIPTDIR/hushd" ]; then
BINDIR="$SCRIPTDIR"
else
BINDIR="$SCRIPTDIR/../../src"
fi
cd "$BINDIR"
./hush-cli -ac_name=TESTDRAGONX $@

View File

@@ -3,12 +3,14 @@
# Copyright 2022 The DragonX Developers
# Released under the GPLv3
# set working directory to the location of this script
# readlink -f does not always exist
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )"
cd $DIR
# Resolve binary directory
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ -f "$SCRIPTDIR/hush-cli" ] || [ -f "$SCRIPTDIR/hushd" ]; then
BINDIR="$SCRIPTDIR"
else
BINDIR="$SCRIPTDIR/../../src"
fi
cd "$BINDIR"
BLOCKTIME=18
SUPPLY=0

View File

@@ -0,0 +1,15 @@
#!/usr/bin/env bash
# Copyright 2016-2024 The Hush Developers
# Copyright 2022 The DragonX Developers
# Released under the GPLv3
# Resolve binary directory
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ -f "$SCRIPTDIR/hush-cli" ] || [ -f "$SCRIPTDIR/hushd" ]; then
BINDIR="$SCRIPTDIR"
else
BINDIR="$SCRIPTDIR/../../src"
fi
cd "$BINDIR"
./hush-cli -ac_name=TESTEQUIHASH $@

View File

@@ -3,12 +3,14 @@
# Copyright 2022 The DragonX Developers
# Released under the GPLv3
# set working directory to the location of this script
# readlink -f does not always exist
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )"
cd $DIR
# Resolve binary directory
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ -f "$SCRIPTDIR/hush-cli" ] || [ -f "$SCRIPTDIR/hushd" ]; then
BINDIR="$SCRIPTDIR"
else
BINDIR="$SCRIPTDIR/../../src"
fi
cd "$BINDIR"
BLOCKTIME=18
SUPPLY=0

View File

@@ -1,12 +1,14 @@
#!/usr/bin/env bash
# Copyright (c) 2016-2024 The Hush developers
# set working directory to the location of this script
# readlink -f does not always exist
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )"
cd $DIR
# Resolve binary directory
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ -f "$SCRIPTDIR/hush-cli" ] || [ -f "$SCRIPTDIR/hushd" ]; then
BINDIR="$SCRIPTDIR"
else
BINDIR="$SCRIPTDIR/../../src"
fi
cd "$BINDIR"
NAME=TUSH

View File

@@ -3,12 +3,14 @@
# Distributed under the GPLv3 software license, see the accompanying
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
# set working directory to the location of this script
# readlink -f does not always exist
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )"
cd $DIR
# Resolve binary directory
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ -f "$SCRIPTDIR/hush-cli" ] || [ -f "$SCRIPTDIR/hushd" ]; then
BINDIR="$SCRIPTDIR"
else
BINDIR="$SCRIPTDIR/../../src"
fi
cd "$BINDIR"
# ./hushd -ac_name=TUSH -ac_private=1 -gen=1 -testnode=1
./hushd -ac_name=TUSH -ac_private=1 -ac_supply=55555

18
contrib/scripts/zush Executable file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# Copyright (c) 2016-2024 The Hush developers
# Resolve binary directory
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ -f "$SCRIPTDIR/hush-cli" ] || [ -f "$SCRIPTDIR/hushd" ]; then
BINDIR="$SCRIPTDIR"
else
BINDIR="$SCRIPTDIR/../../src"
fi
cd "$BINDIR"
NAME=ZUSH
CLI=${HUSHCLI:-./hush-cli}
if [ -f $CLI ]; then
$CLI -ac_name=$NAME "$@"
fi

View File

@@ -46,7 +46,7 @@ A malicious miner could put arbitrary bytes in `nSolution`, iterate nonces until
- Compares the computed hash against `pblock->nSolution`.
- Caches the RandomX VM and cache between calls (protected by mutex), re-initializing only when the key changes.
### `src/main.cpp`
### `src/block_processing.cpp`
- In `CheckBlockHeader()`: added `CheckRandomXSolution()` call inside the `fCheckPOW` block, after the existing `CheckEquihashSolution()` call. Invalid RandomX solutions are rejected with `DoS(100)`.
@@ -89,7 +89,7 @@ A malicious miner could put arbitrary bytes in `nSolution`, iterate nonces until
| `src/hush_defs.h` | 1 | 0 |
| `src/pow.h` | 9 | 0 |
| `src/pow.cpp` | ~105 | 0 |
| `src/main.cpp` | 2 | 0 |
| `src/block_processing.cpp` | 2 | 0 |
| `src/hush_bitcoind.h` | 6 | 0 |
| `src/miner.cpp` | 5 | 5 |
| `src/hush_utils.h` | 10 | 0 |

View File

@@ -121,7 +121,7 @@ The chain magic value is the CRC32 checksum of every non-default consensus
option the HAC uses.
Also make sure to actually validate the new consensus option! That is probably
going to happen in `src/main.cpp` . If you don't, a malicious node can just
going to happen in `src/tx_validation.cpp` or `src/block_processing.cpp` . If you don't, a malicious node can just
modify `src/miner.cpp` to do whatever they want.
## Updates to this document

View File

@@ -19,7 +19,7 @@ with `t1` and now they begin with `R`.
To see what an old HUSH v2 address looks like on the new chain, this online tool
can be used: https://dexstats.info/addressconverter.php
or this command line tool: https://git.hush.is/hush/hush3/src/master/contrib/convert_address.py
or this command line tool: https://git.hush.is/hush/hush3/src/master/contrib/scripts/convert_address.py
### Using an old wallet.dat

View File

@@ -96,7 +96,7 @@ For this repo, it's likely this is the command you need:
gdb src/hushd core
```
NOTE: Even if you are debugging a coredump on a HAC, such as DragonX, the file `src/dragonxd`
NOTE: Even if you are debugging a coredump on a HAC, such as DragonX, the file `contrib/scripts/dragonxd`
is just a shell script that calls `src/hushd` and you always want to give an actual executable
file as the first argument to `gdb`, not a bash script.

View File

@@ -13,11 +13,11 @@ The following command can be used to launch an HSC on a single computer. Each op
HSC CLI arguments that start with `-ac_` means they *Affect Consensus*.
```
./src/hush-arrakis-chain -ac_halving=100 -ac_algo=randomx -ac_name=RANDOMX -ac_private=1 -ac_blocktime=15 -ac_reward=500000000 -ac_supply=55555 -gen=1 -genproclimit=1 -testnode=1
./contrib/scripts/hush-arrakis-chain -ac_halving=100 -ac_algo=randomx -ac_name=RANDOMX -ac_private=1 -ac_blocktime=15 -ac_reward=500000000 -ac_supply=55555 -gen=1 -genproclimit=1 -testnode=1
```
* `hush-arrakis-chain` is the script used to launch or connect to HSCs
* It lives in the `./src` directory, next to `hushd` and `hush-cli`
* It lives in the `./contrib/scripts` directory
* It is called `hush-arrakis-chain.bat` on Windows
* `-ac_halving=100` means "the block reward halves every 100 blocks"
* `-ac_algo=randomx` means "use RandomX for Proof-Of-Work
@@ -41,12 +41,12 @@ HSC CLI arguments that start with `-ac_` means they *Affect Consensus*.
* One node would use
```
# first node
./src/hush-arrakis-chain -ac_halving=100 -ac_algo=randomx -ac_name=RANDOMX -ac_private=1 -ac_blocktime=15 -ac_reward=500000000 -ac_supply=55555
./contrib/scripts/hush-arrakis-chain -ac_halving=100 -ac_algo=randomx -ac_name=RANDOMX -ac_private=1 -ac_blocktime=15 -ac_reward=500000000 -ac_supply=55555
```
* And the second node would use:
```
# mining node. NOTE: This node will mine the genesis block and pre-mine, if any
./src/hush-arrakis-chain -ac_halving=100 -ac_algo=randomx -ac_name=RANDOMX -ac_private=1 -ac_blocktime=15 -ac_reward=500000000 -ac_supply=55555 -gen=1 -genproclimit=1
./contrib/scripts/hush-arrakis-chain -ac_halving=100 -ac_algo=randomx -ac_name=RANDOMX -ac_private=1 -ac_blocktime=15 -ac_reward=500000000 -ac_supply=55555 -gen=1 -genproclimit=1
```
# Advanced Options

View File

@@ -76,10 +76,10 @@ Install deps on Linux:
- There is a hack in the script where you can hardcode a version number if hushd isn't running.
- Comment out the HUSHVER line and uncomment the line above it with a hardcoded version number
- PROTIP: Man page creation must be done after updating the version number and recompiling and before Debian package creation
- Update checkpoints in src/chainparams.cpp via util/checkpoints.pl
- Update checkpoints in src/chainparams_checkpoints_hush3.h (or src/chainparams_checkpoints_dragonx.h for DRAGONX) via util/checkpoints.pl
- Run "./util/checkpoints.pl help" to get example usage
- hushd must be running to run this script, since it uses hush-cli to get the data
- Look for line which says "END HUSH mainnet checkpoint data" near line 560 in chainparams.cpp , that is where checkpoint data ends
- The checkpoint data is in src/chainparams_checkpoints_hush3.h, which is #included at line 559 of chainparams.cpp. Add new entries at the end of that header file.
- Find the highest block height of checkpoint data, let's call it HEIGHT
- Run `./util/checkpoints.pl 1000 HEIGHT &> checkpoints.txt` to generate the latest checkpoint data
- To copy the new data from checkpoints.txt into the file, one way in Vim is to type ":r checkpoints.txt" which will read in a file and paste it as the current cursor

View File

@@ -231,8 +231,8 @@ since it contains various bugfixes and improvements that will benefit busy walle
* sendmany RPC will now reject transactions that send to taddrs immediately, instead of them being rejected in mempool
* Preliminary support for FreeBSD has been added to the Hush build system
* New contrib scripts:
* `contrib/gen-zaddrs.pl` - Generate zaddrs in bulk, defaults to 50
* `contrib/sdl_checkpoints.pl` - Generate SDL checkpoints using `getblockmerkletree`
* `contrib/scripts/gen-zaddrs.pl` - Generate zaddrs in bulk, defaults to 50
* `contrib/scripts/sdl_checkpoints.pl` - Generate SDL checkpoints using `getblockmerkletree`
* ZeroMQ support has been removed from Hush
# Hush 3.9.1 "Luciferous Locust"

117
qa/clean-test-reports.sh Executable file
View File

@@ -0,0 +1,117 @@
#!/usr/bin/env bash
# Copyright (c) 2024-2026 The Hush developers
# Clean up old test reports and log directories
# Usage: ./qa/clean-test-reports.sh [--keep=N] [--dry-run] [--all]
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPORT_DIR="$SCRIPT_DIR/test-reports"
# Defaults
KEEP=3 # number of most recent report sets to keep
DRY_RUN=0
REMOVE_ALL=0
for arg in "$@"; do
case "$arg" in
--keep=*) KEEP="${arg#--keep=}" ;;
--dry-run) DRY_RUN=1 ;;
--all) REMOVE_ALL=1 ;;
--help|-h)
echo "Usage: $0 [--keep=N] [--dry-run] [--all]"
echo ""
echo " --keep=N Keep the N most recent reports (default: 3)"
echo " --dry-run Show what would be removed without deleting"
echo " --all Remove ALL reports and logs (ignores --keep)"
echo ""
exit 0
;;
*) echo "Unknown option: $arg"; exit 1 ;;
esac
done
if [[ ! -d "$REPORT_DIR" ]]; then
echo "Nothing to clean — $REPORT_DIR does not exist."
exit 0
fi
# Gather all report files sorted newest-first
mapfile -t ALL_REPORTS < <(ls -1t "$REPORT_DIR"/test-report-*.txt 2>/dev/null)
total=${#ALL_REPORTS[@]}
if [[ $total -eq 0 ]]; then
echo "No test reports found in $REPORT_DIR"
exit 0
fi
echo "Found $total report(s) in $REPORT_DIR"
if [[ $REMOVE_ALL -eq 1 ]]; then
TO_REMOVE=("${ALL_REPORTS[@]}")
else
if [[ $KEEP -ge $total ]]; then
echo "Keeping all $total reports (--keep=$KEEP >= total)."
echo "Nothing to remove."
exit 0
fi
TO_REMOVE=("${ALL_REPORTS[@]:$KEEP}")
fi
removed_count=0
freed_bytes=0
for report in "${TO_REMOVE[@]}"; do
# Derive the matching logs directory from the report filename
# test-report-20260227_182206.txt -> logs-20260227_182206
ts=$(basename "$report" .txt | sed 's/^test-report-//')
log_dir="$REPORT_DIR/logs-${ts}"
if [[ $DRY_RUN -eq 1 ]]; then
echo " [dry-run] would remove: $(basename "$report")"
[[ -d "$log_dir" ]] && echo " [dry-run] would remove: $(basename "$log_dir")/"
else
# Tally size before removal
if [[ -f "$report" ]]; then
freed_bytes=$(( freed_bytes + $(stat -c%s "$report" 2>/dev/null || echo 0) ))
rm -f "$report"
fi
if [[ -d "$log_dir" ]]; then
freed_bytes=$(( freed_bytes + $(du -sb "$log_dir" 2>/dev/null | awk '{print $1}') ))
rm -rf "$log_dir"
fi
((removed_count++))
fi
done
# Clean up any orphaned log directories (no matching report file)
for log_dir in "$REPORT_DIR"/logs-*/; do
[[ -d "$log_dir" ]] || continue
ts=$(basename "$log_dir" | sed 's/^logs-//')
report="$REPORT_DIR/test-report-${ts}.txt"
if [[ ! -f "$report" ]]; then
if [[ $DRY_RUN -eq 1 ]]; then
echo " [dry-run] would remove orphan: $(basename "$log_dir")/"
else
freed_bytes=$(( freed_bytes + $(du -sb "$log_dir" 2>/dev/null | awk '{print $1}') ))
rm -rf "$log_dir"
((removed_count++))
fi
fi
done
if [[ $DRY_RUN -eq 1 ]]; then
echo ""
echo "Dry run complete. No files were removed."
else
freed_mb=$(( freed_bytes / 1024 / 1024 ))
freed_kb=$(( freed_bytes / 1024 ))
if [[ $freed_mb -gt 0 ]]; then
echo "Removed $removed_count item(s), freed ~${freed_mb}MB"
else
echo "Removed $removed_count item(s), freed ~${freed_kb}KB"
fi
remaining=$(ls -1 "$REPORT_DIR"/test-report-*.txt 2>/dev/null | wc -l)
echo "Remaining reports: $remaining"
fi

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Distributed under the GPLv3 software license, see the accompanying
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
@@ -34,7 +34,7 @@ LD_LIBRARY_PATH=src/leveldb python qa/hush/create_benchmark_archive.py
def check_deps():
if subprocess.call(['which', 'find', 'xz', HUSH_CLI], stdout=subprocess.PIPE):
print USAGE
print(USAGE)
sys.exit()
def encode_varint(n):
@@ -51,8 +51,9 @@ def encode_varint(n):
def decode_varint(v):
n = 0
for ch in range(len(v)):
n = (n << 7) | (ord(v[ch]) & 0x7F)
if (ord(v[ch]) & 0x80):
b = v[ch] if isinstance(v[ch], int) else ord(v[ch])
n = (n << 7) | (b & 0x7F)
if (b & 0x80):
n += 1
else:
return n
@@ -159,8 +160,8 @@ def deterministic_filter(tarinfo):
def create_benchmark_archive(blk_hash):
blk = json.loads(subprocess.check_output([HUSH_CLI, 'getblock', blk_hash]))
print 'Height: %d' % blk['height']
print 'Transactions: %d' % len(blk['tx'])
print(('Height: %d' % blk['height']))
print(('Transactions: %d' % len(blk['tx'])))
os.mkdir('benchmark')
with open('benchmark/block-%d.dat' % blk['height'], 'wb') as f:
@@ -171,25 +172,25 @@ def create_benchmark_archive(blk_hash):
js_txs = len([tx for tx in txs if len(tx['vjoinsplit']) > 0])
if js_txs:
print 'Block contains %d JoinSplit-containing transactions' % js_txs
print(('Block contains %d JoinSplit-containing transactions' % js_txs))
return
inputs = [(x['txid'], x['vout']) for tx in txs for x in tx['vin'] if x.has_key('txid')]
print 'Total inputs: %d' % len(inputs)
inputs = [(x['txid'], x['vout']) for tx in txs for x in tx['vin'] if 'txid' in x]
print(('Total inputs: %d' % len(inputs)))
unique_inputs = {}
for i in sorted(inputs):
if unique_inputs.has_key(i[0]):
if i[0] in unique_inputs:
unique_inputs[i[0]].append(i[1])
else:
unique_inputs[i[0]] = [i[1]]
print 'Unique input transactions: %d' % len(unique_inputs)
print(('Unique input transactions: %d' % len(unique_inputs)))
db_path = 'benchmark/block-%d-inputs' % blk['height']
db = plyvel.DB(db_path, create_if_missing=True)
wb = db.write_batch()
bar = progressbar.ProgressBar(redirect_stdout=True)
print 'Collecting input coins for block'
print('Collecting input coins for block')
for tx in bar(unique_inputs.keys()):
rawtx = json.loads(subprocess.check_output([HUSH_CLI, 'getrawtransaction', tx, '1']))
@@ -258,7 +259,7 @@ def create_benchmark_archive(blk_hash):
tar.add(name, recursive=False, filter=deterministic_filter)
tar.close()
subprocess.check_call(['xz', '-6', archive_name])
print 'Created archive %s.xz' % archive_name
print(('Created archive %s.xz' % archive_name))
subprocess.call(['rm', '-r', 'benchmark'])
if __name__ == '__main__':

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2017 The Zcash developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -25,7 +25,7 @@ from decimal import Decimal
class LargeWalletTest(BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 2)
def setup_network(self):
@@ -48,10 +48,10 @@ class LargeWalletTest(BitcoinTestFramework):
self.nodes[1].generate(1)
self.sync_all()
print('Node 0: %d transactions, %d UTXOs' %
(len(self.nodes[0].listtransactions()), len(self.nodes[0].listunspent())))
print('Node 1: %d transactions, %d UTXOs' %
(len(self.nodes[1].listtransactions()), len(self.nodes[1].listunspent())))
print(('Node 0: %d transactions, %d UTXOs' %
(len(self.nodes[0].listtransactions()), len(self.nodes[0].listunspent()))))
print(('Node 1: %d transactions, %d UTXOs' %
(len(self.nodes[1].listtransactions()), len(self.nodes[1].listunspent()))))
assert_equal(len(self.nodes[0].listunspent()), len(inputs))
if __name__ == '__main__':

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Distributed under the GPLv3 software license, see the accompanying
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
@@ -36,10 +36,10 @@ def test_rpath_runpath(filename):
[repofile('qa/hush/checksec.sh'), '--file', repofile(filename)]
)
if RE_RPATH_RUNPATH.search(output):
print('PASS: %s has no RPATH or RUNPATH.' % filename)
print(('PASS: %s has no RPATH or RUNPATH.' % filename))
return True
else:
print('FAIL: %s has an RPATH or a RUNPATH.' % filename)
print(('FAIL: %s has an RPATH or a RUNPATH.' % filename))
print(output)
return False
@@ -52,10 +52,10 @@ def test_fortify_source(filename):
line2 = proc.stdout.readline()
proc.terminate()
if RE_FORTIFY_AVAILABLE.search(line1) and RE_FORTIFY_USED.search(line2):
print('PASS: %s has FORTIFY_SOURCE.' % filename)
print(('PASS: %s has FORTIFY_SOURCE.' % filename))
return True
else:
print('FAIL: %s is missing FORTIFY_SOURCE.' % filename)
print(('FAIL: %s is missing FORTIFY_SOURCE.' % filename))
return False
def check_security_hardening():
@@ -105,18 +105,18 @@ def ensure_no_dot_so_in_depends():
for lib in libraries:
if lib.find(".so") != -1:
print lib
print(lib)
exit_code = 1
else:
exit_code = 2
print "arch-specific build dir not present"
print "Did you build the ./depends tree?"
print "Are you on a currently unsupported architecture?"
print("arch-specific build dir not present")
print("Did you build the ./depends tree?")
print("Are you on a currently unsupported architecture?")
if exit_code == 0:
print "PASS."
print("PASS.")
else:
print "FAIL."
print("FAIL.")
return exit_code == 0
@@ -160,9 +160,9 @@ STAGE_COMMANDS = {
#
def run_stage(stage):
print('Running stage %s' % stage)
print('=' * (len(stage) + 14))
print
print(('Running stage %s' % stage))
print(('=' * (len(stage) + 14)))
print()
cmd = STAGE_COMMANDS[stage]
if type(cmd) == type([]):
@@ -170,10 +170,10 @@ def run_stage(stage):
else:
ret = cmd()
print
print('-' * (len(stage) + 15))
print('Finished stage %s' % stage)
print
print()
print(('-' * (len(stage) + 15)))
print(('Finished stage %s' % stage))
print()
return ret
@@ -193,7 +193,7 @@ def main():
# Check validity of stages
for s in args.stage:
if s not in STAGES:
print("Invalid stage '%s' (choose from %s)" % (s, STAGES))
print(("Invalid stage '%s' (choose from %s)" % (s, STAGES)))
sys.exit(1)
# Run the stages

View File

@@ -0,0 +1,37 @@
# Release Test Reports
This directory contains test reports for notable commits — releases, protocol
activations, and validation milestones. These are committed to git as an
auditable record that tests passed at specific points in the project history.
## Generating a release report
```bash
# Default: names the file with chain-commit-timestamp
./qa/run-tests.sh --save-release
# With a tag (e.g. for a version release)
./qa/run-tests.sh --save-release=v3.10.5
# DragonX chain profile with a tag
./qa/run-tests.sh --chain=dragonx --save-release=dragonx-activation
# Live DragonX node validation with a tag
./qa/run-tests.sh --live-dragonx --save-release=dragonx-live-v3.10.5
```
## Naming convention
Reports are named: `{chain}-{tag}-{commit}.txt` or `{chain}-{commit}-{timestamp}.txt`
Examples:
- `hush3-v3.10.5-20aeebb.txt`
- `dragonx-activation-20aeebb.txt`
- `hush3-20aeebb-20260227_210000.txt`
## When to commit a report
- Before tagging a release
- After enabling/activating a protocol change (e.g. RandomX validation)
- After significant code changes to consensus, mining, or validation
- When onboarding a new chain (e.g. DragonX support)

View File

@@ -0,0 +1,71 @@
==============================================================================
HUSH3 Release Test Report
Chain: hush3 | Commit: 20aeebb83 | Branch: master
Generated: 2026-02-28 04:22:10 UTC
==============================================================================
Total: 48
Passed: 41
Failed: 0
Skipped: 7
---------- Results ----------
PASS hushd binary exists /home/d/randomxValidationBug/hush3/src/hushd: ELF 64-bit LSB pie executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=b72c50a80fec950e823f85cd6dcfeda4579d1f2c, for GNU/Linux 3.2.0, with debug_info, not stripped
PASS hush-cli binary exists
PASS hush-tx binary exists
PASS hushd is native ELF binary
SKIP hush-gtest binary exists not found (test binaries not built)
SKIP test_bitcoin binary exists not found (test binaries not built)
PASS PIE (Position Independent Executable)
PASS NX (non-executable stack) (no RWE found)
PASS RELRO (relocation read-only)
PASS Stack canary (__stack_chk_fail)
SKIP FORTIFY_SOURCE symbol not found (may still be enabled)
PASS No RPATH/RUNPATH
SKIP test_bitcoin (Boost unit tests) binary not available
SKIP hush-gtest (Google Test suite) binary not available
SKIP secp256k1 tests build error (see log) — cross-compiled tree?
PASS univalue tests
PASS RandomX chain launch PID=425864
PASS RPC availability
PASS Mine 40 RandomX blocks reached height 44
PASS Block nSolution is 32 bytes (RandomX) checked 4 blocks
PASS Chain name matches RXTEST_20260227_222114
PASS RandomX key rotation (past height 37) chain valid through height 44
PASS getinfo sanity check
PASS Memory usage < 4GB 2741MB RSS
PASS getmininginfo responds
PASS Address generation & validation
PASS No RandomX hash mismatches in log valid=135
PASS Graceful shutdown
SKIP RPC integration tests HUSH3 regtest mining not functional (RandomX PoW)
PASS CheckRandomXSolution() in pow.cpp
PASS CheckRandomXSolution() declared in pow.h
PASS block_processing.cpp calls CheckRandomXSolution
PASS hush_bitcoind.h calls CheckRandomXSolution
PASS CRandomXInput class in block.h
PASS ASSETCHAINS_RANDOMX_VALIDATION global
PASS Miner uses CRandomXInput serialization
PASS Miner skips self-validation (OOM fix)
PASS DragonX checkpoint data file exists 2853 lines
PASS chainparams.cpp includes DragonX checkpoints
PASS DragonX seed nodes defined 6 nodes
PASS isdragonx chain detection
PASS DragonX validation height (2838976)
PASS DragonX launch script (dragonxd)
PASS dragonxd has correct chain params ac_name, ac_algo, ac_private verified
PASS DragonX blocktime=36 in launch script
PASS DragonX halving=3500000 in launch script
PASS DragonX reward=300000000 in launch script
PASS DragonX uses hush-arrakis-chain wrapper
---------- Environment ----------
OS: Linux 6.6.87.2-microsoft-standard-WSL2
Arch: x86_64
GCC: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0
Python: Python 3.10.12
Date: 2026-02-28 04:22:10 UTC
==============================================================================

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2018 SuperNET developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -29,7 +29,7 @@ def generate_random_string(length):
class AssetChainPrivateTest (BitcoinTestFramework):
def setup_chain(self):
print("Initializing ac_private test directory "+self.options.tmpdir)
print(("Initializing ac_private test directory "+self.options.tmpdir))
self.num_nodes = 1
initialize_chain_clean(self.options.tmpdir, self.num_nodes)
@@ -78,7 +78,7 @@ class AssetChainPrivateTest (BitcoinTestFramework):
rpc.getwalletinfo()
taddr = rpc.getnewaddress()
print "Sending to " + taddr
print(("Sending to " + taddr))
# sending to arbitrary non-notary transparent address is not allowed
assert_raises(JSONRPCException, rpc.sendtoaddress, taddr,1)

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2014-2015 The Bitcoin Core developers
# Copyright (c) 2016-2024 The Hush developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -15,7 +15,7 @@ import binascii
class AddressIndexTest(BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 4)
def setup_network(self):
@@ -34,7 +34,7 @@ class AddressIndexTest(BitcoinTestFramework):
self.sync_all()
def run_test(self):
print "Mining blocks..."
print("Mining blocks...")
self.nodes[0].generate(105)
self.sync_all()
@@ -48,7 +48,7 @@ class AddressIndexTest(BitcoinTestFramework):
assert_equal(balance0["balance"], 0)
# Check p2pkh and p2sh address indexes
print "Testing p2pkh and p2sh address index..."
print("Testing p2pkh and p2sh address index...")
txid0 = self.nodes[0].sendtoaddress("mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", 10)
self.nodes[0].generate(1)
@@ -83,7 +83,7 @@ class AddressIndexTest(BitcoinTestFramework):
assert_equal(txidsb[2], txidb2)
# Check that limiting by height works
print "Testing querying txids by range of block heights.."
print("Testing querying txids by range of block heights..")
height_txids = self.nodes[1].getaddresstxids({
"addresses": ["2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br"],
"start": 105,
@@ -108,7 +108,7 @@ class AddressIndexTest(BitcoinTestFramework):
assert_equal(balance0["balance"], 45 * 100000000)
# Check that outputs with the same address will only return one txid
print "Testing for txid uniqueness..."
print("Testing for txid uniqueness...")
addressHash = "6349a418fc4578d10a372b54b45c280cc8c4382f".decode("hex")
scriptPubKey = CScript([OP_HASH160, addressHash, OP_EQUAL])
unspent = self.nodes[0].listunspent()
@@ -128,12 +128,12 @@ class AddressIndexTest(BitcoinTestFramework):
assert_equal(txidsmany[3], sent_txid)
# Check that balances are correct
print "Testing balances..."
print("Testing balances...")
balance0 = self.nodes[1].getaddressbalance("2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br")
assert_equal(balance0["balance"], 45 * 100000000 + 21)
# Check that balances are correct after spending
print "Testing balances after spending..."
print("Testing balances after spending...")
privkey2 = "cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG"
address2 = "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW"
addressHash2 = "0b2f0a0c31bfe0406b0ccc1381fdbe311946dadc".decode("hex")
@@ -186,13 +186,13 @@ class AddressIndexTest(BitcoinTestFramework):
assert_equal(len(deltas), 1)
# Check that unspent outputs can be queried
print "Testing utxos..."
print("Testing utxos...")
utxos = self.nodes[1].getaddressutxos({"addresses": [address2]})
assert_equal(len(utxos), 1)
assert_equal(utxos[0]["satoshis"], change_amount)
# Check that indexes will be updated with a reorg
print "Testing reorg..."
print("Testing reorg...")
best_hash = self.nodes[0].getbestblockhash()
self.nodes[0].invalidateblock(best_hash)
@@ -224,7 +224,7 @@ class AddressIndexTest(BitcoinTestFramework):
assert_equal(utxos3[2]["height"], 265)
# Check mempool indexing
print "Testing mempool indexing..."
print("Testing mempool indexing...")
privKey3 = "cVfUn53hAbRrDEuMexyfgDpZPhF7KqXpS8UZevsyTDaugB7HZ3CD"
address3 = "mw4ynwhS7MmrQ27hr82kgqu7zryNDK26JB"
@@ -320,7 +320,7 @@ class AddressIndexTest(BitcoinTestFramework):
assert_equal(len(mempool_deltas), 2)
# Include chaininfo in results
print "Testing results with chain info..."
print("Testing results with chain info...")
deltas_with_info = self.nodes[1].getaddressdeltas({
"addresses": [address2],
@@ -340,7 +340,7 @@ class AddressIndexTest(BitcoinTestFramework):
assert_equal(utxos_with_info["height"], 267)
assert_equal(utxos_with_info["hash"], expected_tip_block_hash)
print "Passed\n"
print("Passed\n")
if __name__ == '__main__':

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Distributed under the GPLv3 software license, see the accompanying
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Distributed under the GPLv3 software license, see the accompanying
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
@@ -10,7 +10,7 @@ from test_framework.blocktools import create_coinbase, create_block
from test_framework.comptool import TestInstance, TestManager
from test_framework.script import CScript, OP_1NEGATE, OP_NOP2, OP_DROP
from binascii import unhexlify
import cStringIO
import io
'''
@@ -47,7 +47,7 @@ class BIP65Test(ComparisonTestFramework):
rawtx = node.createrawtransaction(inputs, outputs)
signresult = node.signrawtransaction(rawtx)
tx = CTransaction()
f = cStringIO.StringIO(unhexlify(signresult['hex']))
f = io.StringIO(unhexlify(signresult['hex']))
tx.deserialize(f)
return tx

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Distributed under the GPLv3/X11 software license, see the accompanying
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
@@ -11,7 +11,7 @@ from test_framework.blocktools import create_coinbase, create_block
from test_framework.comptool import TestInstance, TestManager
from test_framework.script import CScript
from binascii import unhexlify
import cStringIO
import io
'''
@@ -47,7 +47,7 @@ class BIP66Test(ComparisonTestFramework):
rawtx = node.createrawtransaction(inputs, outputs)
signresult = node.signrawtransaction(rawtx)
tx = CTransaction()
f = cStringIO.StringIO(unhexlify(signresult['hex']))
f = io.StringIO(unhexlify(signresult['hex']))
tx.deserialize(f)
return tx

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -28,7 +28,7 @@ class BlockchainTest(BitcoinTestFramework):
"""
def setup_chain(self):
print("Initializing test directory " + self.options.tmpdir)
print(("Initializing test directory " + self.options.tmpdir))
initialize_chain(self.options.tmpdir)
def setup_network(self, split=False):
@@ -41,13 +41,13 @@ class BlockchainTest(BitcoinTestFramework):
node = self.nodes[0]
res = node.gettxoutsetinfo()
assert_equal(res[u'total_amount'], decimal.Decimal('2181.25000000')) # 150*12.5 + 49*6.25
assert_equal(res[u'transactions'], 200)
assert_equal(res[u'height'], 200)
assert_equal(res[u'txouts'], 349) # 150*2 + 49
assert_equal(res[u'bytes_serialized'], 14951), # 32*199 + 48*90 + 49*60 + 27*49
assert_equal(len(res[u'bestblock']), 64)
assert_equal(len(res[u'hash_serialized']), 64)
assert_equal(res['total_amount'], decimal.Decimal('2181.25000000')) # 150*12.5 + 49*6.25
assert_equal(res['transactions'], 200)
assert_equal(res['height'], 200)
assert_equal(res['txouts'], 349) # 150*2 + 49
assert_equal(res['bytes_serialized'], 14951), # 32*199 + 48*90 + 49*60 + 27*49
assert_equal(len(res['bestblock']), 64)
assert_equal(len(res['hash_serialized']), 64)
if __name__ == '__main__':

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2015 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -9,14 +9,14 @@ from test_framework.util import assert_equal, initialize_chain_clean, \
start_nodes
from test_framework.mininode import CTransaction
from binascii import hexlify, unhexlify
from cStringIO import StringIO
from io import StringIO
class DecodeScriptTest(BitcoinTestFramework):
"""Tests decoding scripts via RPC command "decodescript"."""
def setup_chain(self):
print('Initializing test directory ' + self.options.tmpdir)
print(('Initializing test directory ' + self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 1)
def setup_network(self, split=False):
@@ -177,7 +177,7 @@ class DecodeScriptTest(BitcoinTestFramework):
# in fact, it contains an OP_RETURN with data specially crafted to cause improper decode if the code does not catch it.
txSave.vin[0].scriptSig = unhexlify('6a143011020701010101010101020601010101010101')
rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize()))
print(hexlify('636174'))
print((hexlify('636174')))
assert_equal('OP_RETURN 3011020701010101010101020601010101010101', rpc_result['vin'][0]['scriptSig']['asm'])
def run_test(self):

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -15,7 +15,7 @@ from test_framework.util import initialize_chain_clean, start_nodes
class DisableWalletTest (BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 1)
def setup_network(self, split=False):

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2019 Duke Leto who wrote "The SuperNET developers" while never agreeing to the developer agreement nor being listed in AUTHORS
# Distributed under the GPLv3 software license, see the accompanying
@@ -11,20 +11,20 @@ import time
class DPoWConfsTest(BitcoinTestFramework):
def debug_info(self):
rpc = self.nodes[0]
print "-- DEBUG --"
print("-- DEBUG --")
getinfo = rpc.getinfo()
getwalletinfo = rpc.getwalletinfo()
listreceivedbyaddress = rpc.listreceivedbyaddress()
print "notarized=", getinfo['notarized'], " blocks=", getinfo['blocks']
print(("notarized=", getinfo['notarized'], " blocks=", getinfo['blocks']))
#print "getinfo=", getinfo
print "balance=", getwalletinfo['balance']
print(("balance=", getwalletinfo['balance']))
#print "getwalletinfo=", getwalletinfo
print "listreceivedbyaddress=", listreceivedbyaddress
print "-- DEBUG --"
print(("listreceivedbyaddress=", listreceivedbyaddress))
print("-- DEBUG --")
def setup_chain(self):
self.num_nodes = 1
print("Initializing DPoWconfs test directory "+self.options.tmpdir)
print(("Initializing DPoWconfs test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, self.num_nodes)
def setup_network(self):
@@ -71,8 +71,8 @@ class DPoWConfsTest(BitcoinTestFramework):
self.debug_info()
info = rpc.getinfo()
print "notarizedhash=", notarizedhash, "\n"
print "info[notarizedhash]", info['notarizedhash'], "\n"
print(("notarizedhash=", notarizedhash, "\n"))
print(("info[notarizedhash]", info['notarizedhash'], "\n"))
assert_equal( info['notarizedhash'], notarizedhash)
result = rpc.listunspent()
@@ -90,22 +90,22 @@ class DPoWConfsTest(BitcoinTestFramework):
self.debug_info()
minconf = 2
result = rpc.listreceivedbyaddress(minconf)
print "listreceivedbyaddress(2)=", result, "\n"
print(("listreceivedbyaddress(2)=", result, "\n"))
# nothing is notarized, so we should see no results for minconf=2
assert len(result) == 0
print "getreceivedaddress"
print("getreceivedaddress")
received = rpc.getreceivedbyaddress(taddr, minconf)
assert_equal( received, 0.00000000)
#received = rpc.getreceivedbyaddress(taddr)
#assert_equal( received, "5.55000000")
taddr = rpc.getnewaddress()
zaddr = rpc.z_getnewaddress()
# should get insufficient funds error
recipients = [ { "amount" : Decimal('4.20'), "address" : zaddr } ]
txid = rpc.z_sendmany( taddr, recipients, minconf)
taddr = rpc.getnewaddress()
zaddr = rpc.z_getnewaddress()
# should get insufficient funds error
recipients = [ { "amount" : Decimal('4.20'), "address" : zaddr } ]
txid = rpc.z_sendmany( taddr, recipients, minconf)
# generate a notarized block, block 105 and block 106
# only generating the notarized block seems to have
@@ -115,9 +115,9 @@ class DPoWConfsTest(BitcoinTestFramework):
getinfo = rpc.getinfo()
# try to allow notarization data to update
print "Sleeping"
print("Sleeping")
while (getinfo['blocks'] != 106) or (getinfo['notarized'] != 105):
printf(".")
print(".")
time.sleep(1)
getinfo = rpc.getinfo()
@@ -126,7 +126,7 @@ class DPoWConfsTest(BitcoinTestFramework):
#assert_equal(getinfo['notarizedhash'], txids[0])
result = rpc.listreceivedbyaddress(minconf)
print "listreceivedbyaddress(2)=", result
print(("listreceivedbyaddress(2)=", result))
assert_equal( len(result), 1, 'got one xtn with minconf=2' )
@@ -134,13 +134,13 @@ class DPoWConfsTest(BitcoinTestFramework):
assert_greater_than( result[0]['confirmations'], 1)
assert_greater_than( result[0]['rawconfirmations'], 1)
print "listtransactions"
print("listtransactions")
xtns = rpc.listtransactions()
# verify this rpc agrees with listreceivedbyaddress
assert_greater_than(xtns[0]['confirmations'], 1)
assert_greater_than(xtns[0]['rawconfirmations'], 1)
print "getreceivedaddress"
print("getreceivedaddress")
received = rpc.getreceivedbyaddress(taddr, minconf)
assert_equal( "%.8f" % received, "5.55000000")

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2018 The Zcash developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -23,7 +23,7 @@ NULL_FIELD = "0000000000000000000000000000000000000000000000000000000000000000"
class FinalSaplingRootTest(BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 4)
def setup_network(self, split=False):
@@ -50,7 +50,7 @@ class FinalSaplingRootTest(BitcoinTestFramework):
# Verify all generated blocks contain the empty root of the Sapling tree.
blockcount = self.nodes[0].getblockcount()
for height in xrange(1, blockcount + 1):
for height in range(1, blockcount + 1):
blk = self.nodes[0].getblock(str(height))
assert_equal(blk["finalsaplingroot"], SAPLING_TREE_EMPTY_ROOT)

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -16,7 +16,7 @@ from decimal import Decimal
class RawTransactionsTest(BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 3)
def setup_network(self, split=False):
@@ -31,7 +31,7 @@ class RawTransactionsTest(BitcoinTestFramework):
self.sync_all()
def run_test(self):
print "Mining blocks..."
print("Mining blocks...")
feeTolerance = Decimal(0.00000002) #if the fee's positive delta is higher than this value tests will fail, neg. delta always fail the tests
self.nodes[2].generate(1)
@@ -193,7 +193,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0
for i, out in enumerate(dec_tx['vout']):
totalOut += out['value']
if outputs.has_key(out['scriptPubKey']['addresses'][0]):
if out['scriptPubKey']['addresses'][0] in outputs:
matchingOuts+=1
else:
assert_equal(i, rawtxfund['changepos'])
@@ -233,7 +233,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0
for out in dec_tx['vout']:
totalOut += out['value']
if outputs.has_key(out['scriptPubKey']['addresses'][0]):
if out['scriptPubKey']['addresses'][0] in outputs:
matchingOuts+=1
assert_equal(matchingOuts, 1)
@@ -275,7 +275,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0
for out in dec_tx['vout']:
totalOut += out['value']
if outputs.has_key(out['scriptPubKey']['addresses'][0]):
if out['scriptPubKey']['addresses'][0] in outputs:
matchingOuts+=1
assert_equal(matchingOuts, 2)
@@ -293,7 +293,7 @@ class RawTransactionsTest(BitcoinTestFramework):
errorString = ""
try:
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
except JSONRPCException,e:
except JSONRPCException as e:
errorString = e.error['message']
assert_equal("Insufficient" in errorString, True);

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2016 The Zcash developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -15,7 +15,7 @@ class GetBlockTemplateTest(BitcoinTestFramework):
'''
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 4)
def setup_network(self, split=False):

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -52,7 +52,7 @@ class GetBlockTemplateLPTest(BitcoinTestFramework):
'''
def run_test(self):
print "Warning: this test will take about 70 seconds in the best case. Be patient."
print("Warning: this test will take about 70 seconds in the best case. Be patient.")
self.nodes[0].generate(10)
templat = self.nodes[0].getblocktemplate()
longpollid = templat['longpollid']

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
#
@@ -30,7 +30,7 @@ class HardForkDetectionTest(BitcoinTestFramework):
errorString = ""
try:
self.nodes[0].getbalance()
except JSONRPCException,e:
except JSONRPCException as e:
errorString = e.error['message']
assert_equal("Safe mode:" in errorString, True)

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -14,11 +14,11 @@ import base64
try:
import http.client as httplib
except ImportError:
import httplib
import http.client
try:
import urllib.parse as urlparse
except ImportError:
import urlparse
import urllib.parse
class HTTPBasicsTest (BitcoinTestFramework):
def setup_nodes(self):
@@ -29,11 +29,11 @@ class HTTPBasicsTest (BitcoinTestFramework):
#################################################
# lowlevel check for http persistent connection #
#################################################
url = urlparse.urlparse(self.nodes[0].url)
url = urllib.parse.urlparse(self.nodes[0].url)
authpair = url.username + ':' + url.password
headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
conn = httplib.HTTPConnection(url.hostname, url.port)
conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read()
@@ -50,7 +50,7 @@ class HTTPBasicsTest (BitcoinTestFramework):
# same should be if we add keep-alive because this should be the std. behaviour
headers = {"Authorization": "Basic " + base64.b64encode(authpair), "Connection": "keep-alive"}
conn = httplib.HTTPConnection(url.hostname, url.port)
conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read()
@@ -67,7 +67,7 @@ class HTTPBasicsTest (BitcoinTestFramework):
# now do the same with "Connection: close"
headers = {"Authorization": "Basic " + base64.b64encode(authpair), "Connection":"close"}
conn = httplib.HTTPConnection(url.hostname, url.port)
conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read()
@@ -75,22 +75,22 @@ class HTTPBasicsTest (BitcoinTestFramework):
assert_equal(conn.sock!=None, False) # now the connection must be closed after the response
# node1 (2nd node) is running with disabled keep-alive option
urlNode1 = urlparse.urlparse(self.nodes[1].url)
urlNode1 = urllib.parse.urlparse(self.nodes[1].url)
authpair = urlNode1.username + ':' + urlNode1.password
headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
conn = httplib.HTTPConnection(urlNode1.hostname, urlNode1.port)
conn = http.client.HTTPConnection(urlNode1.hostname, urlNode1.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read()
assert_equal('"error":null' in out1, True)
# node2 (third node) is running with standard keep-alive parameters which means keep-alive is on
urlNode2 = urlparse.urlparse(self.nodes[2].url)
urlNode2 = urllib.parse.urlparse(self.nodes[2].url)
authpair = urlNode2.username + ':' + urlNode2.password
headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port)
conn = http.client.HTTPConnection(urlNode2.hostname, urlNode2.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read()

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -16,7 +16,7 @@ import time
class InvalidateTest(BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 3)
def setup_network(self):
@@ -27,46 +27,46 @@ class InvalidateTest(BitcoinTestFramework):
self.nodes.append(start_node(2, self.options.tmpdir, ["-debug"]))
def run_test(self):
print "Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:"
print "Mine 4 blocks on Node 0"
print("Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:")
print("Mine 4 blocks on Node 0")
self.nodes[0].generate(4)
assert(self.nodes[0].getblockcount() == 4)
besthash = self.nodes[0].getbestblockhash()
print "Mine competing 6 blocks on Node 1"
print("Mine competing 6 blocks on Node 1")
self.nodes[1].generate(6)
assert(self.nodes[1].getblockcount() == 6)
print "Connect nodes to force a reorg"
print("Connect nodes to force a reorg")
connect_nodes_bi(self.nodes,0,1)
sync_blocks(self.nodes[0:2])
assert(self.nodes[0].getblockcount() == 6)
badhash = self.nodes[1].getblockhash(2)
print "Invalidate block 2 on node 0 and verify we reorg to node 0's original chain"
print("Invalidate block 2 on node 0 and verify we reorg to node 0's original chain")
self.nodes[0].invalidateblock(badhash)
newheight = self.nodes[0].getblockcount()
newhash = self.nodes[0].getbestblockhash()
if (newheight != 4 or newhash != besthash):
raise AssertionError("Wrong tip for node0, hash %s, height %d"%(newhash,newheight))
print "\nMake sure we won't reorg to a lower work chain:"
print("\nMake sure we won't reorg to a lower work chain:")
connect_nodes_bi(self.nodes,1,2)
print "Sync node 2 to node 1 so both have 6 blocks"
print("Sync node 2 to node 1 so both have 6 blocks")
sync_blocks(self.nodes[1:3])
assert(self.nodes[2].getblockcount() == 6)
print "Invalidate block 5 on node 1 so its tip is now at 4"
print("Invalidate block 5 on node 1 so its tip is now at 4")
self.nodes[1].invalidateblock(self.nodes[1].getblockhash(5))
assert(self.nodes[1].getblockcount() == 4)
print "Invalidate block 3 on node 2, so its tip is now 2"
print("Invalidate block 3 on node 2, so its tip is now 2")
self.nodes[2].invalidateblock(self.nodes[2].getblockhash(3))
assert(self.nodes[2].getblockcount() == 2)
print "..and then mine a block"
print("..and then mine a block")
self.nodes[2].generate(1)
print "Verify all nodes are at the right height"
print("Verify all nodes are at the right height")
time.sleep(5)
for i in xrange(3):
print i,self.nodes[i].getblockcount()
for i in range(3):
print((i,self.nodes[i].getblockcount()))
assert(self.nodes[2].getblockcount() == 3)
assert(self.nodes[0].getblockcount() == 4)
node1height = self.nodes[1].getblockcount()

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
#
# Distributed under the GPLv3/X11 software license, see the accompanying
@@ -59,7 +59,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework):
Now we need that block to mature so we can spend the coinbase.
'''
test = TestInstance(sync_every_block=False)
for i in xrange(100):
for i in range(100):
block = create_block(self.tip, create_coinbase(), self.block_time)
block.solve()
self.tip = block.sha256

View File

@@ -1,10 +1,11 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2019 Bartlomiej Lisiecki
# Distributed under the GPLv3 software license, see the accompanying
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
from decimal import Decimal
from functools import reduce
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, assert_greater_than, start_nodes,\
initialize_chain_clean, connect_nodes_bi, wait_and_assert_operationid_status
@@ -18,7 +19,7 @@ fee = Decimal('0.0001') # constant (but can be changed within reason)
class IVKImportExportTest (BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 4)
def setup_network(self, split=False):
@@ -49,13 +50,9 @@ class IVKImportExportTest (BitcoinTestFramework):
def verify_utxos(node, amts, zaddr):
amts.sort(reverse=True)
txs = node.z_listreceivedbyaddress(zaddr)
def cmp_confirmations_high_to_low(a, b):
return cmp(b["amount"], a["amount"])
txs.sort(cmp_confirmations_high_to_low)
print("Sorted txs", txs)
print("amts", amts)
txs.sort(key=lambda x: x["amount"], reverse=True)
print(("Sorted txs", txs))
print(("amts", amts))
try:
assert_equal(amts, [tx["amount"] for tx in txs])

View File

@@ -1,10 +1,11 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2017 The Zcash developers
# Distributed under the GPLv3 software license, see the accompanying
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
from decimal import Decimal
from functools import reduce
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, assert_greater_than, start_nodes, initialize_chain_clean, connect_nodes_bi
@@ -16,7 +17,7 @@ logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO)
class KeyImportExportTest (BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 4)
def setup_network(self, split=False):
@@ -39,11 +40,7 @@ class KeyImportExportTest (BitcoinTestFramework):
def verify_utxos(node, amounts):
utxos = node.listunspent(1, 10**9, [addr])
def cmp_confirmations_high_to_low(a, b):
return cmp(b["confirmations"], a["confirmations"])
utxos.sort(cmp_confirmations_high_to_low)
utxos.sort(key=lambda x: x["confirmations"], reverse=True)
try:
assert_equal(amounts, [utxo["amount"] for utxo in utxos])

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -50,7 +50,7 @@ def run_test(nodes, tmpdir):
try:
addr = nodes[0].getnewaddress()
raise AssertionError('Keypool should be exhausted after one address')
except JSONRPCException,e:
except JSONRPCException as e:
assert(e.error['code']==-12)
# put three new keys in the keypool
@@ -70,7 +70,7 @@ def run_test(nodes, tmpdir):
try:
addr = nodes[0].getrawchangeaddress()
raise AssertionError('Keypool should be exhausted after three addresses')
except JSONRPCException,e:
except JSONRPCException as e:
assert(e.error['code']==-12)
@@ -93,7 +93,7 @@ def main():
success = False
nodes = []
try:
print("Initializing test directory "+options.tmpdir)
print(("Initializing test directory "+options.tmpdir))
if not os.path.isdir(options.tmpdir):
os.makedirs(options.tmpdir)
initialize_chain(options.tmpdir)
@@ -105,12 +105,12 @@ def main():
success = True
except AssertionError as e:
print("Assertion failed: "+e.message)
print(("Assertion failed: "+e.message))
except JSONRPCException as e:
print("JSONRPC error: "+e.error['message'])
print(("JSONRPC error: "+e.error['message']))
traceback.print_tb(sys.exc_info()[2])
except Exception as e:
print("Unexpected exception caught during testing: "+str(sys.exc_info()[0]))
print(("Unexpected exception caught during testing: "+str(sys.exc_info()[0])))
traceback.print_tb(sys.exc_info()[2])
if not options.nocleanup:

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
#
# Distributed under the GPLv3/X11 software license, see the accompanying
@@ -74,9 +74,9 @@ class TestManager(NodeConnCB):
raise AssertionError("Error, test failed: block %064x requested more than once" % key)
if total_requests > MAX_REQUESTS:
raise AssertionError("Error, too many blocks (%d) requested" % total_requests)
print "Round %d: success (total requests: %d)" % (count, total_requests)
print(("Round %d: success (total requests: %d)" % (count, total_requests)))
except AssertionError as e:
print "TEST FAILED: ", e.args
print(("TEST FAILED: ", e.args))
self.disconnectOkay = True
self.connection.disconnect_node()
@@ -89,7 +89,7 @@ class MaxBlocksInFlightTest(BitcoinTestFramework):
help="Binary to test max block requests behavior")
def setup_chain(self):
print "Initializing test directory "+self.options.tmpdir
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 1)
def setup_network(self):

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2018 The Zcash developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -28,7 +28,7 @@ class MempoolUpgradeActivationTest(BitcoinTestFramework):
self.sync_all
def setup_chain(self):
print "Initializing test directory "+self.options.tmpdir
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 2)
def run_test(self):
@@ -45,7 +45,7 @@ class MempoolUpgradeActivationTest(BitcoinTestFramework):
node0_zaddr = self.nodes[0].z_getnewaddress()
recipients = [{'address': node0_zaddr, 'amount': Decimal('10')}]
myopid = self.nodes[1].z_sendmany(node1_taddr, recipients, 1, Decimal('0'))
print wait_and_assert_operationid_status(self.nodes[1], myopid)
print((wait_and_assert_operationid_status(self.nodes[1], myopid)))
self.sync_all()
# Mempool checks for activation of upgrade Y at height H on base X

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2018 The Zcash developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -37,13 +37,13 @@ class MempoolTxExpiryTest(BitcoinTestFramework):
self.nodes[0].generate(6)
self.sync_all()
print "Splitting network..."
print("Splitting network...")
self.split_network()
# When Overwinter is activated, test dependent txs
firstTx = self.nodes[0].sendtoaddress(alice, 0.1)
firstTxInfo = self.nodes[0].getrawtransaction(firstTx, 1)
print "First tx expiry height:", firstTxInfo['expiryheight']
print(("First tx expiry height:", firstTxInfo['expiryheight']))
# Mine first transaction
self.nodes[0].generate(1)
for outpoint in firstTxInfo['vout']:
@@ -57,19 +57,19 @@ class MempoolTxExpiryTest(BitcoinTestFramework):
assert(rawTxSigned['complete'])
secondTx = self.nodes[0].sendrawtransaction(rawTxSigned['hex'])
secondTxInfo = self.nodes[0].getrawtransaction(secondTx, 1)
print "Second tx expiry height:", secondTxInfo['expiryheight']
print(("Second tx expiry height:", secondTxInfo['expiryheight']))
# Mine second, dependent transaction
self.nodes[0].generate(1)
print "Mine 6 competing blocks on Node 2..."
print("Mine 6 competing blocks on Node 2...")
blocks = self.nodes[2].generate(6)
print "Connect nodes to force a reorg"
print("Connect nodes to force a reorg")
connect_nodes_bi(self.nodes,0,2)
self.is_network_split = False
print "Syncing blocks"
print("Syncing blocks")
sync_blocks(self.nodes)
print "Ensure that both txs are dropped from mempool of node 0"
print "Blockheight node 0:", self.nodes[0].getblockchaininfo()['blocks']
print "Blockheight node 2:", self.nodes[2].getblockchaininfo()['blocks']
print("Ensure that both txs are dropped from mempool of node 0")
print(("Blockheight node 0:", self.nodes[0].getblockchaininfo()['blocks']))
print(("Blockheight node 2:", self.nodes[2].getblockchaininfo()['blocks']))
assert_equal(set(self.nodes[0].getrawmempool()), set())
assert_equal(set(self.nodes[2].getrawmempool()), set())
@@ -81,10 +81,10 @@ class MempoolTxExpiryTest(BitcoinTestFramework):
# Get balance on node 0
bal = self.nodes[0].z_gettotalbalance()
print "Balance before zsend, after shielding 10: ", bal
print(("Balance before zsend, after shielding 10: ", bal))
assert_equal(Decimal(bal["private"]), Decimal("9.9999"))
print "Splitting network..."
print("Splitting network...")
self.split_network()
# Create transactions
@@ -100,121 +100,121 @@ class MempoolTxExpiryTest(BitcoinTestFramework):
assert_equal(rawtx["version"], 3)
assert_equal(rawtx["overwintered"], True)
assert_equal(rawtx["expiryheight"], blockheight + 5)
print "Blockheight at persist_transparent & persist_shielded creation:", self.nodes[0].getblockchaininfo()['blocks']
print "Expiryheight of persist_transparent:", rawtx['expiryheight']
print(("Blockheight at persist_transparent & persist_shielded creation:", self.nodes[0].getblockchaininfo()['blocks']))
print(("Expiryheight of persist_transparent:", rawtx['expiryheight']))
# Verify shielded transaction is version 3 intended for Overwinter branch
rawtx = self.nodes[0].getrawtransaction(persist_shielded, 1)
print "Expiryheight of persist_shielded", rawtx['expiryheight']
print(("Expiryheight of persist_shielded", rawtx['expiryheight']))
assert_equal(rawtx["version"], 3)
assert_equal(rawtx["overwintered"], True)
assert_equal(rawtx["expiryheight"], blockheight + 5)
print "\n Blockheight advances to less than expiry block height. After reorg, txs should persist in mempool"
print("\n Blockheight advances to less than expiry block height. After reorg, txs should persist in mempool")
assert(persist_transparent in self.nodes[0].getrawmempool())
assert(persist_shielded in self.nodes[0].getrawmempool())
assert_equal(set(self.nodes[2].getrawmempool()), set())
print "mempool node 0:", self.nodes[0].getrawmempool()
print "mempool node 2:", self.nodes[2].getrawmempool()
print(("mempool node 0:", self.nodes[0].getrawmempool()))
print(("mempool node 2:", self.nodes[2].getrawmempool()))
bal = self.nodes[0].z_gettotalbalance()
print "Printing balance before persist_shielded & persist_transparent are initially mined from mempool", bal
print(("Printing balance before persist_shielded & persist_transparent are initially mined from mempool", bal))
# Txs are mined on node 0; will later be rolled back
self.nodes[0].generate(1)
print "Node 0 generated 1 block"
print "Node 0 height:", self.nodes[0].getblockchaininfo()['blocks']
print "Node 2 height:", self.nodes[2].getblockchaininfo()['blocks']
print("Node 0 generated 1 block")
print(("Node 0 height:", self.nodes[0].getblockchaininfo()['blocks']))
print(("Node 2 height:", self.nodes[2].getblockchaininfo()['blocks']))
bal = self.nodes[0].z_gettotalbalance()
print "Printing balance after persist_shielded & persist_transparent are mined:", bal
print(("Printing balance after persist_shielded & persist_transparent are mined:", bal))
assert_equal(set(self.nodes[0].getrawmempool()), set())
print "Mine 2 competing blocks on Node 2..."
print("Mine 2 competing blocks on Node 2...")
blocks = self.nodes[2].generate(2)
for block in blocks:
blk = self.nodes[2].getblock(block)
print "Height: {0}, Mined block txs: {1}".format(blk["height"], blk["tx"])
print "Connect nodes to force a reorg"
print(("Height: {0}, Mined block txs: {1}".format(blk["height"], blk["tx"])))
print("Connect nodes to force a reorg")
connect_nodes_bi(self.nodes,0,2)
self.is_network_split = False
print "Syncing blocks"
print("Syncing blocks")
sync_blocks(self.nodes)
print "Ensure that txs are back in mempool of node 0"
print "Blockheight node 0:", self.nodes[0].getblockchaininfo()['blocks']
print "Blockheight node 2:", self.nodes[2].getblockchaininfo()['blocks']
print "mempool node 0: ", self.nodes[0].getrawmempool()
print "mempool node 2: ", self.nodes[2].getrawmempool()
print("Ensure that txs are back in mempool of node 0")
print(("Blockheight node 0:", self.nodes[0].getblockchaininfo()['blocks']))
print(("Blockheight node 2:", self.nodes[2].getblockchaininfo()['blocks']))
print(("mempool node 0: ", self.nodes[0].getrawmempool()))
print(("mempool node 2: ", self.nodes[2].getrawmempool()))
assert(persist_transparent in self.nodes[0].getrawmempool())
assert(persist_shielded in self.nodes[0].getrawmempool())
bal = self.nodes[0].z_gettotalbalance()
# Mine txs to get them out of the way of mempool sync in split_network()
print "Generating another block on node 0 to clear txs from mempool"
print("Generating another block on node 0 to clear txs from mempool")
self.nodes[0].generate(1)
assert_equal(set(self.nodes[0].getrawmempool()), set())
sync_blocks(self.nodes)
print "Splitting network..."
print("Splitting network...")
self.split_network()
print "\n Blockheight advances to equal expiry block height. After reorg, txs should persist in mempool"
print("\n Blockheight advances to equal expiry block height. After reorg, txs should persist in mempool")
myopid = self.nodes[0].z_sendmany(z_alice, recipients)
persist_shielded_2 = wait_and_assert_operationid_status(self.nodes[0], myopid)
persist_transparent_2 = self.nodes[0].sendtoaddress(bob, 0.01)
rawtx_trans = self.nodes[0].getrawtransaction(persist_transparent_2, 1)
rawtx_shield = self.nodes[0].getrawtransaction(persist_shielded_2, 1)
print "Blockheight node 0 at persist_transparent_2 creation:", self.nodes[0].getblockchaininfo()['blocks']
print "Blockheight node 2 at persist_transparent_2 creation:", self.nodes[2].getblockchaininfo()['blocks']
print "Expiryheight of persist_transparent_2:", rawtx_trans['expiryheight']
print "Expiryheight of persist_shielded_2:", rawtx_shield['expiryheight']
print(("Blockheight node 0 at persist_transparent_2 creation:", self.nodes[0].getblockchaininfo()['blocks']))
print(("Blockheight node 2 at persist_transparent_2 creation:", self.nodes[2].getblockchaininfo()['blocks']))
print(("Expiryheight of persist_transparent_2:", rawtx_trans['expiryheight']))
print(("Expiryheight of persist_shielded_2:", rawtx_shield['expiryheight']))
blocks = self.nodes[2].generate(4)
for block in blocks:
blk = self.nodes[2].getblock(block)
print "Height: {0}, Mined block txs: {1}".format(blk["height"], blk["tx"])
print "Connect nodes to force a reorg"
print(("Height: {0}, Mined block txs: {1}".format(blk["height"], blk["tx"])))
print("Connect nodes to force a reorg")
connect_nodes_bi(self.nodes, 0, 2)
self.is_network_split = False
sync_blocks(self.nodes)
print "Ensure that persist_transparent_2 & persist_shielded_2 are in mempool at expiry block height"
print "Blockheight node 0:", self.nodes[0].getblockchaininfo()['blocks']
print "Blockheight node 2:", self.nodes[2].getblockchaininfo()['blocks']
print "mempool node 0: ", self.nodes[0].getrawmempool()
print "mempool node 2: ", self.nodes[2].getrawmempool()
print("Ensure that persist_transparent_2 & persist_shielded_2 are in mempool at expiry block height")
print(("Blockheight node 0:", self.nodes[0].getblockchaininfo()['blocks']))
print(("Blockheight node 2:", self.nodes[2].getblockchaininfo()['blocks']))
print(("mempool node 0: ", self.nodes[0].getrawmempool()))
print(("mempool node 2: ", self.nodes[2].getrawmempool()))
assert(persist_transparent_2 in self.nodes[0].getrawmempool())
assert(persist_shielded_2 in self.nodes[0].getrawmempool())
# Mine persist txs to get them out of the way of mempool sync in split_network()
self.nodes[0].generate(1)
assert_equal(set(self.nodes[0].getrawmempool()), set())
sync_blocks(self.nodes)
print "Balance after persist_shielded_2 is mined to remove from mempool: ", self.nodes[0].z_gettotalbalance()
print(("Balance after persist_shielded_2 is mined to remove from mempool: ", self.nodes[0].z_gettotalbalance()))
print "Splitting network..."
print("Splitting network...")
self.split_network()
print "\n Blockheight advances to greater than expiry block height. After reorg, txs should expire from mempool"
print "Balance before expire_shielded is sent: ", self.nodes[0].z_gettotalbalance()
print("\n Blockheight advances to greater than expiry block height. After reorg, txs should expire from mempool")
print(("Balance before expire_shielded is sent: ", self.nodes[0].z_gettotalbalance()))
myopid = self.nodes[0].z_sendmany(z_alice, recipients)
expire_shielded = wait_and_assert_operationid_status(self.nodes[0], myopid)
expire_transparent = self.nodes[0].sendtoaddress(bob, 0.01)
print "Blockheight node 0 at expire_transparent creation:", self.nodes[0].getblockchaininfo()['blocks']
print "Blockheight node 2 at expire_shielded creation:", self.nodes[2].getblockchaininfo()['blocks']
print "Expiryheight of expire_transparent:", self.nodes[0].getrawtransaction(expire_transparent, 1)['expiryheight']
print "Expiryheight of expire_shielded:", self.nodes[0].getrawtransaction(expire_shielded, 1)['expiryheight']
print(("Blockheight node 0 at expire_transparent creation:", self.nodes[0].getblockchaininfo()['blocks']))
print(("Blockheight node 2 at expire_shielded creation:", self.nodes[2].getblockchaininfo()['blocks']))
print(("Expiryheight of expire_transparent:", self.nodes[0].getrawtransaction(expire_transparent, 1)['expiryheight']))
print(("Expiryheight of expire_shielded:", self.nodes[0].getrawtransaction(expire_shielded, 1)['expiryheight']))
assert(expire_transparent in self.nodes[0].getrawmempool())
assert(expire_shielded in self.nodes[0].getrawmempool())
blocks = self.nodes[2].generate(6)
for block in blocks:
blk = self.nodes[2].getblock(block)
print "Height: {0}, Mined block txs: {1}".format(blk["height"], blk["tx"])
print "Connect nodes to force a reorg"
print(("Height: {0}, Mined block txs: {1}".format(blk["height"], blk["tx"])))
print("Connect nodes to force a reorg")
connect_nodes_bi(self.nodes, 0, 2)
self.is_network_split = False
sync_blocks(self.nodes)
print "Ensure that expire_transparent & expire_shielded are in mempool at expiry block height"
print "mempool node 0: ", self.nodes[0].getrawmempool()
print "mempool node 2: ", self.nodes[2].getrawmempool()
print("Ensure that expire_transparent & expire_shielded are in mempool at expiry block height")
print(("mempool node 0: ", self.nodes[0].getrawmempool()))
print(("mempool node 2: ", self.nodes[2].getrawmempool()))
assert_equal(set(self.nodes[0].getrawmempool()), set())
print "Ensure balance of node 0 is correct"
print("Ensure balance of node 0 is correct")
bal = self.nodes[0].z_gettotalbalance()
print "Balance after expire_shielded has expired: ", bal
print(("Balance after expire_shielded has expired: ", bal))
assert_equal(Decimal(bal["private"]), Decimal("7.9999"))

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2017 The Zcash developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -26,7 +26,7 @@ class MempoolTxInputLimitTest(BitcoinTestFramework):
self.sync_all
def setup_chain(self):
print "Initializing test directory "+self.options.tmpdir
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 2)
def call_z_sendmany(self, from_addr, to_addr, amount):
@@ -94,7 +94,7 @@ class MempoolTxInputLimitTest(BitcoinTestFramework):
try:
self.nodes[1].sendfrom("", node0_taddr, spend_taddr_amount - Decimal('1'))
assert(False)
except JSONRPCException,e:
except JSONRPCException as e:
msg = e.error['message']
assert_equal("Too many transparent inputs 3 > limit 2", msg)

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -18,7 +18,7 @@ from test_framework.util import assert_equal, assert_raises, \
class MerkleBlockTest(BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 4)
def setup_network(self):
@@ -37,7 +37,7 @@ class MerkleBlockTest(BitcoinTestFramework):
self.sync_all()
def run_test(self):
print "Mining blocks..."
print("Mining blocks...")
self.nodes[0].generate(105)
self.sync_all()

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -16,7 +16,7 @@ import time
try:
import urllib.parse as urlparse
except ImportError:
import urlparse
import urllib.parse
class NodeHandlingTest (BitcoinTestFramework):
def run_test(self):
@@ -50,7 +50,7 @@ class NodeHandlingTest (BitcoinTestFramework):
###########################
# RPC disconnectnode test #
###########################
url = urlparse.urlparse(self.nodes[1].url)
url = urllib.parse.urlparse(self.nodes[1].url)
self.nodes[0].disconnectnode(url.hostname+":"+str(p2p_port(1)))
time.sleep(2) #disconnecting a node needs a little bit of time
for node in self.nodes[0].getpeerinfo():

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Distributed under the GPLv3 software license, see the accompanying
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
@@ -118,7 +118,7 @@ class TestNspvClient(unittest.TestCase):
self.assertEqual(result["result"], "success")
self.assertEqual(result["retcode"], 1)
self.assertEqual(result["expected"], result["broadcast"])
print("Broadcast txid: " + result["broadcast"])
print(("Broadcast txid: " + result["broadcast"]))
time.sleep(1)
def test_nspv_logout(self):

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
#
# Distributed under the GPLv3/X11 software license, see the accompanying
@@ -158,7 +158,7 @@ class AcceptBlockTest(BitcoinTestFramework):
# This should be accepted.
blocks_h2 = [] # the height 2 blocks on each node's chain
block_time = time.time() + 1
for i in xrange(2):
for i in range(2):
blocks_h2.append(create_block(tips[i], create_coinbase(), block_time))
blocks_h2[i].solve()
block_time += 1
@@ -168,11 +168,11 @@ class AcceptBlockTest(BitcoinTestFramework):
[ x.sync_with_ping() for x in [test_node, white_node] ]
assert_equal(self.nodes[0].getblockcount(), 2)
assert_equal(self.nodes[1].getblockcount(), 2)
print "First height 2 block accepted by both nodes"
print("First height 2 block accepted by both nodes")
# 3. Send another block that builds on the original tip.
blocks_h2f = [] # Blocks at height 2 that fork off the main chain
for i in xrange(2):
for i in range(2):
blocks_h2f.append(create_block(tips[i], create_coinbase(), blocks_h2[i].nTime+1))
blocks_h2f[i].solve()
test_node.send_message(msg_block(blocks_h2f[0]))
@@ -187,11 +187,11 @@ class AcceptBlockTest(BitcoinTestFramework):
if x['hash'] == blocks_h2f[1].hash:
assert_equal(x['status'], "valid-headers")
print "Second height 2 block accepted only from allowlisted peer"
print("Second height 2 block accepted only from allowlisted peer")
# 4. Now send another block that builds on the forking chain.
blocks_h3 = []
for i in xrange(2):
for i in range(2):
blocks_h3.append(create_block(blocks_h2f[i].sha256, create_coinbase(), blocks_h2f[i].nTime+1))
blocks_h3[i].solve()
test_node.send_message(msg_block(blocks_h3[0]))
@@ -207,13 +207,13 @@ class AcceptBlockTest(BitcoinTestFramework):
# But this block should be accepted by node0 since it has more work.
try:
self.nodes[0].getblock(blocks_h3[0].hash)
print "Unrequested more-work block accepted from non-allowlisted peer"
print("Unrequested more-work block accepted from non-allowlisted peer")
except:
raise AssertionError("Unrequested more work block was not processed")
# Node1 should have accepted and reorged.
assert_equal(self.nodes[1].getblockcount(), 3)
print "Successfully reorged to length 3 chain from allowlisted peer"
print("Successfully reorged to length 3 chain from allowlisted peer")
# 4b. Now mine 288 more blocks and deliver; all should be processed but
# the last (height-too-high) on node0. Node1 should process the tip if
@@ -221,8 +221,8 @@ class AcceptBlockTest(BitcoinTestFramework):
tips = blocks_h3
headers_message = msg_headers()
all_blocks = [] # node0's blocks
for j in xrange(2):
for i in xrange(288):
for j in range(2):
for i in range(288):
next_block = create_block(tips[j].sha256, create_coinbase(), tips[j].nTime+1)
next_block.solve()
if j==0:
@@ -240,7 +240,7 @@ class AcceptBlockTest(BitcoinTestFramework):
raise AssertionError("Unrequested block too far-ahead should have been ignored")
except:
if x == all_blocks[287]:
print "Unrequested block too far-ahead not processed"
print("Unrequested block too far-ahead not processed")
else:
raise AssertionError("Unrequested block with more work should have been accepted")
@@ -250,7 +250,7 @@ class AcceptBlockTest(BitcoinTestFramework):
try:
white_node.sync_with_ping()
self.nodes[1].getblock(tips[1].hash)
print "Unrequested block far ahead of tip accepted from allowlisted peer"
print("Unrequested block far ahead of tip accepted from allowlisted peer")
except:
raise AssertionError("Unrequested block from allowlisted peer not accepted")
@@ -266,7 +266,7 @@ class AcceptBlockTest(BitcoinTestFramework):
# a getdata request for this block.
test_node.sync_with_ping()
assert_equal(self.nodes[0].getblockcount(), 2)
print "Unrequested block that would complete more-work chain was ignored"
print("Unrequested block that would complete more-work chain was ignored")
# 6. Try to get node to request the missing block.
# Poke the node with an inv for block at height 3 and see if that
@@ -282,14 +282,14 @@ class AcceptBlockTest(BitcoinTestFramework):
# Check that the getdata includes the right block
assert_equal(getdata.inv[0].hash, blocks_h2f[0].sha256)
print "Inv at tip triggered getdata for unprocessed block"
print("Inv at tip triggered getdata for unprocessed block")
# 7. Send the missing block for the third time (now it is requested)
test_node.send_message(msg_block(blocks_h2f[0]))
test_node.sync_with_ping()
assert_equal(self.nodes[0].getblockcount(), 290)
print "Successfully reorged to longer chain from non-allowlisted peer"
print("Successfully reorged to longer chain from non-allowlisted peer")
[ c.disconnect_node() for c in connections ]

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2018 The Zcash developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -47,7 +47,7 @@ class TestNode(NodeConnCB):
class NodeBloomTest(BitcoinTestFramework):
def setup_chain(self):
print "Initializing test directory "+self.options.tmpdir
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 2)
def setup_network(self):

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2018 The Zcash developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -10,7 +10,7 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import initialize_chain_clean, start_nodes, \
p2p_port, assert_equal
import time, cStringIO
import time, io
from binascii import hexlify, unhexlify
@@ -48,7 +48,7 @@ class TestNode(NodeConnCB):
class TxExpiryDoSTest(BitcoinTestFramework):
def setup_chain(self):
print "Initializing test directory "+self.options.tmpdir
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 1)
def setup_network(self):
@@ -63,13 +63,13 @@ class TxExpiryDoSTest(BitcoinTestFramework):
tx = CTransaction()
if txModifier:
f = cStringIO.StringIO(unhexlify(rawtx))
f = io.StringIO(unhexlify(rawtx))
tx.deserialize(f)
txModifier(tx)
rawtx = hexlify(tx.serialize())
signresult = node.signrawtransaction(rawtx)
f = cStringIO.StringIO(unhexlify(signresult['hex']))
f = io.StringIO(unhexlify(signresult['hex']))
tx.deserialize(f)
return tx

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2017 The Zcash developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -15,7 +15,7 @@ import time
class PrioritiseTransactionTest (BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 4)
def setup_network(self, split=False):
@@ -30,7 +30,7 @@ class PrioritiseTransactionTest (BitcoinTestFramework):
def run_test (self):
# tx priority is calculated: priority = sum(input_value_in_base_units * input_age)/size_in_bytes
print "Mining 11kb blocks..."
print("Mining 11kb blocks...")
self.nodes[0].generate(501)
base_fee = self.nodes[0].getnetworkinfo()['relayfee']

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2015 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -34,11 +34,11 @@ class PruneTest(BitcoinTestFramework):
# create one script_pubkey
script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes
for i in xrange (512):
for i in range (512):
script_pubkey = script_pubkey + "01"
# concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change
self.txouts = "81"
for k in xrange(128):
for k in range(128):
# add txout value
self.txouts = self.txouts + "0000000000000000"
# add length of script_pubkey
@@ -48,7 +48,7 @@ class PruneTest(BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 3)
def setup_network(self):
@@ -80,7 +80,7 @@ class PruneTest(BitcoinTestFramework):
sync_blocks(self.nodes[0:2])
self.nodes[0].generate(150)
# Then mine enough full blocks to create more than 550MB of data
for i in xrange(645):
for i in range(645):
self.mine_full_block(self.nodes[0], self.address[0])
sync_blocks(self.nodes[0:3])
@@ -88,11 +88,11 @@ class PruneTest(BitcoinTestFramework):
def test_height_min(self):
if not os.path.isfile(self.prunedir+"blk00000.dat"):
raise AssertionError("blk00000.dat is missing, pruning too early")
print "Success"
print "Though we're already using more than 550MB, current usage:", calc_usage(self.prunedir)
print "Mining 25 more blocks should cause the first block file to be pruned"
print("Success")
print(("Though we're already using more than 550MB, current usage:", calc_usage(self.prunedir)))
print("Mining 25 more blocks should cause the first block file to be pruned")
# Pruning doesn't run until we're allocating another chunk, 20 full blocks past the height cutoff will ensure this
for i in xrange(25):
for i in range(25):
self.mine_full_block(self.nodes[0],self.address[0])
waitstart = time.time()
@@ -101,17 +101,17 @@ class PruneTest(BitcoinTestFramework):
if time.time() - waitstart > 10:
raise AssertionError("blk00000.dat not pruned when it should be")
print "Success"
print("Success")
usage = calc_usage(self.prunedir)
print "Usage should be below target:", usage
print(("Usage should be below target:", usage))
if (usage > 550):
raise AssertionError("Pruning target not being met")
def create_chain_with_staleblocks(self):
# Create stale blocks in manageable sized chunks
print "Mine 24 (stale) blocks on Node 1, followed by 25 (main chain) block reorg from Node 0, for 12 rounds"
print("Mine 24 (stale) blocks on Node 1, followed by 25 (main chain) block reorg from Node 0, for 12 rounds")
for j in xrange(12):
for j in range(12):
# Disconnect node 0 so it can mine a longer reorg chain without knowing about node 1's soon-to-be-stale chain
# Node 2 stays connected, so it hears about the stale blocks and then reorg's when node0 reconnects
# Stopping node 0 also clears its mempool, so it doesn't have node1's transactions to accidentally mine
@@ -119,7 +119,7 @@ class PruneTest(BitcoinTestFramework):
self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=999000", "-checkblocks=5"], timewait=900)
# Mine 24 blocks in node 1
self.utxo = self.nodes[1].listunspent()
for i in xrange(24):
for i in range(24):
if j == 0:
self.mine_full_block(self.nodes[1],self.address[1])
else:
@@ -127,7 +127,7 @@ class PruneTest(BitcoinTestFramework):
# Reorg back with 25 block chain from node 0
self.utxo = self.nodes[0].listunspent()
for i in xrange(25):
for i in range(25):
self.mine_full_block(self.nodes[0],self.address[0])
# Create connections in the order so both nodes can see the reorg at the same time
@@ -135,7 +135,7 @@ class PruneTest(BitcoinTestFramework):
connect_nodes(self.nodes[2], 0)
sync_blocks(self.nodes[0:3])
print "Usage can be over target because of high stale rate:", calc_usage(self.prunedir)
print(("Usage can be over target because of high stale rate:", calc_usage(self.prunedir)))
def reorg_test(self):
# Node 1 will mine a 300 block chain starting 287 blocks back from Node 0 and Node 2's tip
@@ -146,11 +146,11 @@ class PruneTest(BitcoinTestFramework):
self.nodes[1]=start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=5000", "-checkblocks=5", "-disablesafemode"], timewait=900)
height = self.nodes[1].getblockcount()
print "Current block height:", height
print(("Current block height:", height))
invalidheight = height-287
badhash = self.nodes[1].getblockhash(invalidheight)
print "Invalidating block at height:",invalidheight,badhash
print(("Invalidating block at height:",invalidheight,badhash))
self.nodes[1].invalidateblock(badhash)
# We've now switched to our previously mined-24 block fork on node 1, but thats not what we want
@@ -162,29 +162,29 @@ class PruneTest(BitcoinTestFramework):
curhash = self.nodes[1].getblockhash(invalidheight - 1)
assert(self.nodes[1].getblockcount() == invalidheight - 1)
print "New best height", self.nodes[1].getblockcount()
print(("New best height", self.nodes[1].getblockcount()))
# Reboot node1 to clear those giant tx's from mempool
stop_node(self.nodes[1],1)
self.nodes[1]=start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=5000", "-checkblocks=5", "-disablesafemode"], timewait=900)
print "Generating new longer chain of 300 more blocks"
print("Generating new longer chain of 300 more blocks")
self.nodes[1].generate(300)
print "Reconnect nodes"
print("Reconnect nodes")
connect_nodes(self.nodes[0], 1)
connect_nodes(self.nodes[2], 1)
sync_blocks(self.nodes[0:3])
print "Verify height on node 2:",self.nodes[2].getblockcount()
print "Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir)
print(("Verify height on node 2:",self.nodes[2].getblockcount()))
print(("Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir)))
print "Mine 220 more blocks so we have requisite history (some blocks will be big and cause pruning of previous chain)"
print("Mine 220 more blocks so we have requisite history (some blocks will be big and cause pruning of previous chain)")
self.nodes[0].generate(220) #node 0 has many large tx's in its mempool from the disconnects
sync_blocks(self.nodes[0:3])
usage = calc_usage(self.prunedir)
print "Usage should be below target:", usage
print(("Usage should be below target:", usage))
if (usage > 550):
raise AssertionError("Pruning target not being met")
@@ -196,7 +196,7 @@ class PruneTest(BitcoinTestFramework):
self.nodes[2].getblock(self.forkhash)
raise AssertionError("Old block wasn't pruned so can't test redownload")
except JSONRPCException:
print "Will need to redownload block",self.forkheight
print(("Will need to redownload block",self.forkheight))
# Verify that we have enough history to reorg back to the fork point
# Although this is more than 288 blocks, because this chain was written more recently
@@ -220,14 +220,14 @@ class PruneTest(BitcoinTestFramework):
# At this point node 2 is within 288 blocks of the fork point so it will preserve its ability to reorg
if self.nodes[2].getblockcount() < self.mainchainheight:
blocks_to_mine = first_reorg_height + 1 - self.mainchainheight
print "Rewind node 0 to prev main chain to mine longer chain to trigger redownload. Blocks needed:", blocks_to_mine
print(("Rewind node 0 to prev main chain to mine longer chain to trigger redownload. Blocks needed:", blocks_to_mine))
self.nodes[0].invalidateblock(curchainhash)
assert(self.nodes[0].getblockcount() == self.mainchainheight)
assert(self.nodes[0].getbestblockhash() == self.mainchainhash2)
goalbesthash = self.nodes[0].generate(blocks_to_mine)[-1]
goalbestheight = first_reorg_height + 1
print "Verify node 2 reorged back to the main chain, some blocks of which it had to redownload"
print("Verify node 2 reorged back to the main chain, some blocks of which it had to redownload")
waitstart = time.time()
while self.nodes[2].getblockcount() < goalbestheight:
time.sleep(0.1)
@@ -240,7 +240,7 @@ class PruneTest(BitcoinTestFramework):
def mine_full_block(self, node, address):
# Want to create a full block
# We'll generate a 66k transaction below, and 14 of them is close to the 1MB block limit
for j in xrange(14):
for j in range(14):
if len(self.utxo) < 14:
self.utxo = node.listunspent()
inputs=[]
@@ -264,8 +264,8 @@ class PruneTest(BitcoinTestFramework):
def run_test(self):
print "Warning! This test requires 4GB of disk space and takes over 30 mins (up to 2 hours)"
print "Mining a big blockchain of 995 blocks"
print("Warning! This test requires 4GB of disk space and takes over 30 mins (up to 2 hours)")
print("Mining a big blockchain of 995 blocks")
self.create_big_chain()
# Chain diagram key:
# * blocks on main chain
@@ -276,12 +276,12 @@ class PruneTest(BitcoinTestFramework):
# Start by mining a simple chain that all nodes have
# N0=N1=N2 **...*(995)
print "Check that we haven't started pruning yet because we're below PruneAfterHeight"
print("Check that we haven't started pruning yet because we're below PruneAfterHeight")
self.test_height_min()
# Extend this chain past the PruneAfterHeight
# N0=N1=N2 **...*(1020)
print "Check that we'll exceed disk space target if we have a very high stale block rate"
print("Check that we'll exceed disk space target if we have a very high stale block rate")
self.create_chain_with_staleblocks()
# Disconnect N0
# And mine a 24 block chain on N1 and a separate 25 block chain on N0
@@ -305,7 +305,7 @@ class PruneTest(BitcoinTestFramework):
self.mainchainheight = self.nodes[2].getblockcount() #1320
self.mainchainhash2 = self.nodes[2].getblockhash(self.mainchainheight)
print "Check that we can survive a 288 block reorg still"
print("Check that we can survive a 288 block reorg still")
(self.forkheight,self.forkhash) = self.reorg_test() #(1033, )
# Now create a 288 block reorg by mining a longer chain on N1
# First disconnect N1
@@ -338,7 +338,7 @@ class PruneTest(BitcoinTestFramework):
# \
# *...**(1320)
print "Test that we can rerequest a block we previously pruned if needed for a reorg"
print("Test that we can rerequest a block we previously pruned if needed for a reorg")
self.reorg_back()
# Verify that N2 still has block 1033 on current chain (@), but not on main chain (*)
# Invalidate 1033 on current chain (@) on N2 and we should be able to reorg to
@@ -358,7 +358,7 @@ class PruneTest(BitcoinTestFramework):
#
# N1 doesn't change because 1033 on main chain (*) is invalid
print "Done"
print("Done")
if __name__ == '__main__':
PruneTest().main()

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -20,7 +20,7 @@ from decimal import Decimal
class RawTransactionsTest(BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 3)
def setup_network(self, split=False):
@@ -64,7 +64,7 @@ class RawTransactionsTest(BitcoinTestFramework):
errorString = ""
try:
rawtx = self.nodes[2].sendrawtransaction(rawtx['hex'])
except JSONRPCException,e:
except JSONRPCException as e:
errorString = e.error['message']
assert_equal("Missing inputs" in errorString, True);

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2018 The Zcash developers
# Distributed under the GPLv3 software license, see the accompanying

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2014 The Bitcoin Core developers
# Copyright (c) 2016-2024 The Hush developers
# Released under the GPLv3
@@ -14,7 +14,7 @@ from test_framework.util import assert_equal, initialize_chain_clean, \
class ReindexTest(BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 1)
def setup_network(self):
@@ -28,7 +28,7 @@ class ReindexTest(BitcoinTestFramework):
wait_bitcoinds()
self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex", "-checkblockindex=1"])
assert_equal(self.nodes[0].getblockcount(), 3)
print "Success"
print("Success")
if __name__ == '__main__':
ReindexTest().main()

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -15,17 +15,17 @@ from test_framework.util import assert_equal, assert_greater_than, \
import struct
import binascii
import json
import StringIO
import io
from decimal import Decimal
try:
import http.client as httplib
except ImportError:
import httplib
import http.client
try:
import urllib.parse as urlparse
except ImportError:
import urlparse
import urllib.parse
def deser_uint256(f):
r = 0
@@ -36,7 +36,7 @@ def deser_uint256(f):
# allows simple http get calls
def http_get_call(host, port, path, response_object = 0):
conn = httplib.HTTPConnection(host, port)
conn = http.client.HTTPConnection(host, port)
conn.request('GET', path)
if response_object:
@@ -46,7 +46,7 @@ def http_get_call(host, port, path, response_object = 0):
# allows simple http post calls with a request body
def http_post_call(host, port, path, requestdata = '', response_object = 0):
conn = httplib.HTTPConnection(host, port)
conn = http.client.HTTPConnection(host, port)
conn.request('POST', path, requestdata)
if response_object:
@@ -58,7 +58,7 @@ class RESTTest (BitcoinTestFramework):
FORMAT_SEPARATOR = "."
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 3)
def setup_network(self, split=False):
@@ -70,8 +70,8 @@ class RESTTest (BitcoinTestFramework):
self.sync_all()
def run_test(self):
url = urlparse.urlparse(self.nodes[0].url)
print "Mining blocks..."
url = urllib.parse.urlparse(self.nodes[0].url)
print("Mining blocks...")
self.nodes[0].generate(1)
self.sync_all()
@@ -150,7 +150,7 @@ class RESTTest (BitcoinTestFramework):
binaryRequest += struct.pack("i", 0);
bin_response = http_post_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'bin', binaryRequest)
output = StringIO.StringIO()
output = io.StringIO()
output.write(bin_response)
output.seek(0)
chainHeight = struct.unpack("i", output.read(4))[0]

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2018 The Zcash developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -14,7 +14,7 @@ import time
class RewindBlockIndexTest (BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 3)
def setup_network(self, split=False):

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -67,7 +67,7 @@ def run_test(tmpdir):
break
if non_loopback_ip is None:
assert(not 'This test requires at least one non-loopback IPv4 interface')
print("Using interface %s for testing" % non_loopback_ip)
print(("Using interface %s for testing" % non_loopback_ip))
defaultport = rpc_port(0)
@@ -122,7 +122,7 @@ def main():
success = False
try:
print("Initializing test directory "+options.tmpdir)
print(("Initializing test directory "+options.tmpdir))
if not os.path.isdir(options.tmpdir):
os.makedirs(options.tmpdir)
initialize_chain(options.tmpdir)
@@ -132,9 +132,9 @@ def main():
success = True
except AssertionError as e:
print("Assertion failed: "+e.message)
print(("Assertion failed: "+e.message))
except Exception as e:
print("Unexpected exception caught during testing: "+str(e))
print(("Unexpected exception caught during testing: "+str(e)))
traceback.print_tb(sys.exc_info()[2])
if not options.nocleanup:

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
#
# Distributed under the GPLv3/X11 software license, see the accompanying
@@ -82,7 +82,7 @@ def ParseScriptFlags(flag_string):
if x in flag_map:
flags |= flag_map[x]
else:
print "Error: unrecognized script flag: ", x
print(("Error: unrecognized script flag: ", x))
return flags
'''
@@ -106,7 +106,7 @@ def ParseScript(json_script):
parsed_script += CScriptNum(int(x, 0))
elif x.startswith("0x"):
# Raw hex data, inserted NOT pushed onto stack:
for i in xrange(2, len(x), 2):
for i in range(2, len(x), 2):
parsed_script = CScript(bytes(parsed_script) + bytes(chr(int(x[i:i+2],16))))
elif x.startswith("'") and x.endswith("'") and len(x) >= 2:
# Single-quoted string, pushed as data.
@@ -117,7 +117,7 @@ def ParseScript(json_script):
if tryopname in OPCODES_BY_NAME:
parsed_script += CScriptOp(OPCODES_BY_NAME["OP_" + x])
else:
print "ParseScript: error parsing '%s'" % x
print(("ParseScript: error parsing '%s'" % x))
return ""
return parsed_script
@@ -176,7 +176,7 @@ class ScriptTest(ComparisonTestFramework):
self.tip = block.sha256
test.blocks_and_transactions = [[block, True]]
for i in xrange(100):
for i in range(100):
block = create_block(self.tip, create_coinbase(), self.block_time)
self.block_time += 1
block.solve()
@@ -210,7 +210,7 @@ class ScriptTest(ComparisonTestFramework):
Build out to 100 blocks total, maturing the coinbase.
'''
test = TestInstance(objects=[], sync_every_block=False, sync_every_tx=False)
for i in xrange(100):
for i in range(100):
b = create_block(self.tip, create_coinbase(), self.block_time)
b.solve()
test.blocks_and_transactions.append([b, True])
@@ -242,7 +242,7 @@ class ScriptTest(ComparisonTestFramework):
else:
self.block_time = 1333230000 + counter # Before the BIP16 switchover
print "Script test: [%s]" % script_test
print(("Script test: [%s]" % script_test))
yield self.generate_test_instance(scriptpubkey, scriptsig)
counter += 1

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Distributed under the GPLv3 software license, see the accompanying
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
@@ -10,7 +10,7 @@ from test_framework.authproxy import JSONRPCException
class SignOfflineTest (BitcoinTestFramework):
# Setup Methods
def setup_chain(self):
print "Initializing test directory " + self.options.tmpdir
print(("Initializing test directory " + self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 2)
def setup_network(self):
@@ -20,7 +20,7 @@ class SignOfflineTest (BitcoinTestFramework):
# Tests
def run_test(self):
print "Mining blocks..."
print("Mining blocks...")
self.nodes[0].generate(101)
offline_node = start_node(1, self.options.tmpdir, ["-maxconnections=0", "-nuparams=5ba81b19:10"])

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# Copyright (c) 2016-2024 The Hush developers
# Copyright (c) 2015 The Bitcoin Core developers
# Distributed under the GPLv3 software license, see the accompanying
@@ -13,7 +13,7 @@ class SignRawTransactionsTest(BitcoinTestFramework):
"""Tests transaction signing via RPC command "signrawtransaction"."""
def setup_chain(self):
print('Initializing test directory ' + self.options.tmpdir)
print(('Initializing test directory ' + self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 1)
def setup_network(self, split=False):

Some files were not shown because too many files have changed in this diff Show More