9 Commits
dragonx ... dev

Author SHA1 Message Date
Duke
61513966c2 Remove googlemock and googletest deps 2026-03-03 18:47:26 -05:00
Duke
f15ac8ca8f Add randomx unit tests 2026-03-03 18:42:14 -05:00
Duke
71a8a627bd Add more netbase tests 2026-03-03 18:19:04 -05:00
Duke
2781ea64e0 Add netbase unit tests 2026-03-03 18:11:00 -05:00
Duke
25c62c52f5 remove ntz tests 2026-03-03 17:35:22 -05:00
Duke
c5a9aab2f9 Merge remote-tracking branch 'origin/dev' into dev 2026-03-03 17:33:57 -05:00
Duke
4a69d23e05 Add c++ unit tests with docs; split out ./rpctest and ./cpptest from ./test 2026-03-03 17:31:24 -05:00
duke
d6d495c447 AI/LLM usage policy
Inspired by the policy in https://github.com/ggml-org/llama.cpp/blob/master/CONTRIBUTING.md
2026-03-03 11:40:16 -05:00
duke
0867d8cf62 We do not have a code of conduct doc 2026-03-03 11:29:15 -05:00
17 changed files with 262 additions and 464 deletions

View File

@@ -7,11 +7,11 @@ set -eu -o pipefail
# run correct build script for detected OS # run correct build script for detected OS
if [[ "$OSTYPE" == "linux-gnu"* ]]; then if [[ "$OSTYPE" == "linux-gnu"* ]]; then
./util/build.sh --disable-tests $@ ./util/build.sh $@
elif [[ "$OSTYPE" == "darwin"* ]]; then elif [[ "$OSTYPE" == "darwin"* ]]; then
./util/build-mac.sh --disable-tests $@ ./util/build-mac.sh $@
elif [[ "$OSTYPE" == "msys"* ]]; then elif [[ "$OSTYPE" == "msys"* ]]; then
./util/build-win.sh --disable-tests $@ ./util/build-win.sh $@
#elif [[ "$OSTYPE" == "freebsd"* ]]; then #elif [[ "$OSTYPE" == "freebsd"* ]]; then
# placeholder # placeholder
else else

7
cpptest Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
# Copyright 2026-now 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
# Run all tests by default
./src/hush-test $@

View File

@@ -1,33 +0,0 @@
# url=https://github.com/google/googlemock/archive/release-1.7.0.tar.gz
package=googlemock
$(package)_version=1.7.0
$(package)_dependencies=googletest
$(package)_download_path=https://github.com/google/$(package)/archive
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_download_file=release-$($(package)_version).tar.gz
$(package)_sha256_hash=3f20b6acb37e5a98e8c4518165711e3e35d47deb6cdb5a4dd4566563b5efd232
ifeq ($(build_os),darwin)
define $(package)_set_vars
$(package)_build_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)" CXX="$($(package)_cxx)" CXXFLAGS="$($(package)_cxxflags)"
endef
endif
ifeq ($(build_os),darwin)
$(package)_install=ginstall
define $(package)_build_cmds
$(MAKE) -C make GTEST_DIR='$(host_prefix)' gmock-all.o
endef
else
$(package)_install=install
define $(package)_build_cmds
$(MAKE) -C make GTEST_DIR='$(host_prefix)' CXXFLAGS='-fPIC' gmock-all.o
endef
endif
define $(package)_stage_cmds
$($(package)_install) -D ./make/gmock-all.o $($(package)_staging_dir)$(host_prefix)/lib/libgmock.a && \
cp -a ./include $($(package)_staging_dir)$(host_prefix)/include
endef

View File

@@ -1,40 +0,0 @@
package=googletest
$(package)_version=1.8.0
$(package)_download_path=https://github.com/google/$(package)/archive
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_download_file=release-$($(package)_version).tar.gz
$(package)_sha256_hash=58a6f4277ca2bc8565222b3bbd58a177609e9c488e8a72649359ba51450db7d8
define $(package)_set_vars
$(package)_cxxflags+=-std=c++11
$(package)_cxxflags_linux=-fPIC
endef
ifeq ($(build_os),darwin)
define $(package)_set_vars
$(package)_build_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)" CXX="$($(package)_cxx)" CXXFLAGS="$($(package)_cxxflags)"
endef
endif
ifeq ($(build_os),darwin)
$(package)_install=ginstall
define $(package)_build_cmds
$(MAKE) -C googlemock/make gmock.a && \
$(MAKE) -C googletest/make gtest.a
endef
else
$(package)_install=install
define $(package)_build_cmds
$(MAKE) -C googlemock/make CC="$($(package)_cc)" CXX="$($(package)_cxx)" AR="$($(package)_ar)" CXXFLAGS="$($(package)_cxxflags)" gmock.a && \
$(MAKE) -C googletest/make CC="$($(package)_cc)" CXX="$($(package)_cxx)" AR="$($(package)_ar)" CXXFLAGS="$($(package)_cxxflags)" gtest.a
endef
endif
define $(package)_stage_cmds
mkdir -p $($(package)_staging_dir)$(host_prefix)/lib && \
install ./googlemock/make/gmock.a $($(package)_staging_dir)$(host_prefix)/lib/libgmock.a && \
install ./googletest/make/gtest.a $($(package)_staging_dir)$(host_prefix)/lib/libgtest.a && \
cp -a ./googlemock/include $($(package)_staging_dir)$(host_prefix)/ && \
cp -a ./googletest/include $($(package)_staging_dir)$(host_prefix)/
endef

View File

@@ -39,8 +39,8 @@ native_packages := native_ccache
wallet_packages=bdb wallet_packages=bdb
ifeq ($(host_os),linux) ifeq ($(host_os),linux)
packages := boost wolfssl libevent $(zcash_packages) libcurl #googlemock googletest packages := boost wolfssl libevent $(zcash_packages) libcurl
else else
packages := boost wolfssl libevent $(zcash_packages) libcurl #googlemock googletest packages := boost wolfssl libevent $(zcash_packages) libcurl
endif endif

View File

@@ -1,10 +1,10 @@
# Hush Core (hushd) Software Contribution Guidelines # Hush Core (hushd) Software Contribution Guidelines
Thank you for reaching out and trying to make Hush an even better software application and cryptocoin platform. These contribution guidelines shall help you figuring out where you can be helpful and how to easily get started. Thank you for reaching out and trying to make Hush an even better software application and cryptocoin platform. These contribution guidelines shall help you figuring out where you can be helpful and how to easily get started.
## Table of Contents ## Table of Contents
0. [AI/LLM Usage Policty](#ai/llm-usage-policy)
0. [Types of contributions we're looking for](#types-of-contributions-were-looking-for) 0. [Types of contributions we're looking for](#types-of-contributions-were-looking-for)
0. [Ground rules & expectations](#ground-rules--expectations) 0. [Ground rules & expectations](#ground-rules--expectations)
0. [How to contribute](#how-to-contribute) 0. [How to contribute](#how-to-contribute)
@@ -13,6 +13,21 @@ Thank you for reaching out and trying to make Hush an even better software appli
0. [Contribution review process](#contribution-review-process) 0. [Contribution review process](#contribution-review-process)
0. [Community](#community) 0. [Community](#community)
## AI/LLM Usage Policy
> [!IMPORTANT]
> This project does **NOT** accept pull requests that are fully or predominantly AI-generated. AI tools may be utilized solely in an assistive capacity. The human submitting new code to the project must actually understand the code changes they are submitting.
Code that is initially generated by AI and subsequently edited will still be considered AI-generated. AI assistance is permissible only when the majority of the code is authored by a human contributor, with AI employed exclusively for corrections or to expand on verbose modifications that the contributor has already conceptualized (e.g., generating repeated lines with minor variations).
If AI is used to generate any portion of the code, contributors must adhere to the following requirements:
1. Explicitly disclose the manner in which AI was employed, including the exact model and quantization used and if it was done via local AI, such as with llama.cpp or a SaaS provider.
2. Perform a comprehensive manual review prior to submitting the pull request.
3. Be prepared to explain every line of code they submitted when asked about it by a maintainer.
4. It is strictly prohibited to use AI to write your posts for you (bug reports, feature requests, pull request descriptions, Github discussions, responding to humans, ...).
## Types of contributions we're looking for ## Types of contributions we're looking for
There are many ways you can directly contribute to Hush: There are many ways you can directly contribute to Hush:
@@ -31,7 +46,6 @@ Interested in making a contribution? Read on!
Before we get started, here are a few things we expect from you (and that you should expect from others): Before we get started, here are a few things we expect from you (and that you should expect from others):
* Be kind and thoughtful in your conversations around this project. We all come from different backgrounds and projects, which means we likely have different perspectives on "how free software and open source is done." Try to listen to others rather than convince them that your way is correct. * Be kind and thoughtful in your conversations around this project. We all come from different backgrounds and projects, which means we likely have different perspectives on "how free software and open source is done." Try to listen to others rather than convince them that your way is correct.
* Open Source Guides are released with a [Contributor Code of Conduct](./code_of_conduct.md). By participating in this project, you agree to abide by its terms.
* If you open a pull request, please ensure that your contribution does not increase test failures. If there are additional test failures, you will need to address them before we can merge your contribution. * If you open a pull request, please ensure that your contribution does not increase test failures. If there are additional test failures, you will need to address them before we can merge your contribution.
* When adding content, please consider if it is widely valuable. Please don't add references or links to things you or your employer have created as others will do so if they appreciate it. * When adding content, please consider if it is widely valuable. Please don't add references or links to things you or your employer have created as others will do so if they appreciate it.

View File

@@ -16,6 +16,48 @@ other programs and Operating System overhead. A good rule of thumb is:
Divide how many GBs of RAM you have by 2, subtract one. Use that many jobs. Divide how many GBs of RAM you have by 2, subtract one. Use that many jobs.
# Run all tests
To run both C++ and RPC tests:
./test
C++ test run much faster than the RPC tests.
## Run C++ Unit tests
To run the C++ unit tests
./src/hush-test
Example successful output:
Running 42 test cases...
*** No errors detected
Example failure output:
Running 42 test cases...
test-hush/main.cpp(16): error: in "test_sodium": check init_and_check_sodium() != 0 has failed [0 == 0]
*** 1 failure is detected in the test module "HushTestSuite"
# Run Python RPC tests
To run our QA/functional tests:
./rpctest
Example successful output:
# Running 2 tests..
PASS!
Example failure output:
FAIL! Number of failed tests: 1 . Details in test-1234567.txt
## Dealing with dependency changes ## Dealing with dependency changes

47
rpctest Executable file
View File

@@ -0,0 +1,47 @@
#!/usr/bin/env perl
# Copyright 2016-2026 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
use strict;
use warnings;
use 5.010;
my $flags = $ENV{TEST_FLAGS} || '--tracerpc';
my $test_dir = './qa/rpc-tests';
$ENV{PYTHONPATH} = "./qa/rpc-tests/test_framework/";
#$ENV{PYTHON_DEBUG} = 1;
my @tests_to_run = qw{
lockzins.py
shieldcoinbase_donation.py
};
my $exit = 0;
my $failed_tests = 0;
my $time=time();
my $num_tests = @tests_to_run;
print "# Running $num_tests tests";
for my $test (@tests_to_run) {
# send both stderr+stdout to our output file
my $cmd = "$test_dir/$test $flags 1>test-$time.txt 2>&1";
system($cmd);
print ".";
if($?) {
say "$cmd FAILED!";
$exit = 1;
$failed_tests++;
}
}
print "\n";
if ($exit) {
say "FAIL! Number of failed tests: $failed_tests . Details in test-$time.txt";
} else {
say "PASS!";
}
exit($exit);

View File

@@ -683,7 +683,7 @@ endif
$(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$(abspath $(<D) $<) $(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$(abspath $(<D) $<)
if ENABLE_TESTS if ENABLE_TESTS
#include Makefile.test-hush.include include Makefile.test-hush.include
#include Makefile.test.include #include Makefile.test.include
#include Makefile.gtest.include #include Makefile.gtest.include
endif endif

View File

@@ -6,19 +6,14 @@ TESTS += hush-test
bin_PROGRAMS += hush-test bin_PROGRAMS += hush-test
# tool for generating our public parameters # tool for generating our public parameters
hush_test_SOURCES = test-hush/main.cpp hush_test_SOURCES = test-hush/main.cpp \
# devs can enable this shit, it just slows down default compiles test-hush/test_netbase_tests.cpp \
test-hush/randomx.cpp
# test-hush/testutils.cpp \ # test-hush/testutils.cpp \
# test-hush/test_cryptoconditions.cpp \ # test-hush/test_cryptoconditions.cpp \
# test-hush/test_coinimport.cpp \ # test-hush/test_coinimport.cpp \
# test-hush/test_eval_bet.cpp \ # test-hush/test_addrman.cpp
# test-hush/test_eval_notarization.cpp \
# test-hush/test_parse_notarization.cpp \
# test-hush/test_addrman.cpp \
# test-hush/test_netbase_tests.cpp
hush_test_CPPFLAGS = $(hushd_CPPFLAGS) hush_test_CPPFLAGS = $(hushd_CPPFLAGS)
hush_test_LDADD = $(hushd_LDADD)
hush_test_LDADD = -lgtest $(hushd_LDADD) hush_test_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static
hush_test_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static

View File

@@ -1,29 +1,37 @@
// Copyright (c) 2016-2024 The Hush developers // Copyright (c) 2016-now The Hush developers
// Distributed under the GPLv3 software license, see the accompanying // Distributed under the GPLv3 software license, see the accompanying
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html // file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
#include "key.h" #include "key.h"
#include "base58.h" #include "base58.h"
#include "chainparams.h" #include "chainparams.h"
#include "gtest/gtest.h"
#include "crypto/common.h" #include "crypto/common.h"
//#include "testutils.h" #define BOOST_TEST_MODULE HushTestSuite
#include <boost/test/included/unit_test.hpp>
std::string notaryPubkey = "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47";
std::string notarySecret = "UxFWWxsf1d7w7K5TvAWSkeX4H95XQKwdwGv49DXwWUTzPTTjHBbU";
int main(int argc, char **argv) { // Test that libsodium has been initialized correctly
/* BOOST_AUTO_TEST_CASE(test_sodium) {
assert(init_and_check_sodium() != -1); BOOST_CHECK_NE( init_and_check_sodium(), -1 );
ECC_Start(); }
ECCVerifyHandle handle; // Inits secp256k1 verify context
SelectParams(CBaseChainParams::REGTEST); BOOST_AUTO_TEST_CASE(test_ecc) {
ECC_Start();
CBitcoinSecret vchSecret; BOOST_CHECK("created secp256k1 context");
// this returns false due to network prefix mismatch but works anyway
vchSecret.SetString(notarySecret); ECCVerifyHandle handle; // Inits secp256k1 verify context
CKey notaryKey = vchSecret.GetKey(); // this value is currently private
*/ //BOOST_CHECK_EQUAL( ECCVerifyHandle::refcount, 1 );
testing::InitGoogleTest(&argc, argv); ECC_Stop();
return RUN_ALL_TESTS(); BOOST_CHECK("destroyed secp256k1 context");
}
BOOST_AUTO_TEST_CASE(test_nets) {
SelectParams(CBaseChainParams::REGTEST);
BOOST_CHECK("regtest");
SelectParams(CBaseChainParams::MAIN);
BOOST_CHECK("mainnet");
SelectParams(CBaseChainParams::TESTNET);
BOOST_CHECK("testnet");
} }

44
src/test-hush/randomx.cpp Normal file
View File

@@ -0,0 +1,44 @@
// Copyright (c) 2016-now 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
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
#include "addrman.h"
#include <string>
#include "netbase.h"
#include <boost/test/unit_test.hpp>
#include "RandomX/src/randomx.h"
BOOST_AUTO_TEST_SUITE(randomx)
BOOST_AUTO_TEST_CASE(test_basic) {
randomx_flags flags = randomx_get_flags();
randomx_cache *randomxCache = randomx_alloc_cache(flags);
BOOST_CHECK_MESSAGE(randomxCache != NULL, "randomxCache is not null");
randomx_dataset *randomxDataset = randomx_alloc_dataset(flags);
BOOST_CHECK_MESSAGE(randomxDataset != NULL, "randomxDataset is not null");
auto datasetItemCount = randomx_dataset_item_count();
BOOST_CHECK_MESSAGE( datasetItemCount > 0, "datasetItemCount is positive");
// unknown location(0): fatal error: in "randomx/test_basic": memory access violation at address: 0x7f6983ce2000: invalid permissions
/* TODO
randomx_init_dataset(randomxDataset, randomxCache, 0, datasetItemCount);
char randomxHash[RANDOMX_HASH_SIZE];
randomx_vm *myVM = nullptr;
myVM = randomx_create_vm(flags, nullptr, randomxDataset);
BOOST_CHECK_MESSAGE(myVM != NULL, "randomx_vm is not null");
CDataStream randomxInput(SER_NETWORK, PROTOCOL_VERSION);
randomxInput << "stuff and things";
randomx_calculate_hash(myVM, &randomxInput, sizeof randomxInput, randomxHash);
*/
}
BOOST_AUTO_TEST_SUITE_END()

View File

@@ -1,197 +0,0 @@
// 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
#include <gtest/gtest.h>
#include "cc/betprotocol.h"
#include "cc/eval.h"
#include "base58.h"
#include "core_io.h"
#include "key.h"
#include "main.h"
#include "script/cc.h"
#include "primitives/transaction.h"
#include "script/interpreter.h"
#include "script/serverchecker.h"
#include "testutils.h"
extern int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
namespace TestEvalNotarization {
class EvalMock : public Eval
{
public:
uint32_t nNotaries;
uint8_t notaries[64][33];
std::map<uint256, CTransaction> txs;
std::map<uint256, CBlockIndex> blocks;
int32_t GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t timestamp) const
{
memcpy(pubkeys, notaries, sizeof(notaries));
return nNotaries;
}
bool GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const
{
auto r = txs.find(hash);
if (r != txs.end()) {
txOut = r->second;
if (blocks.count(hash) > 0)
hashBlock = hash;
return true;
}
return false;
}
bool GetBlock(uint256 hash, CBlockIndex& blockIdx) const
{
auto r = blocks.find(hash);
if (r == blocks.end()) return false;
blockIdx = r->second;
return true;
}
};
//static auto noop = [&](CMutableTransaction &mtx){};
static auto noop = [](CMutableTransaction &mtx){};
template<typename Modifier>
void SetupEval(EvalMock &eval, CMutableTransaction &notary, Modifier modify)
{
eval.nNotaries = hush_notaries(eval.notaries, 780060, 1522946781);
// make fake notary inputs
notary.vin.resize(11);
for (int i=0; i<notary.vin.size(); i++) {
CMutableTransaction txIn;
txIn.vout.resize(1);
txIn.vout[0].scriptPubKey << VCH(eval.notaries[i*2], 33) << OP_CHECKSIG;
notary.vin[i].prevout = COutPoint(txIn.GetHash(), 0);
eval.txs[txIn.GetHash()] = CTransaction(txIn);
}
modify(notary);
eval.txs[notary.GetHash()] = CTransaction(notary);
eval.blocks[notary.GetHash()].SetHeight(780060);
eval.blocks[notary.GetHash()].nTime = 1522946781;
}
// inputs have been dropped
static auto rawNotaryTx = "01000000000290460100000000002321020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9ac0000000000000000506a4c4dae8e0f3e6e5de498a072f5967f3c418c4faba5d56ac8ce17f472d029ef3000008f2e0100424f545300050ba773f0bc31da5839fc7cb9bd7b87f3b765ca608e5cf66785a466659b28880500000000000000";
CTransaction notaryTx;
static bool init = DecodeHexTx(notaryTx, rawNotaryTx);
static uint256 proofTxHash = uint256S("37f76551a16093fbb0a92ee635bbd45b3460da8fd00cf7d5a6b20d93e727fe4c");
static auto vMomProof = ParseHex("0303faecbdd4b3da128c2cd2701bb143820a967069375b2ec5b612f39bbfe78a8611978871c193457ab1e21b9520f4139f113b8d75892eb93ee247c18bccfd067efed7eacbfcdc8946cf22de45ad536ec0719034fb9bc825048fe6ab61fee5bd6e9aae0bb279738d46673c53d68eb2a72da6dbff215ee41a4d405a74ff7cd355805b"); // $ fiat/bots txMoMproof $proofTxHash
/*
TEST(TestEvalNotarization, testGetNotarization)
{
EvalMock eval;
CMutableTransaction notary(notaryTx);
SetupEval(eval, notary, noop);
NotarizationData data;
ASSERT_TRUE(eval.GetNotarizationData(notary.GetHash(), data));
EXPECT_EQ(data.height, 77455);
EXPECT_EQ(data.blockHash.GetHex(), "000030ef29d072f417cec86ad5a5ab4f8c413c7f96f572a098e45d6e3e0f8eae");
EXPECT_STREQ(data.symbol, "BOTS");
EXPECT_EQ(data.MoMDepth, 5);
EXPECT_EQ(data.MoM.GetHex(), "88289b6566a48567f65c8e60ca65b7f3877bbdb97cfc3958da31bcf073a70b05");
MoMProof proof;
E_UNMARSHAL(vMomProof, ss >> proof);
EXPECT_EQ(data.MoM, proof.branch.Exec(proofTxHash));
}
TEST(TestEvalNotarization, testInvalidNotaryPubkey)
{
EvalMock eval;
CMutableTransaction notary(notaryTx);
SetupEval(eval, notary, noop);
memset(eval.notaries[10], 0, 33);
NotarizationData data;
ASSERT_FALSE(eval.GetNotarizationData(notary.GetHash(), data));
}
*/
TEST(TestEvalNotarization, testInvalidNotarizationBadOpReturn)
{
EvalMock eval;
CMutableTransaction notary(notaryTx);
notary.vout[1].scriptPubKey = CScript() << OP_RETURN << 0;
SetupEval(eval, notary, noop);
NotarizationData data(0);
ASSERT_FALSE(eval.GetNotarizationData(notary.GetHash(), data));
}
TEST(TestEvalNotarization, testInvalidNotarizationTxNotEnoughSigs)
{
EvalMock eval;
CMutableTransaction notary(notaryTx);
SetupEval(eval, notary, [](CMutableTransaction &tx) {
tx.vin.resize(10);
});
NotarizationData data(0);
ASSERT_FALSE(eval.GetNotarizationData(notary.GetHash(), data));
}
TEST(TestEvalNotarization, testInvalidNotarizationTxDoesntExist)
{
EvalMock eval;
CMutableTransaction notary(notaryTx);
SetupEval(eval, notary, noop);
NotarizationData data(0);
ASSERT_FALSE(eval.GetNotarizationData(uint256(), data));
}
TEST(TestEvalNotarization, testInvalidNotarizationDupeNotary)
{
EvalMock eval;
CMutableTransaction notary(notaryTx);
SetupEval(eval, notary, [](CMutableTransaction &tx) {
tx.vin[1] = tx.vin[3];
});
NotarizationData data(0);
ASSERT_FALSE(eval.GetNotarizationData(notary.GetHash(), data));
}
TEST(TestEvalNotarization, testInvalidNotarizationInputNotCheckSig)
{
EvalMock eval;
CMutableTransaction notary(notaryTx);
SetupEval(eval, notary, [&](CMutableTransaction &tx) {
int i = 1;
CMutableTransaction txIn;
txIn.vout.resize(1);
txIn.vout[0].scriptPubKey << VCH(eval.notaries[i*2], 33) << OP_RETURN;
notary.vin[i].prevout = COutPoint(txIn.GetHash(), 0);
eval.txs[txIn.GetHash()] = CTransaction(txIn);
});
NotarizationData data(0);
ASSERT_FALSE(eval.GetNotarizationData(notary.GetHash(), data));
}
} /* namespace TestEvalNotarization */

View File

@@ -1,81 +1,85 @@
// Copyright (c) 2016-2024 The Hush developers // Copyright (c) 2016-2024 The Hush developers
// Distributed under the GPLv3 software license, see the accompanying // Distributed under the GPLv3 software license, see the accompanying
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html // file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
#include <gtest/gtest.h>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include "addrman.h" #include "addrman.h"
#include <string> #include <string>
#include "netbase.h" #include "netbase.h"
//#include <boost/test/included/unit_test.hpp>
#include <boost/test/unit_test.hpp>
#define GTEST_COUT_NOCOLOR std::cerr << "[ ] [ INFO ] " BOOST_AUTO_TEST_SUITE(netbase)
namespace testing
{
namespace internal
{
enum GTestColor {
COLOR_DEFAULT,
COLOR_RED,
COLOR_GREEN,
COLOR_YELLOW
};
extern void ColoredPrintf(GTestColor color, const char* fmt, ...);
}
}
#define PRINTF(...) do { testing::internal::ColoredPrintf(testing::internal::COLOR_GREEN, "[ ] "); testing::internal::ColoredPrintf(testing::internal::COLOR_YELLOW, __VA_ARGS__); } while(0)
// C++ stream interface
class TestCout : public std::stringstream
{
public:
~TestCout()
{
PRINTF("%s",str().c_str());
}
};
#define GTEST_COUT_COLOR TestCout()
using namespace std;
static CNetAddr ResolveIP(const std::string& ip) static CNetAddr ResolveIP(const std::string& ip)
{ {
vector<CNetAddr> vIPs;
CNetAddr addr; CNetAddr addr;
if (LookupHost(ip.c_str(), vIPs)) { bool fAllowLookup = true;
addr = vIPs[0]; if (LookupHost(ip.c_str(), addr, fAllowLookup)) {
} else } else {
{
// it was BOOST_CHECK_MESSAGE, but we can't use ASSERT outside a test
GTEST_COUT_COLOR << strprintf("failed to resolve: %s", ip) << std::endl;
} }
return addr; return addr;
} }
namespace TestNetBaseTests { BOOST_AUTO_TEST_CASE(test_resolve) {
TEST(TestAddrmanTests, netbase_getgroup) {
std::vector<bool> asmap; // use /16 std::vector<bool> asmap; // use /16
ASSERT_TRUE(ResolveIP("127.0.0.1").GetGroup(asmap) == std::vector<unsigned char>({0})); // Local -> !Routable() BOOST_CHECK(ResolveIP("127.0.0.1").GetGroup(asmap) == std::vector<unsigned char>({0})); // Local -> !Routable()
ASSERT_TRUE(ResolveIP("257.0.0.1").GetGroup(asmap) == std::vector<unsigned char>({0})); // !Valid -> !Routable() BOOST_CHECK(ResolveIP("257.0.0.1").GetGroup(asmap) == std::vector<unsigned char>({0})); // !Valid -> !Routable()
ASSERT_TRUE(ResolveIP("10.0.0.1").GetGroup(asmap) == std::vector<unsigned char>({0})); // RFC1918 -> !Routable() BOOST_CHECK(ResolveIP("10.0.0.1").GetGroup(asmap) == std::vector<unsigned char>({0})); // RFC1918 -> !Routable()
ASSERT_TRUE(ResolveIP("169.254.1.1").GetGroup(asmap) == std::vector<unsigned char>({0})); // RFC3927 -> !Routable() BOOST_CHECK(ResolveIP("169.254.1.1").GetGroup(asmap) == std::vector<unsigned char>({0})); // RFC3927 -> !Routable()
ASSERT_TRUE(ResolveIP("1.2.3.4").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // IPv4 BOOST_CHECK(ResolveIP("1.2.3.4").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // IPv4
// std::vector<unsigned char> vch = ResolveIP("4.3.2.1").GetGroup(asmap); // std::vector<unsigned char> vch = ResolveIP("4.3.2.1").GetGroup(asmap);
// GTEST_COUT_COLOR << boost::to_string((int)vch[0]) << boost::to_string((int)vch[1]) << boost::to_string((int)vch[2]) << std::endl;
ASSERT_TRUE(ResolveIP("::FFFF:0:102:304").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC6145 BOOST_CHECK(ResolveIP("::FFFF:0:102:304").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC6145
ASSERT_TRUE(ResolveIP("64:FF9B::102:304").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC6052 BOOST_CHECK(ResolveIP("64:FF9B::102:304").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC6052
ASSERT_TRUE(ResolveIP("2002:102:304:9999:9999:9999:9999:9999").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC3964 BOOST_CHECK(ResolveIP("2002:102:304:9999:9999:9999:9999:9999").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC3964
ASSERT_TRUE(ResolveIP("2001:0:9999:9999:9999:9999:FEFD:FCFB").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC4380 BOOST_CHECK(ResolveIP("2001:0:9999:9999:9999:9999:FEFD:FCFB").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC4380
ASSERT_TRUE(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_ONION, 239})); // Tor BOOST_CHECK(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_ONION, 239})); // Tor
ASSERT_TRUE(ResolveIP("2001:470:abcd:9999:9999:9999:9999:9999").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV6, 32, 1, 4, 112, 175})); //he.net BOOST_CHECK(ResolveIP("2001:470:abcd:9999:9999:9999:9999:9999").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV6, 32, 1, 4, 112, 175})); //he.net
ASSERT_TRUE(ResolveIP("2001:2001:9999:9999:9999:9999:9999:9999").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV6, 32, 1, 32, 1})); //IPv6 BOOST_CHECK(ResolveIP("2001:2001:9999:9999:9999:9999:9999:9999").GetGroup(asmap) == std::vector<unsigned char>({(unsigned char)NET_IPV6, 32, 1, 32, 1})); //IPv6
}
} }
#define TEST_ONION "hushv3h6mbxd2pptj42reko3jcexcgnz5zvp3mqcu6myto3jhhn4yzyd.onion"
BOOST_AUTO_TEST_CASE(netbase_networks)
{
BOOST_CHECK(ResolveIP("127.0.0.1").GetNetwork() == NET_UNROUTABLE);
BOOST_CHECK(ResolveIP("10.0.0.42").GetNetwork() == NET_UNROUTABLE);
BOOST_CHECK(ResolveIP("::1").GetNetwork() == NET_UNROUTABLE);
BOOST_CHECK(ResolveIP("8.8.8.8").GetNetwork() == NET_IPV4);
BOOST_CHECK(ResolveIP("2001::8888").GetNetwork() == NET_IPV6);
BOOST_CHECK(ResolveIP(TEST_ONION).GetNetwork() == NET_ONION);
}
BOOST_AUTO_TEST_CASE(netbase_properties)
{
BOOST_CHECK(ResolveIP("127.0.0.1").IsIPv4());
BOOST_CHECK(ResolveIP("::FFFF:192.168.1.1").IsIPv4());
BOOST_CHECK(ResolveIP("::1").IsIPv6());
BOOST_CHECK(ResolveIP("10.0.0.1").IsRFC1918());
BOOST_CHECK(ResolveIP("192.168.1.1").IsRFC1918());
BOOST_CHECK(ResolveIP("172.31.255.255").IsRFC1918());
BOOST_CHECK(ResolveIP("198.18.0.0").IsRFC2544());
BOOST_CHECK(ResolveIP("198.19.255.255").IsRFC2544());
BOOST_CHECK(ResolveIP("2001:0DB8::").IsRFC3849());
BOOST_CHECK(ResolveIP("169.254.1.1").IsRFC3927());
BOOST_CHECK(ResolveIP("2002::1").IsRFC3964());
BOOST_CHECK(ResolveIP("FC00::").IsRFC4193());
BOOST_CHECK(ResolveIP("2001::2").IsRFC4380());
BOOST_CHECK(ResolveIP("2001:10::").IsRFC4843());
BOOST_CHECK(ResolveIP("2001:20::").IsRFC7343());
BOOST_CHECK(ResolveIP("FE80::").IsRFC4862());
BOOST_CHECK(ResolveIP("64:FF9B::").IsRFC6052());
BOOST_CHECK(ResolveIP(TEST_ONION).IsTor());
BOOST_CHECK(ResolveIP("127.0.0.1").IsLocal());
BOOST_CHECK(ResolveIP("::1").IsLocal());
BOOST_CHECK(ResolveIP("8.8.8.8").IsRoutable());
BOOST_CHECK(ResolveIP("2001::1").IsRoutable());
BOOST_CHECK(ResolveIP("127.0.0.1").IsValid());
}
BOOST_AUTO_TEST_SUITE_END()

View File

@@ -1,54 +0,0 @@
// 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
#include <gtest/gtest.h>
#include "cc/eval.h"
#include "core_io.h"
#include "key.h"
#include "testutils.h"
namespace TestParseNotarization {
class TestParseNotarization : public ::testing::Test, public Eval {};
TEST(TestParseNotarization, test_ee2fa)
{
// ee2fa47820a31a979f9f21cb3fedbc484bf9a8957cb6c9acd0af28ced29bdfe1
std::vector<uint8_t> opret = ParseHex("c349ff90f3bce62c1b7b49d1da0423b1a3d9b733130cce825b95b9e047c729066e020d00743a06fdb95ad5775d032b30bbb3680dac2091a0f800cf54c79fd3461ce9b31d4b4d4400");
NotarizationData nd;
ASSERT_TRUE(E_UNMARSHAL(opret, ss >> nd));
}
TEST(TestParseNotarization, test__)
{
// 576e910a1f704207bcbcf724124ff9adc5237f45cb6919589cd0aa152caec424
std::vector<uint8_t> opret = ParseHex("b3ed7fbbfbc027caeeeec81e65489ec5d9cd47cda675a5cbb75b4a845e67cf0ef6330300b5a6bd8385feb833f3be961c9d8a46fcecd36dcdfa42ad81a20a892433722f0b4b4d44004125a06024eae24c11f36ea110acd707b041d5355b6e1b42de5e2614357999c6aa02000d26ad0300000000404b4c000000000005130300500d000061f22ba7d19fe29ac3baebd839af8b7127d1f90755534400");
NotarizationData nd;
// We can't parse this one
ASSERT_FALSE(E_UNMARSHAL(opret, ss >> nd));
}
TEST(TestParseNotarization, test__a)
{
// be55101e6c5a93fb3611a44bd66217ad8714d204275ea4e691cfff9d65dff85c TXSCL
std::vector<uint8_t> opret = ParseHex("fb9ea2818eec8b07f8811bab49d64379db074db478997f8114666f239bd79803cc460000d0fac4e715b7e2b917a5d79f85ece0c423d27bd3648fd39ac1dc7db8e1bd4b16545853434c00a69eab9f23d7fb63c4624973e7a9079d6ada2f327040936356d7af5e849f6d670a0003001caf7b7b9e1c9bc59d0c7a619c9683ab1dd0794b6f3ea184a19f8fda031150e700000000");
NotarizationData nd(1);
bool res = E_UNMARSHAL(opret, ss >> nd);
ASSERT_TRUE(res);
}
TEST(TestParseNotarization, test__b)
{
// 03085dafed656aaebfda25bf43ffe9d1fb72565bb1fc8b2a12a631659f28f877 TXSCL
std::vector<uint8_t> opret = ParseHex("48c71a10aa060eab1a43f52acefac3b81fb2a2ce310186b06141884c0501d403c246000052e6d49afd82d9ab3d97c996dd9b6a78a554ffa1625e8dadf0494bd1f8442e3e545853434c007cc5c07e3b67520fd14e23cd5b49f2aa022f411500fd3326ff91e6dc0544a1c90c0003008b69117bb1376ac8df960f785d8c208c599d3a36248c98728256bb6d4737e59600000000");
NotarizationData nd(1);
bool res = E_UNMARSHAL(opret, ss >> nd);
ASSERT_TRUE(res);
}
// for l in `g 'parse notarization' ~/.hush/HUSH3/debug.log | pyline 'l.split()[8]'`; do hoek decodeTx '{"hex":"'`src/hush-cli getrawtransaction "$l"`'"}' | jq '.outputs[1].script.op_return' | pyline 'import base64; print base64.b64decode(l).encode("hex")'; done
}

View File

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

47
test
View File

@@ -1,47 +1,8 @@
#!/usr/bin/env perl #!/bin/bash
# Copyright 2016-2026 The Hush developers # Copyright 2026-now The Hush developers
# Distributed under the GPLv3 software license, see the accompanying # Distributed under the GPLv3 software license, see the accompanying
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html # file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
use strict; # Run c++ tests first, they are faster
use warnings; ./cpptest && ./rpctest
use 5.010;
my $flags = $ENV{TEST_FLAGS} || '--tracerpc';
my $test_dir = './qa/rpc-tests';
$ENV{PYTHONPATH} = "./qa/rpc-tests/test_framework/";
#$ENV{PYTHON_DEBUG} = 1;
my @tests_to_run = qw{
lockzins.py
shieldcoinbase_donation.py
};
my $exit = 0;
my $failed_tests = 0;
my $time=time();
my $num_tests = @tests_to_run;
print "# Running $num_tests tests";
for my $test (@tests_to_run) {
# send both stderr+stdout to our output file
my $cmd = "$test_dir/$test $flags 1>test-$time.txt 2>&1";
system($cmd);
print ".";
if($?) {
say "$cmd FAILED!";
$exit = 1;
$failed_tests++;
}
}
print "\n";
if ($exit) {
say "FAIL! Number of failed tests: $failed_tests . Details in test-$time.txt";
} else {
say "PASS!";
}
exit($exit);