Merge #6047: backport: trivial 2024 06 05

76279c1a37 Merge bitcoin/bitcoin#25149: refactor: Add thread safety annotation to `BanMan::SweepBanned()` (MacroFake)
6269c6f1db Merge bitcoin/bitcoin#25053: Guard `#include <config/bitcoin-config.h>` (fanquake)
d50f0b016f Merge bitcoin/bitcoin#24977: rpc: Explain active and internal in listdescriptors (fanquake)
3c44399d55 Merge bitcoin/bitcoin#24856: lint: Converting lint-assertions.sh to lint-assertions.py (laanwj)
e9f5b4b735 Merge bitcoin/bitcoin#24213: refactor: use Span in random.* (laanwj)
7e0474ac1c Merge bitcoin/bitcoin#24632: add `(none)` in -getinfo `Warnings:` if no warning returned (laanwj)
57e9b56bad Merge bitcoin/bitcoin#24145: mempool: Clear vTxHashes when mapTx is cleared (laanwj)
fe56d9b994 Merge bitcoin/bitcoin#24698: test: -peerblockfilters without -blockfilterindex raises an error (MarcoFalke)
3cabce645e Merge bitcoin/bitcoin#24472: fuzz: execute each file in dir without fuzz engine (MarcoFalke)
f5116a7d31 Merge bitcoin-core/gui#549: refactor: use std::chrono for formatDurationStr() helper (Hennadii Stepanov)
3fa8158510 Merge bitcoin/bitcoin#22317: doc: Highlight DNS requests part in tor.md (Andrew Chow)
72b62edd5a Merge bitcoin/bitcoin#23834: wallettool: Check that the dumpfile checksum is the correct size (laanwj)
ee9b3cdb0e Merge bitcoin/bitcoin#23979: test: wait for rather than assert presence of file in startupnotify test (MarcoFalke)
2ec5940399 Merge bitcoin/bitcoin#23532: test: add functional test for -startupnotify (MarcoFalke)
5a31be9608 Merge bitcoin/bitcoin#23812: test: fix intermittent failures in p2p_timeouts.py (MarcoFalke)
10828f5b3d Merge bitcoin/bitcoin#23733: fuzz: Move ISO8601 to one place (MarcoFalke)
7f39b5af41 Merge bitcoin/bitcoin#23635: test: Bump shellcheck version to 0.8.0 (fanquake)

Pull request description:

  ## Issue being fixed or feature implemented
  Trivial batch of backports

  ## What was done?
  trivial backports

  ## How Has This Been Tested?
  Unit tests ran; waiting on CI

  ## Breaking Changes

  ## Checklist:
    _Go over all the following points, and put an `x` in all the boxes that apply._
  - [ ] I have performed a self-review of my own code
  - [ ] I have commented my code, particularly in hard-to-understand areas
  - [ ] I have added or updated relevant unit/integration/functional/e2e tests
  - [ ] I have made corresponding changes to the documentation
  - [ ] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

Top commit has no ACKs.

Tree-SHA512: a3f97003e6441468951b827b2c3ea607740e5b9d36b96c2f93e45e7fb4088ecf4d0a2b7038de050ca0e7d61379c364969f4a8caff98ec1cc69016f4114e64c6a
This commit is contained in:
pasta 2024-06-07 09:33:35 -05:00
commit d7413ffbf7
No known key found for this signature in database
GPG Key ID: 52527BEDABE87984
37 changed files with 268 additions and 118 deletions

View File

@ -17,6 +17,6 @@ ${CI_RETRY_EXE} pip3 install vulture==2.3
${CI_RETRY_EXE} pip3 install yq
${CI_RETRY_EXE} pip3 install mypy==0.781
SHELLCHECK_VERSION=v0.7.2
SHELLCHECK_VERSION=v0.8.0
curl -sL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" | tar --xz -xf - --directory /tmp/
export PATH="/tmp/shellcheck-${SHELLCHECK_VERSION}:${PATH}"

View File

@ -34,7 +34,7 @@ check_tools cat mkdir make git guix
#
under_dir() {
local path_residue
path_residue="${2##${1}}"
path_residue="${2##"${1}"}"
if [ -z "$path_residue" ] || [ "$path_residue" = "$2" ]; then
return 1
else

View File

@ -35,9 +35,11 @@ outgoing connections, but more is possible.
-onion=ip:port Set the proxy server to use for Tor onion services. You do not
need to set this if it's the same as -proxy. You can use -onion=0
to explicitly disable access to onion services.
------------------------------------------------------------------
Note: Only the -proxy option sets the proxy for DNS requests;
with -onion they will not route over Tor, so use -proxy if you
have privacy concerns.
------------------------------------------------------------------
-listen When using -proxy, listening is disabled by default. If you want
to manually configure an onion service (see section 3), you'll

View File

@ -42,7 +42,7 @@ bool SerializeFileDB(const std::string& prefix, const fs::path& path, const Data
{
// Generate random temporary filename
uint16_t randv = 0;
GetRandBytes((unsigned char*)&randv, sizeof(randv));
GetRandBytes({(unsigned char*)&randv, sizeof(randv)});
std::string tmpfn = strprintf("%s.%04x", prefix, randv);
// open temp output file, and associate with CAutoFile

View File

@ -16,6 +16,19 @@
BanMan::BanMan(fs::path ban_file, CClientUIInterface* client_interface, int64_t default_ban_time)
: m_client_interface(client_interface), m_ban_db(std::move(ban_file)), m_default_ban_time(default_ban_time)
{
LoadBanlist();
DumpBanlist();
}
BanMan::~BanMan()
{
DumpBanlist();
}
void BanMan::LoadBanlist()
{
LOCK(m_cs_banned);
if (m_client_interface) m_client_interface->InitMessage(_("Loading banlist…").translated);
int64_t n_start = GetTimeMillis();
@ -29,13 +42,6 @@ BanMan::BanMan(fs::path ban_file, CClientUIInterface* client_interface, int64_t
m_banned = {};
m_is_dirty = true;
}
DumpBanlist();
}
BanMan::~BanMan()
{
DumpBanlist();
}
void BanMan::DumpBanlist()
@ -183,23 +189,24 @@ void BanMan::GetBanned(banmap_t& banmap)
void BanMan::SweepBanned()
{
AssertLockHeld(m_cs_banned);
int64_t now = GetTime();
bool notify_ui = false;
{
LOCK(m_cs_banned);
banmap_t::iterator it = m_banned.begin();
while (it != m_banned.end()) {
CSubNet sub_net = (*it).first;
CBanEntry ban_entry = (*it).second;
if (!sub_net.IsValid() || now > ban_entry.nBanUntil) {
m_banned.erase(it++);
m_is_dirty = true;
notify_ui = true;
LogPrint(BCLog::NET, "Removed banned node address/subnet: %s\n", sub_net.ToString());
} else
++it;
banmap_t::iterator it = m_banned.begin();
while (it != m_banned.end()) {
CSubNet sub_net = (*it).first;
CBanEntry ban_entry = (*it).second;
if (!sub_net.IsValid() || now > ban_entry.nBanUntil) {
m_banned.erase(it++);
m_is_dirty = true;
notify_ui = true;
LogPrint(BCLog::NET, "Removed banned node address/subnet: %s\n", sub_net.ToString());
} else {
++it;
}
}
// update UI
if (notify_ui && m_client_interface) {
m_client_interface->BannedListChanged();

View File

@ -81,11 +81,12 @@ public:
void DumpBanlist();
private:
void LoadBanlist() EXCLUSIVE_LOCKS_REQUIRED(!m_cs_banned);
bool BannedSetIsDirty();
//!set the "dirty" flag for the banlist
void SetBannedSetDirty(bool dirty = true);
//!clean unused entries (if bantime has expired)
void SweepBanned();
void SweepBanned() EXCLUSIVE_LOCKS_REQUIRED(m_cs_banned);
RecursiveMutex m_cs_banned;
banmap_t m_banned GUARDED_BY(m_cs_banned);

View File

@ -1048,7 +1048,9 @@ static void ParseGetInfoResult(UniValue& result)
result_string += "\n";
}
result_string += strprintf("%sWarnings:%s %s", YELLOW, RESET, result["warnings"].getValStr());
const std::string warnings{result["warnings"].getValStr()};
result_string += strprintf("%sWarnings:%s %s", YELLOW, RESET, warnings.empty() ? "(none)" : warnings);
result.setStr(result_string);
}

View File

@ -63,7 +63,7 @@ void CBLSSecretKey::MakeNewKey()
{
unsigned char buf[SerSize];
while (true) {
GetStrongRandBytes(buf, sizeof(buf));
GetStrongRandBytes({buf, sizeof(buf)});
try {
impl = bls::PrivateKey::FromBytes(bls::Bytes(reinterpret_cast<const uint8_t*>(buf), SerSize));
break;

View File

@ -97,7 +97,7 @@ void CBLSIESMultiRecipientBlobs::InitEncrypt(size_t count)
{
ephemeralSecretKey.MakeNewKey();
ephemeralPubKey = ephemeralSecretKey.GetPublicKey();
GetStrongRandBytes(ivSeed.begin(), ivSeed.size());
GetStrongRandBytes({ivSeed.begin(), ivSeed.size()});
uint256 iv = ivSeed;
ivVector.resize(count);

View File

@ -224,7 +224,7 @@ const unsigned int CDBWrapper::OBFUSCATE_KEY_NUM_BYTES = 8;
std::vector<unsigned char> CDBWrapper::CreateObfuscateKey() const
{
std::vector<uint8_t> ret(OBFUSCATE_KEY_NUM_BYTES);
GetRandBytes(ret.data(), OBFUSCATE_KEY_NUM_BYTES);
GetRandBytes(ret);
return ret;
}

View File

@ -157,7 +157,7 @@ bool CKey::Check(const unsigned char *vch) {
void CKey::MakeNewKey(bool fCompressedIn) {
do {
GetStrongRandBytes(keydata.data(), keydata.size());
GetStrongRandBytes(keydata);
} while (!Check(keydata.data()));
fValid = true;
fCompressed = fCompressedIn;
@ -242,7 +242,7 @@ bool CKey::VerifyPubKey(const CPubKey& pubkey) const {
}
unsigned char rnd[8];
std::string str = "Bitcoin key verification\n";
GetRandBytes(rnd, sizeof(rnd));
GetRandBytes(rnd);
uint256 hash;
CHash256().Write(MakeUCharSpan(str)).Write(rnd).Finalize(hash);
std::vector<unsigned char> vchSig;
@ -406,7 +406,7 @@ void ECC_Start() {
{
// Pass in a random blinding seed to the secp256k1 context.
std::vector<unsigned char, secure_allocator<unsigned char>> vseed(32);
GetRandBytes(vseed.data(), 32);
GetRandBytes(vseed);
bool ret = secp256k1_context_randomize(ctx, vseed.data());
assert(ret);
}

View File

@ -1247,7 +1247,7 @@ void PeerManagerImpl::PushNodeVersion(CNode& pnode, const Peer& peer)
CAddress addrMe = CAddress(CService(), nLocalNodeServices);
uint256 mnauthChallenge;
GetRandBytes(mnauthChallenge.begin(), mnauthChallenge.size());
GetRandBytes({mnauthChallenge.begin(), mnauthChallenge.size()});
pnode.SetSentMNAuthChallenge(mnauthChallenge);
int nProtocolVersion = PROTOCOL_VERSION;
@ -5220,7 +5220,7 @@ void PeerManagerImpl::MaybeSendPing(CNode& node_to, Peer& peer, std::chrono::mic
if (pingSend) {
uint64_t nonce = 0;
while (nonce == 0) {
GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
GetRandBytes({(unsigned char*)&nonce, sizeof(nonce)});
}
peer.m_ping_queued = false;
peer.m_ping_start = now;

View File

@ -1676,23 +1676,18 @@ QString ConnectionTypeToQString(ConnectionType conn_type)
QString formatDurationStr(std::chrono::seconds dur)
{
const auto secs = count_seconds(dur);
QStringList strList;
int days = secs / 86400;
int hours = (secs % 86400) / 3600;
int mins = (secs % 3600) / 60;
int seconds = secs % 60;
if (days)
strList.append(QObject::tr("%1 d").arg(days));
if (hours)
strList.append(QObject::tr("%1 h").arg(hours));
if (mins)
strList.append(QObject::tr("%1 m").arg(mins));
if (seconds || (!days && !hours && !mins))
strList.append(QObject::tr("%1 s").arg(seconds));
return strList.join(" ");
using days = std::chrono::duration<int, std::ratio<86400>>; // can remove this line after C++20
const auto d{std::chrono::duration_cast<days>(dur)};
const auto h{std::chrono::duration_cast<std::chrono::hours>(dur - d)};
const auto m{std::chrono::duration_cast<std::chrono::minutes>(dur - d - h)};
const auto s{std::chrono::duration_cast<std::chrono::seconds>(dur - d - h - m)};
QStringList str_list;
if (auto d2{d.count()}) str_list.append(QObject::tr("%1 d").arg(d2));
if (auto h2{h.count()}) str_list.append(QObject::tr("%1 h").arg(h2));
if (auto m2{m.count()}) str_list.append(QObject::tr("%1 m").arg(m2));
const auto s2{s.count()};
if (s2 || str_list.empty()) str_list.append(QObject::tr("%1 s").arg(s2));
return str_list.join(" ");
}
QString formatServicesStr(quint64 mask)

View File

@ -17,6 +17,7 @@
#include <logging.h> // for LogPrintf()
#include <randomenv.h>
#include <support/allocators/secure.h>
#include <span.h>
#include <sync.h> // for Mutex
#include <util/time.h> // for GetTimeMicros()
@ -582,8 +583,8 @@ static void ProcRand(unsigned char* out, int num, RNGLevel level) noexcept
}
}
void GetRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::FAST); }
void GetStrongRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::SLOW); }
void GetRandBytes(Span<unsigned char> bytes) noexcept { ProcRand(bytes.data(), bytes.size(), RNGLevel::FAST); }
void GetStrongRandBytes(Span<unsigned char> bytes) noexcept { ProcRand(bytes.data(), bytes.size(), RNGLevel::SLOW); }
void RandAddPeriodic() noexcept { ProcRand(nullptr, 0, RNGLevel::PERIODIC); }
void RandAddEvent(const uint32_t event_info) noexcept { GetRNGState().AddEvent(event_info); }
@ -602,7 +603,7 @@ int GetRandInt(int nMax) noexcept
uint256 GetRandHash() noexcept
{
uint256 hash;
GetRandBytes((unsigned char*)&hash, sizeof(hash));
GetRandBytes(hash);
return hash;
}

View File

@ -69,7 +69,7 @@
*
* Thread-safe.
*/
void GetRandBytes(unsigned char* buf, int num) noexcept;
void GetRandBytes(Span<unsigned char> bytes) noexcept;
/** Generate a uniform random integer in the range [0..range). Precondition: range > 0 */
uint64_t GetRand(uint64_t nMax) noexcept;
/** Generate a uniform random duration in the range [0..max). Precondition: max.count() > 0 */
@ -98,7 +98,7 @@ bool GetRandBool(double rate);
*
* Thread-safe.
*/
void GetStrongRandBytes(unsigned char* buf, int num) noexcept;
void GetStrongRandBytes(Span<unsigned char> bytes) noexcept;
/**
* Gather entropy from various expensive sources, and feed them to the PRNG state.

View File

@ -77,7 +77,7 @@ bool GenerateAuthCookie(std::string *cookie_out)
{
const size_t COOKIE_SIZE = 32;
unsigned char rand_pwd[COOKIE_SIZE];
GetRandBytes(rand_pwd, COOKIE_SIZE);
GetRandBytes(rand_pwd);
std::string cookie = COOKIEAUTH_USER + ":" + HexStr(rand_pwd);
/** the umask determines what permissions are used to create this file -

View File

@ -5,14 +5,16 @@
#include <shutdown.h>
#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif
#include <logging.h>
#include <util/tokenpipe.h>
#include <node/ui_interface.h>
#include <warnings.h>
#include <config/bitcoin-config.h>
#include <assert.h>
#include <atomic>
#ifdef WIN32

View File

@ -9,7 +9,9 @@
#include <test/util/setup_common.h>
#include <util/check.h>
#include <util/sock.h>
#include <util/time.h>
#include <csignal>
#include <cstdint>
#include <string>
#include <exception>
@ -31,6 +33,7 @@ void FuzzFrameworkRegisterTarget(std::string_view name, TypeTestOneInput target,
Assert(it_ins.second);
}
static std::string_view g_fuzz_target;
static TypeTestOneInput* g_test_one_input{nullptr};
void initialize()
@ -64,9 +67,12 @@ void initialize()
should_abort = true;
}
Assert(!should_abort);
std::string_view fuzz_target{Assert(std::getenv("FUZZ"))};
const auto it = FuzzTargets().find(fuzz_target);
Assert(it != FuzzTargets().end());
g_fuzz_target = Assert(std::getenv("FUZZ"));
const auto it = FuzzTargets().find(g_fuzz_target);
if (it == FuzzTargets().end()) {
std::cerr << "No fuzzer for " << g_fuzz_target << "." << std::endl;
std::exit(EXIT_FAILURE);
}
Assert(!g_test_one_input);
g_test_one_input = &std::get<0>(it->second);
std::get<1>(it->second)();
@ -84,6 +90,35 @@ static bool read_stdin(std::vector<uint8_t>& data)
}
#endif
#if defined(PROVIDE_FUZZ_MAIN_FUNCTION) && !defined(__AFL_LOOP)
static bool read_file(fs::path p, std::vector<uint8_t>& data)
{
uint8_t buffer[1024];
FILE* f = fsbridge::fopen(p, "rb");
if (f == nullptr) return false;
do {
const size_t length = fread(buffer, sizeof(uint8_t), sizeof(buffer), f);
if (ferror(f)) return false;
data.insert(data.end(), buffer, buffer + length);
} while (!feof(f));
fclose(f);
return true;
}
#endif
#if defined(PROVIDE_FUZZ_MAIN_FUNCTION) && !defined(__AFL_LOOP)
static fs::path g_input_path;
void signal_handler(int signal)
{
if (signal == SIGABRT) {
std::cerr << "Error processing input " << g_input_path << std::endl;
} else {
std::cerr << "Unexpected signal " << signal << " received\n";
}
std::_Exit(EXIT_FAILURE);
}
#endif
// This function is used by libFuzzer
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
@ -122,10 +157,37 @@ int main(int argc, char** argv)
}
#else
std::vector<uint8_t> buffer;
if (!read_stdin(buffer)) {
if (argc <= 1) {
if (!read_stdin(buffer)) {
return 0;
}
test_one_input(buffer);
return 0;
}
test_one_input(buffer);
std::signal(SIGABRT, signal_handler);
int64_t start_time = GetTimeSeconds();
int tested = 0;
for (int i = 1; i < argc; ++i) {
fs::path input_path(*(argv + i));
if (fs::is_directory(input_path)) {
for (fs::directory_iterator it(input_path); it != fs::directory_iterator(); ++it) {
if (!fs::is_regular_file(it->path())) continue;
g_input_path = it->path();
Assert(read_file(it->path(), buffer));
test_one_input(buffer);
++tested;
buffer.clear();
}
} else {
g_input_path = input_path;
Assert(read_file(input_path, buffer));
test_one_input(buffer);
++tested;
buffer.clear();
}
}
int64_t end_time = GetTimeSeconds();
std::cout << g_fuzz_target << ": succeeded against " << tested << " files in " << (end_time - start_time) << "s." << std::endl;
#endif
return 0;
}

View File

@ -32,12 +32,10 @@
#include <util/strencodings.h>
#include <util/string.h>
#include <util/system.h>
#include <util/time.h>
#include <version.h>
#include <cassert>
#include <chrono>
#include <ctime>
#include <limits>
#include <optional>
#include <set>
@ -78,8 +76,6 @@ FUZZ_TARGET_INIT(integer, initialize_integer)
(void)ComputeMerkleRoot(v256);
(void)CountBits(u64);
(void)DecompressAmount(u64);
(void)FormatISO8601Date(i64);
(void)FormatISO8601DateTime(i64);
{
if (std::optional<CAmount> parsed = ParseMoney(FormatMoney(i64))) {

View File

@ -19,6 +19,7 @@ FUZZ_TARGET(parse_iso8601)
const std::string random_string = fuzzed_data_provider.ConsumeRemainingBytesAsString();
const std::string iso8601_datetime = FormatISO8601DateTime(random_time);
(void)FormatISO8601Date(random_time);
const int64_t parsed_time_1 = ParseISO8601DateTime(iso8601_datetime);
if (random_time >= 0) {
assert(parsed_time_1 >= 0);

View File

@ -204,7 +204,7 @@ BOOST_AUTO_TEST_CASE(key_key_negation)
// create a dummy hash for signature comparison
unsigned char rnd[8];
std::string str = "Bitcoin key verification\n";
GetRandBytes(rnd, sizeof(rnd));
GetRandBytes(rnd);
uint256 hash;
CHash256().Write(MakeUCharSpan(str)).Write(rnd).Finalize(hash);

View File

@ -511,7 +511,7 @@ void TorController::protocolinfo_cb(TorControlConnection& _conn, const TorContro
// _conn.Command("AUTHENTICATE " + HexStr(status_cookie.second), std::bind(&TorController::auth_cb, this, std::placeholders::_1, std::placeholders::_2));
cookie = std::vector<uint8_t>(status_cookie.second.begin(), status_cookie.second.end());
clientNonce = std::vector<uint8_t>(TOR_NONCE_SIZE, 0);
GetRandBytes(clientNonce.data(), TOR_NONCE_SIZE);
GetRandBytes(clientNonce);
_conn.Command("AUTHCHALLENGE SAFECOOKIE " + HexStr(clientNonce), std::bind(&TorController::authchallenge_cb, this, std::placeholders::_1, std::placeholders::_2));
} else {
if (status_cookie.first) {

View File

@ -1020,6 +1020,7 @@ void CTxMemPool::removeExpiredAssetUnlock(int nBlockHeight)
void CTxMemPool::_clear()
{
vTxHashes.clear();
mapTx.clear();
mapNextTx.clear();
mapProTxAddresses.clear();

View File

@ -8,8 +8,8 @@
ByteVectorHash::ByteVectorHash()
{
GetRandBytes(reinterpret_cast<unsigned char*>(&m_k0), sizeof(m_k0));
GetRandBytes(reinterpret_cast<unsigned char*>(&m_k1), sizeof(m_k1));
GetRandBytes({reinterpret_cast<unsigned char*>(&m_k0), sizeof(m_k0)});
GetRandBytes({reinterpret_cast<unsigned char*>(&m_k1), sizeof(m_k1)});
}
size_t ByteVectorHash::operator()(const std::vector<unsigned char>& input) const

View File

@ -3,7 +3,9 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <util/tokenpipe.h>
#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif
#ifndef WIN32

View File

@ -36,7 +36,7 @@ SecureString CMnemonic::Generate(int strength)
return SecureString();
}
SecureVector data(32);
GetStrongRandBytes(data.data(), 32);
GetStrongRandBytes({data.data(), 32});
SecureString mnemonic = FromData(data, strength / 8);
return mnemonic;
}

View File

@ -215,6 +215,11 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling
if (key == "checksum") {
std::vector<unsigned char> parsed_checksum = ParseHex(value);
if (parsed_checksum.size() != checksum.size()) {
error = Untranslated("Error: Checksum is not the correct size");
ret = false;
break;
}
std::copy(parsed_checksum.begin(), parsed_checksum.end(), checksum.begin());
break;
}

View File

@ -1951,13 +1951,13 @@ RPCHelpMan listdescriptors()
{RPCResult::Type::OBJ, "", "", {
{RPCResult::Type::STR, "desc", "Descriptor string representation"},
{RPCResult::Type::NUM, "timestamp", "The creation time of the descriptor"},
{RPCResult::Type::BOOL, "active", "Activeness flag"},
{RPCResult::Type::BOOL, "internal", true, "Whether this is an internal or external descriptor; defined only for active descriptors"},
{RPCResult::Type::ARR_FIXED, "range", true, "Defined only for ranged descriptors", {
{RPCResult::Type::BOOL, "active", "Whether this descriptor is currently used to generate new addresses"},
{RPCResult::Type::BOOL, "internal", /*optional=*/true, "True if this descriptor is used to generate change addresses. False if this descriptor is used to generate receiving addresses; defined only for active descriptors"},
{RPCResult::Type::ARR_FIXED, "range", /*optional=*/true, "Defined only for ranged descriptors", {
{RPCResult::Type::NUM, "", "Range start inclusive"},
{RPCResult::Type::NUM, "", "Range end inclusive"},
}},
{RPCResult::Type::NUM, "next", true, "The next index to generate addresses from; defined only for ranged descriptors"},
{RPCResult::Type::NUM, "next", /*optional=*/true, "The next index to generate addresses from; defined only for ranged descriptors"},
}},
}}
}},

View File

@ -93,7 +93,7 @@ BOOST_AUTO_TEST_CASE(passphrase) {
std::string hash(GetRandHash().ToString());
std::vector<unsigned char> vchSalt(8);
GetRandBytes(vchSalt.data(), vchSalt.size());
GetRandBytes(vchSalt);
uint32_t rounds = InsecureRand32();
if (rounds > 30000)
rounds = 30000;

View File

@ -616,12 +616,12 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
CKeyingMaterial _vMasterKey;
_vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
GetStrongRandBytes(_vMasterKey.data(), WALLET_CRYPTO_KEY_SIZE);
GetStrongRandBytes(_vMasterKey);
CMasterKey kMasterKey;
kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
GetStrongRandBytes(kMasterKey.vchSalt.data(), WALLET_CRYPTO_SALT_SIZE);
GetStrongRandBytes(kMasterKey.vchSalt);
CCrypter crypter;
int64_t nStartTime = GetTimeMillis();

View File

@ -0,0 +1,41 @@
#!/usr/bin/env python3
# Copyright (c) 2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test -startupnotify."""
import os
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
)
NODE_DIR = "node0"
FILE_NAME = "test.txt"
class StartupNotifyTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
self.disable_syscall_sandbox = True
def run_test(self):
tmpdir_file = os.path.join(self.options.tmpdir, NODE_DIR, FILE_NAME)
assert not os.path.exists(tmpdir_file)
self.log.info("Test -startupnotify command is run when node starts")
self.restart_node(0, extra_args=[f"-startupnotify=echo '{FILE_NAME}' >> {NODE_DIR}/{FILE_NAME}"])
self.wait_until(lambda: os.path.exists(tmpdir_file))
self.log.info("Test -startupnotify is executed once")
with open(tmpdir_file, "r", encoding="utf8") as f:
file_content = f.read()
assert_equal(file_content.count(FILE_NAME), 1)
self.log.info("Test node is fully started")
assert_equal(self.nodes[0].getblockcount(), 200)
if __name__ == '__main__':
StartupNotifyTest().main()

View File

@ -245,6 +245,12 @@ class CompactFiltersTest(BitcoinTestFramework):
peer_0.send_message(request)
peer_0.wait_for_disconnect()
self.log.info("Test -peerblockfilters without -blockfilterindex raises an error")
self.stop_node(0)
self.nodes[0].extra_args = ["-peerblockfilters"]
msg = "Error: Cannot set -peerblockfilters without -blockfilterindex."
self.nodes[0].assert_start_raises_init_error(expected_msg=msg)
def compute_last_header(prev_header, hashes):
"""Compute the last filter header from a starting header and a sequence of filter hashes."""

View File

@ -48,10 +48,13 @@ class TimeoutsTest(BitcoinTestFramework):
self.mock_time = int(time.time())
self.mock_forward(0)
# Setup the p2p connections
no_verack_node = self.nodes[0].add_p2p_connection(TestP2PConn(), wait_for_verack=False)
no_version_node = self.nodes[0].add_p2p_connection(TestP2PConn(), send_version=False, wait_for_verack=False)
no_send_node = self.nodes[0].add_p2p_connection(TestP2PConn(), send_version=False, wait_for_verack=False)
# Setup the p2p connections, making sure the connections are established before the mocktime is bumped
with self.nodes[0].assert_debug_log(['Added connection peer=0']):
no_verack_node = self.nodes[0].add_p2p_connection(TestP2PConn(), wait_for_verack=False)
with self.nodes[0].assert_debug_log(['Added connection peer=1']):
no_version_node = self.nodes[0].add_p2p_connection(TestP2PConn(), send_version=False, wait_for_verack=False)
with self.nodes[0].assert_debug_log(['Added connection peer=2']):
no_send_node = self.nodes[0].add_p2p_connection(TestP2PConn(), send_version=False, wait_for_verack=False)
# Wait until we got the verack in response to the version. Though, don't wait for the other node to receive the
# verack, since we never sent one

View File

@ -266,6 +266,7 @@ BASE_SCRIPTS = [
'rpc_bind.py --nonloopback',
'mining_basic.py',
'rpc_named_arguments.py',
'feature_startupnotify.py',
'wallet_listsinceblock.py --legacy-wallet',
'wallet_listsinceblock.py --descriptors',
'wallet_listdescriptors.py --descriptors',

View File

@ -396,7 +396,11 @@ class ToolWalletTest(BitcoinTestFramework):
bad_sum_wallet_dump = os.path.join(self.nodes[0].datadir, "wallet-bad_sum3.dump")
dump_data["checksum"] = "2" * 10
self.write_dump(dump_data, bad_sum_wallet_dump)
self.assert_raises_tool_error('Error: Dumpfile checksum does not match. Computed {}, expected {}{}'.format(checksum, "2" * 10, "0" * 54), '-wallet=badload', '-dumpfile={}'.format(bad_sum_wallet_dump), 'createfromdump')
self.assert_raises_tool_error('Error: Checksum is not the correct size', '-wallet=badload', '-dumpfile={}'.format(bad_sum_wallet_dump), 'createfromdump')
assert not os.path.isdir(os.path.join(self.nodes[0].datadir, "regtest/wallets", "badload"))
dump_data["checksum"] = "3" * 66
self.write_dump(dump_data, bad_sum_wallet_dump)
self.assert_raises_tool_error('Error: Checksum is not the correct size', '-wallet=badload', '-dumpfile={}'.format(bad_sum_wallet_dump), 'createfromdump')
assert not os.path.isdir(os.path.join(self.nodes[0].datadir, "regtest/wallets", "badload"))

52
test/lint/lint-assertions.py Executable file
View File

@ -0,0 +1,52 @@
#!/usr/bin/env python3
#
# Copyright (c) 2018-2022 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
# Check for assertions with obvious side effects.
import sys
import subprocess
def git_grep(params: [], error_msg: ""):
try:
output = subprocess.check_output(["git", "grep", *params], universal_newlines=True, encoding="utf8")
print(error_msg)
print(output)
return 1
except subprocess.CalledProcessError as ex1:
if ex1.returncode > 1:
raise ex1
return 0
def main():
# PRE31-C (SEI CERT C Coding Standard):
# "Assertions should not contain assignments, increment, or decrement operators."
exit_code = git_grep([
"-E",
r"[^_]assert\(.*(\+\+|\-\-|[^=!<>]=[^=!<>]).*\);",
"--",
"*.cpp",
"*.h"
], "Assertions should not have side effects:")
# Macro CHECK_NONFATAL(condition) should be used instead of assert for RPC code, where it
# is undesirable to crash the whole program. See: src/util/check.h
# src/rpc/server.cpp is excluded from this check since it's mostly meta-code.
exit_code |= git_grep([
"-nE",
r"\<(A|a)ssert *\(.*\);",
"--",
"src/rpc/",
"src/wallet/rpc*",
":(exclude)src/rpc/server.cpp"
], "CHECK_NONFATAL(condition) should be used instead of assert for RPC code.")
sys.exit(exit_code)
if __name__ == "__main__":
main()

View File

@ -1,34 +0,0 @@
#!/usr/bin/env bash
#
# Copyright (c) 2018-2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
# Check for assertions with obvious side effects.
export LC_ALL=C
EXIT_CODE=0
# PRE31-C (SEI CERT C Coding Standard):
# "Assertions should not contain assignments, increment, or decrement operators."
OUTPUT=$(git grep -E '[^_]assert\(.*(\+\+|\-\-|[^=!<>]=[^=!<>]).*\);' -- "*.cpp" "*.h")
if [[ ${OUTPUT} != "" ]]; then
echo "Assertions should not have side effects:"
echo
echo "${OUTPUT}"
EXIT_CODE=1
fi
# Macro CHECK_NONFATAL(condition) should be used instead of assert for RPC code, where it
# is undesirable to crash the whole program. See: src/util/check.h
# src/rpc/server.cpp is excluded from this check since it's mostly meta-code.
OUTPUT=$(git grep -nE '\<(A|a)ssert *\(.*\);' -- "src/rpc/" "src/wallet/rpc*" ":(exclude)src/rpc/server.cpp")
if [[ ${OUTPUT} != "" ]]; then
echo "CHECK_NONFATAL(condition) should be used instead of assert for RPC code."
echo
echo "${OUTPUT}"
EXIT_CODE=1
fi
exit ${EXIT_CODE}