Skip to content

backport: trivial 2024 10 23 pr1 #6345

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
03e0bd3
Merge bitcoin/bitcoin#27319: addrman, refactor: improve stochastic te…
achow101 Feb 8, 2024
f096880
Merge bitcoin/bitcoin#29377: test: Add makefile target for running un…
achow101 Feb 8, 2024
b719883
Merge bitcoin/bitcoin#29399: test: Fix utxo set hash serialisation si…
fanquake Feb 12, 2024
3914745
Merge bitcoin/bitcoin#29425: test: fix intermittent failure in wallet…
fanquake Feb 13, 2024
9963e6b
Merge bitcoin/bitcoin#29413: fuzz: increase length of string used for…
fanquake Feb 13, 2024
9b6a05d
Merge bitcoin/bitcoin#29443: depends: fix BDB compilation on OpenBSD
fanquake Feb 26, 2024
92bad90
Merge bitcoin/bitcoin#28178: fuzz: Generate with random libFuzzer set…
fanquake Feb 27, 2024
a23b342
Merge bitcoin/bitcoin#29475: doc: Fix Broken Links
fanquake Feb 27, 2024
fdac2b3
Merge bitcoin/bitcoin#29493: subtree: update crc32c subtree
fanquake Feb 28, 2024
910a7d6
Merge bitcoin/bitcoin#29529: fuzz: restrict fopencookie usage to Linu…
fanquake Mar 6, 2024
4dce690
Merge bitcoin/bitcoin#29576: Update functional test runner to return …
fanquake Mar 7, 2024
8d6e5e7
Merge bitcoin/bitcoin#29583: fuzz: Apply fuzz env (suppressions, etc.…
fanquake Mar 8, 2024
c961755
Merge bitcoin/bitcoin#29595: doc: Wrap flags with code in developer-n…
fanquake Mar 8, 2024
bd607f0
Merge bitcoin/bitcoin#29393: i2p: log connection was refused due to a…
achow101 Mar 9, 2024
045fa5f
Merge bitcoin/bitcoin#29514: tests: Provide more helpful assert_equal…
achow101 Mar 11, 2024
d0e15d5
Merge bitcoin/bitcoin#29606: refactor: Reserve memory for ToLower/ToU…
achow101 Mar 13, 2024
6d7aa3d
Merge bitcoin/bitcoin#29497: test: simplify test_runner.py
fanquake Mar 14, 2024
b70e091
Merge bitcoin/bitcoin#29667: fuzz: actually test garbage >64b in p2p …
fanquake Mar 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion depends/packages/bdb.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ $(package)_cflags+=-Wno-error=implicit-function-declaration -Wno-error=format-se
$(package)_cxxflags+=-std=c++17
$(package)_cppflags_freebsd=-D_XOPEN_SOURCE=600 -D__BSD_VISIBLE=1
$(package)_cppflags_netbsd=-D_XOPEN_SOURCE=600
Copy link
Collaborator

Choose a reason for hiding this comment

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

should bump version here: doc/build-openbsd.md

see bitcoin#29481 as an useful follow-up.

Copy link
Member Author

Choose a reason for hiding this comment

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

Our openbsd docs are missing backports, unable to merge this PR relatively trivially atm

$(package)_cppflags_openbsd=-D_XOPEN_SOURCE=600
$(package)_cppflags_mingw32=-DUNICODE -D_UNICODE
endef

Expand Down
2 changes: 1 addition & 1 deletion doc/developer-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ produce better debugging builds.
### Show sources in debugging

If you have ccache enabled, absolute paths are stripped from debug information
with the -fdebug-prefix-map and -fmacro-prefix-map options (if supported by the
with the `-fdebug-prefix-map` and `-fmacro-prefix-map` options (if supported by the
compiler). This might break source file detection in case you move binaries
after compilation, debug from the directory other than the project root or use
an IDE that only supports absolute paths for debugging.
Expand Down
4 changes: 3 additions & 1 deletion src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,9 @@ dash_test_check: $(TEST_BINARY) FORCE
dash_test_clean : FORCE
rm -f $(CLEAN_BITCOIN_TEST) $(test_test_dash_OBJECTS) $(TEST_BINARY)

check-local: $(BITCOIN_TESTS:.cpp=.cpp.test)
check-unit: $(BITCOIN_TESTS:.cpp=.cpp.test)

check-local: check-unit
if BUILD_BITCOIN_TX
@echo "Running test/util/bitcoin-util-test.py..."
$(PYTHON) $(top_builddir)/test/util/bitcoin-util-test.py
Expand Down
9 changes: 4 additions & 5 deletions src/addrman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -581,11 +581,10 @@ bool AddrManImpl::AddSingle(const CAddress& addr, const CNetAddr& source, int64_
return false;

// stochastic test: previous nRefCount == N: 2^N times harder to increase it
int nFactor = 1;
for (int n = 0; n < pinfo->nRefCount; n++)
nFactor *= 2;
if (nFactor > 1 && (insecure_rand.randrange(nFactor) != 0))
return false;
if (pinfo->nRefCount > 0) {
const int nFactor{1 << pinfo->nRefCount};
if (insecure_rand.randrange(nFactor) != 0) return false;
}
} else {
pinfo = Create(addr, source, &nId);
pinfo->nTime = std::max((int64_t)0, (int64_t)pinfo->nTime - nTimePenalty);
Expand Down
32 changes: 20 additions & 12 deletions src/crc32c/src/crc32c_arm64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include <cstddef>
#include <cstdint>
#include <cstring>

#include "./crc32c_internal.h"
#ifdef CRC32C_HAVE_CONFIG_H
Expand All @@ -29,14 +30,14 @@
// compute 8bytes for each segment parallelly
#define CRC32C32BYTES(P, IND) \
do { \
crc1 = __crc32cd( \
crc1, *((const uint64_t *)(P) + (SEGMENTBYTES / 8) * 1 + (IND))); \
crc2 = __crc32cd( \
crc2, *((const uint64_t *)(P) + (SEGMENTBYTES / 8) * 2 + (IND))); \
crc3 = __crc32cd( \
crc3, *((const uint64_t *)(P) + (SEGMENTBYTES / 8) * 3 + (IND))); \
crc0 = __crc32cd( \
crc0, *((const uint64_t *)(P) + (SEGMENTBYTES / 8) * 0 + (IND))); \
std::memcpy(&d64, (P) + SEGMENTBYTES * 1 + (IND) * 8, sizeof(d64)); \
crc1 = __crc32cd(crc1, d64); \
std::memcpy(&d64, (P) + SEGMENTBYTES * 2 + (IND) * 8, sizeof(d64)); \
crc2 = __crc32cd(crc2, d64); \
std::memcpy(&d64, (P) + SEGMENTBYTES * 3 + (IND) * 8, sizeof(d64)); \
crc3 = __crc32cd(crc3, d64); \
std::memcpy(&d64, (P) + SEGMENTBYTES * 0 + (IND) * 8, sizeof(d64)); \
crc0 = __crc32cd(crc0, d64); \
} while (0);

// compute 8*8 bytes for each segment parallelly
Expand Down Expand Up @@ -68,6 +69,9 @@ uint32_t ExtendArm64(uint32_t crc, const uint8_t *data, size_t size) {
int64_t length = size;
uint32_t crc0, crc1, crc2, crc3;
uint64_t t0, t1, t2;
uint16_t d16;
uint32_t d32;
uint64_t d64;

// k0=CRC(x^(3*SEGMENTBYTES*8)), k1=CRC(x^(2*SEGMENTBYTES*8)),
// k2=CRC(x^(SEGMENTBYTES*8))
Expand All @@ -88,7 +92,8 @@ uint32_t ExtendArm64(uint32_t crc, const uint8_t *data, size_t size) {
t2 = (uint64_t)vmull_p64(crc2, k2);
t1 = (uint64_t)vmull_p64(crc1, k1);
t0 = (uint64_t)vmull_p64(crc0, k0);
crc = __crc32cd(crc3, *(uint64_t *)data);
std::memcpy(&d64, data, sizeof(d64));
crc = __crc32cd(crc3, d64);
data += sizeof(uint64_t);
crc ^= __crc32cd(0, t2);
crc ^= __crc32cd(0, t1);
Expand All @@ -98,18 +103,21 @@ uint32_t ExtendArm64(uint32_t crc, const uint8_t *data, size_t size) {
}

while (length >= 8) {
crc = __crc32cd(crc, *(uint64_t *)data);
std::memcpy(&d64, data, sizeof(d64));
crc = __crc32cd(crc, d64);
data += 8;
length -= 8;
}

if (length & 4) {
crc = __crc32cw(crc, *(uint32_t *)data);
std::memcpy(&d32, data, sizeof(d32));
crc = __crc32cw(crc, d32);
data += 4;
}

if (length & 2) {
crc = __crc32ch(crc, *(uint16_t *)data);
std::memcpy(&d16, data, sizeof(d16));
crc = __crc32ch(crc, d16);
data += 2;
}

Expand Down
1 change: 1 addition & 0 deletions src/i2p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ bool Session::Connect(const CService& to, Connection& conn, bool& proxy_error)
// Refuse connecting to arbitrary ports. We don't specify any destination port to the SAM proxy
// when connecting (SAM 3.1 does not use ports) and it forces/defaults it to I2P_SAM31_PORT.
if (to.GetPort() != I2P_SAM31_PORT) {
Log("Error connecting to %s, connection refused due to arbitrary port %s", to.ToStringAddrPort(), to.GetPort());
proxy_error = false;
return false;
}
Expand Down
3 changes: 2 additions & 1 deletion src/test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ that runs all of the unit tests. The main source file for the test library is fo
Unit tests will be automatically compiled if dependencies were met in `./configure`
and tests weren't explicitly disabled.

After configuring, they can be run with `make check`.
After configuring, they can be run with `make check`, which includes unit tests from
subtrees, or `make && make -C src check-unit` for just the unit tests.
Copy link
Collaborator

Choose a reason for hiding this comment

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

finally we have it! =) Unit tests run QUADRUPLE fast now!

Used to be:

$ time make check -j20
real    2m1.358s
user    4m53.064s
sys     0m19.916s

became:

$ time make -C src check-unit -j20
real    0m34.330s
user    2m37.573s
sys     0m17.590s

Copy link
Member Author

Choose a reason for hiding this comment

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

Ahh, interesting!

Copy link
Collaborator

@knst knst Oct 24, 2024

Choose a reason for hiding this comment

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

maybe actually add test_dash_qt_check to README.md ? but with or without it's fine

-subtrees, or `make && make -C src check-unit` for just the unit tests.
+subtrees, or `make && make -C src check-unit test_dash_qt_check` for just the unit tests.


To run the unit tests manually, launch `src/test/test_dash`. To recompile
after a test file was modified, run `make` and then run the test again. If you
Expand Down
2 changes: 1 addition & 1 deletion src/test/fuzz/net_permissions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
FUZZ_TARGET(net_permissions)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const std::string s = fuzzed_data_provider.ConsumeRandomLengthString(32);
const std::string s = fuzzed_data_provider.ConsumeRandomLengthString(1000);
const NetPermissionFlags net_permission_flags = ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS);

NetWhitebindPermissions net_whitebind_permissions;
Expand Down
1 change: 1 addition & 0 deletions src/test/fuzz/p2p_transport_serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ std::unique_ptr<Transport> MakeV2Transport(NodeId nodeid, bool initiator, RNG& r
} else {
// If it's longer, generate it from the RNG. This avoids having large amounts of
// (hopefully) irrelevant data needing to be stored in the fuzzer data.
garb.resize(garb_len);
for (auto& v : garb) v = uint8_t(rng());
}
// Retrieve entropy
Expand Down
2 changes: 1 addition & 1 deletion src/test/fuzz/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ FILE* FuzzedFileProvider::open()
[&] {
mode = "a+";
});
#if defined _GNU_SOURCE && !defined __ANDROID__
#if defined _GNU_SOURCE && (defined(__linux__) || defined(__FreeBSD__))
const cookie_io_functions_t io_hooks = {
FuzzedFileProvider::read,
FuzzedFileProvider::write,
Expand Down
2 changes: 2 additions & 0 deletions src/util/strencodings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,13 +476,15 @@ bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
std::string ToLower(const std::string& str)
{
std::string r;
r.reserve(str.size());
for (auto ch : str) r += ToLower(ch);
return r;
}

std::string ToUpper(const std::string& str)
{
std::string r;
r.reserve(str.size());
for (auto ch : str) r += ToUpper(ch);
return r;
}
Expand Down
4 changes: 1 addition & 3 deletions test/functional/feature_utxo_set_hash.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test UTXO set hash value calculation in gettxoutsetinfo."""

import struct

from test_framework.messages import (
CBlock,
COutPoint,
Expand Down Expand Up @@ -58,7 +56,7 @@ def test_muhash_implementation(self):
continue

data = COutPoint(int(tx.rehash(), 16), n).serialize()
data += struct.pack("<i", height * 2 + coinbase)
data += (height * 2 + coinbase).to_bytes(4, "little")
data += tx_out.serialize()

muhash.insert(data)
Expand Down
18 changes: 5 additions & 13 deletions test/functional/p2p_i2p_ports.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,28 @@
Test ports handling for I2P hosts
"""

import re

from test_framework.test_framework import BitcoinTestFramework

PROXY = "127.0.0.1:60000"

class I2PPorts(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
# The test assumes that an I2P SAM proxy is not listening here.
self.extra_args = [["-i2psam=127.0.0.1:60000"]]
self.extra_args = [[f"-i2psam={PROXY}"]]

def run_test(self):
node = self.nodes[0]

self.log.info("Ensure we don't try to connect if port!=0")
addr = "zsxwyo6qcn3chqzwxnseusqgsnuw3maqnztkiypyfxtya4snkoka.b32.i2p:8333"
raised = False
try:
with node.assert_debug_log(expected_msgs=[f"Error connecting to {addr}"]):
node.addnode(node=addr, command="onetry")
except AssertionError as e:
raised = True
if not re.search(r"Expected messages .* does not partially match log", str(e)):
raise AssertionError(f"Assertion raised as expected, but with an unexpected message: {str(e)}")
if not raised:
raise AssertionError("Assertion should have been raised")
with node.assert_debug_log(expected_msgs=[f"Error connecting to {addr}, connection refused due to arbitrary port 8333"]):
node.addnode(node=addr, command="onetry")

self.log.info("Ensure we try to connect if port=0 and get an error due to missing I2P proxy")
addr = "h3r6bkn46qxftwja53pxiykntegfyfjqtnzbm6iv6r5mungmqgmq.b32.i2p:0"
with node.assert_debug_log(expected_msgs=[f"Error connecting to {addr}"]):
with node.assert_debug_log(expected_msgs=[f"Error connecting to {addr}: Cannot connect to {PROXY}"]):
node.addnode(node=addr, command="onetry")


Expand Down
2 changes: 1 addition & 1 deletion test/functional/test_framework/netutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Linux network utilities.

Roughly based on http://voorloopnul.com/blog/a-python-netstat-in-less-than-100-lines-of-code/ by Ricardo Pascal
Roughly based on https://web.archive.org/web/20190424172231/http://voorloopnul.com/blog/a-python-netstat-in-less-than-100-lines-of-code/ by Ricardo Pascal
"""

import sys
Expand Down
17 changes: 17 additions & 0 deletions test/functional/test_framework/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,24 @@ def assert_fee_amount(fee, tx_size, fee_per_kB):
raise AssertionError("Fee of %s DASH too high! (Should be %s DASH)" % (str(fee), str(target_fee)))


def summarise_dict_differences(thing1, thing2):
if not isinstance(thing1, dict) or not isinstance(thing2, dict):
return thing1, thing2
d1, d2 = {}, {}
for k in sorted(thing1.keys()):
if k not in thing2:
d1[k] = thing1[k]
elif thing1[k] != thing2[k]:
d1[k], d2[k] = summarise_dict_differences(thing1[k], thing2[k])
for k in sorted(thing2.keys()):
if k not in thing1:
d2[k] = thing2[k]
return d1, d2

def assert_equal(thing1, thing2, *args):
if thing1 != thing2 and not args and isinstance(thing1, dict) and isinstance(thing2, dict):
d1,d2 = summarise_dict_differences(thing1, thing2)
raise AssertionError("not(%s == %s)\n in particular not(%s == %s)" % (thing1, thing2, d1, d2))
if thing1 != thing2 or any(thing1 != arg for arg in args):
raise AssertionError("not(%s)" % " == ".join(str(arg) for arg in (thing1, thing2) + args))

Expand Down
18 changes: 8 additions & 10 deletions test/functional/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ def main():
if not enable_bitcoind:
print("No functional tests to run.")
print("Rerun ./configure with --with-daemon and then make")
sys.exit(0)
sys.exit(1)

# Build list of tests
test_list = []
Expand Down Expand Up @@ -502,7 +502,7 @@ def main():
if not test_list:
print("No valid test scripts specified. Check that your test is in one "
"of the test lists in test_runner.py, or run test_runner.py with no arguments to run all tests")
sys.exit(0)
sys.exit(1)

if args.help:
# Print help for test_runner.py, then print help of the first script (with args removed) and exit.
Expand Down Expand Up @@ -592,14 +592,12 @@ def run_tests(*, test_list, src_dir, build_dir, tmpdir, jobs=1, attempts=1, enab
max_len_name = len(max(test_list, key=len))
test_count = len(test_list)
all_passed = True
i = 0
while i < test_count:
while not job_queue.done():
if failfast and not all_passed:
break
for test_result, testdir, stdout, stderr in job_queue.get_next():
test_results.append(test_result)
i += 1
done_str = "{}/{} - {}{}{}".format(i, test_count, BOLD[1], test_result.name, BOLD[0])
done_str = f"{len(test_results)}/{test_count} - {BOLD[1]}{test_result.name}{BOLD[0]}"
if test_result.status == "Passed":
logging.debug("%s passed, Duration: %s s" % (done_str, test_result.time))
elif test_result.status == "Skipped":
Expand Down Expand Up @@ -684,15 +682,16 @@ def __init__(self, *, num_tests_parallel, tests_dir, tmpdir, test_list, flags, u
self.tmpdir = tmpdir
self.test_list = test_list
self.flags = flags
self.num_running = 0
self.jobs = []
self.use_term_control = use_term_control
self.attempts = attempts

def done(self):
return not (self.jobs or self.test_list)

def get_next(self):
while self.num_running < self.num_jobs and self.test_list:
while len(self.jobs) < self.num_jobs and self.test_list:
# Add tests
self.num_running += 1
test = self.test_list.pop(0)
portseed = len(self.test_list)
portseed_arg = ["--portseed={}".format(portseed)]
Expand Down Expand Up @@ -764,7 +763,6 @@ def get_next(self):
continue
else:
status = "Failed"
self.num_running -= 1
self.jobs.remove(job)
if self.use_term_control:
clearline = '\r' + (' ' * dot_count) + '\r'
Expand Down
1 change: 1 addition & 0 deletions test/functional/wallet_reorgsrestore.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def run_test(self):
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("10"))
tx = self.nodes[0].gettransaction(txid)
self.generate(self.nodes[0], 4, sync_fun=self.no_op)
self.sync_blocks([self.nodes[0], self.nodes[2]])
tx_before_reorg = self.nodes[0].gettransaction(txid)
assert_equal(tx_before_reorg["confirmations"], 4)

Expand Down
17 changes: 13 additions & 4 deletions test/fuzz/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import configparser
import logging
import os
import random
import subprocess
import sys

Expand Down Expand Up @@ -93,7 +94,10 @@ def main():
sys.exit(1)

# Build list of tests
test_list_all = parse_test_list(fuzz_bin=os.path.join(config["environment"]["BUILDDIR"], 'src', 'test', 'fuzz', 'fuzz'))
test_list_all = parse_test_list(
fuzz_bin=os.path.join(config["environment"]["BUILDDIR"], 'src', 'test', 'fuzz', 'fuzz'),
source_dir=config['environment']['SRCDIR'],
)

if not test_list_all:
logging.error("No fuzz targets found")
Expand Down Expand Up @@ -207,9 +211,13 @@ def job(command, t):
for target in targets:
target_corpus_dir = os.path.join(corpus_dir, target)
os.makedirs(target_corpus_dir, exist_ok=True)
use_value_profile = int(random.random() < .3)
command = [
os.path.join(build_dir, 'src', 'test', 'fuzz', 'fuzz'),
"-runs=100000",
"-rss_limit_mb=8000",
"-max_total_time=6000",
"-reload=0",
f"-use_value_profile={use_value_profile}",
target_corpus_dir,
]
futures.append(fuzz_pool.submit(job, command, target))
Expand Down Expand Up @@ -298,11 +306,12 @@ def job(t, args):
sys.exit(1)


def parse_test_list(*, fuzz_bin):
def parse_test_list(*, fuzz_bin, source_dir):
test_list_all = subprocess.run(
fuzz_bin,
env={
'PRINT_ALL_FUZZ_TARGETS_AND_ABORT': ''
'PRINT_ALL_FUZZ_TARGETS_AND_ABORT': '',
**get_fuzz_env(target="", source_dir=source_dir)
},
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
Expand Down
Loading