Skip to content
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

backport: bitcoin#8456, #15704, #18850, #19241, #19317, #19493, #19739, #19903, #20003 #5813

Merged
merged 9 commits into from
Jan 11, 2024
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ case $host in
AC_MSG_ERROR("windres not found")
fi

CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -D_WIN32_WINNT=0x0601"
CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -D_WIN32_WINNT=0x0601 -D_WIN32_IE=0x0501 -DWIN32_LEAN_AND_MEAN"

dnl libtool insists upon adding -nostdlib and a list of objects/libs to link against.
dnl That breaks our ability to build dll's with static libgcc/libstdc++/libssp. Override
Expand Down
13 changes: 10 additions & 3 deletions doc/build-openbsd.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ OpenBSD build guide
======================
(updated for OpenBSD 6.2)

This guide describes how to build dashd and command-line utilities on OpenBSD.

OpenBSD is most commonly used as a server OS, so this guide does not contain instructions for building the GUI.
This guide describes how to build dashd, dash-qt, and command-line utilities on OpenBSD.

Preparation
-------------
Expand All @@ -13,6 +11,7 @@ Run the following as root to install the base dependencies for building:

```bash
pkg_add git gmake libevent libtool
pkg_add qt5 # (optional for enabling the GUI)
pkg_add autoconf # (select highest version, e.g. 2.69)
pkg_add automake # (select highest version, e.g. 1.15)
pkg_add python # (select highest version, e.g. 3.6)
Expand Down Expand Up @@ -75,6 +74,14 @@ To configure without wallet:
./configure --disable-wallet --with-gui=no CC=cc CXX=c++ MAKE=gmake
```

To configure with GUI:
```bash
./configure --with-gui=yes CC=cc CXX=c++ \
BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" \
BDB_CFLAGS="-I${BDB_PREFIX}/include" \
MAKE=gmake
```

Build and run the tests:
```bash
gmake # use -jX here for parallelism
Expand Down
4 changes: 2 additions & 2 deletions src/base58.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ static const int8_t mapBase58[256] = {
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
};

bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch, int max_ret_len)
[[nodiscard]] static bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch, int max_ret_len)
{
// Skip leading spaces.
while (*psz && IsSpace(*psz))
Expand Down Expand Up @@ -141,7 +141,7 @@ std::string EncodeBase58Check(Span<const unsigned char> input)
return EncodeBase58(vch);
}

bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet, int max_ret_len)
[[nodiscard]] static bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet, int max_ret_len)
{
if (!DecodeBase58(psz, vchRet, max_ret_len > std::numeric_limits<int>::max() - 4 ? std::numeric_limits<int>::max() : max_ret_len + 4) ||
(vchRet.size() < 4)) {
Expand Down
13 changes: 0 additions & 13 deletions src/base58.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,6 @@
*/
std::string EncodeBase58(Span<const unsigned char> input);

/**
* Decode a base58-encoded string (psz) into a byte vector (vchRet).
* return true if decoding is successful.
* psz cannot be nullptr.
*/
[[nodiscard]] bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet, int max_ret_len);

/**
* Decode a base58-encoded string (str) into a byte vector (vchRet).
* return true if decoding is successful.
Expand All @@ -43,12 +36,6 @@ std::string EncodeBase58(Span<const unsigned char> input);
*/
std::string EncodeBase58Check(Span<const unsigned char> input);

/**
* Decode a base58-encoded string (psz) that includes a checksum into a byte
* vector (vchRet), return true if decoding is successful
*/
[[nodiscard]] bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet, int max_ret_len);

/**
* Decode a base58-encoded string (str) that includes a checksum into a byte
* vector (vchRet), return true if decoding is successful
Expand Down
5 changes: 5 additions & 0 deletions src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ typedef std::map<int, uint256> MapCheckpoints;

struct CCheckpointData {
MapCheckpoints mapCheckpoints;

int GetHeight() const {
const auto& final_checkpoint = mapCheckpoints.rbegin();
return final_checkpoint->first /* height */;
}
};

struct AssumeutxoHash : public BaseHash<uint256> {
Expand Down
3 changes: 0 additions & 3 deletions src/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
#endif

#ifdef WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
Expand Down
6 changes: 5 additions & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ void SetupServerArgs(NodeContext& node)
argsman.AddArg("-checkblocks=<n>", strprintf("How many blocks to check at startup (default: %u, 0 = all)", DEFAULT_CHECKBLOCKS), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-checklevel=<n>", strprintf("How thorough the block verification of -checkblocks is: %s (0-4, default: %u)", Join(CHECKLEVEL_DOC, ", "), DEFAULT_CHECKLEVEL), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-checkmempool=<n>", strprintf("Run checks every <n> transactions (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-checkpoints", strprintf("Enable rejection of any forks from the known historical chain until block 1450000 (default: %u)", DEFAULT_CHECKPOINTS_ENABLED), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-checkpoints", strprintf("Enable rejection of any forks from the known historical chain until block %s (default: %u)", defaultChainParams->Checkpoints().GetHeight(), DEFAULT_CHECKPOINTS_ENABLED), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-deprecatedrpc=<method>", "Allows deprecated RPC method(s) to be used", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-limitancestorcount=<n>", strprintf("Do not accept transactions if number of in-mempool ancestors is <n> or more (default: %u)", DEFAULT_ANCESTOR_LIMIT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-limitancestorsize=<n>", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds <n> kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
Expand Down Expand Up @@ -1419,6 +1419,10 @@ bool AppInitParameterInteraction(const ArgsManager& args)

nMaxTipAge = args.GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE);

if (args.IsArgSet("-proxy") && args.GetArg("-proxy", "").empty()) {
return InitError(_("No proxy server specified. Use -proxy=<ip> or -proxy=<ip:port>."));
}

try {
const bool fRecoveryEnabled{llmq::utils::QuorumDataRecoveryEnabled()};
const bool fQuorumVvecRequestsEnabled{llmq::utils::GetEnabledQuorumVvecSyncEntries().size() > 0};
Expand Down
5 changes: 0 additions & 5 deletions src/qt/guiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@
#include <cmath>

#ifdef WIN32
#ifdef _WIN32_IE
#undef _WIN32_IE
#endif
#define _WIN32_IE 0x0501
#define WIN32_LEAN_AND_MEAN 1
#ifndef NOMINMAX
#define NOMINMAX
#endif
Expand Down
1 change: 0 additions & 1 deletion src/support/lockedpool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#endif

#ifdef WIN32
#define WIN32_LEAN_AND_MEAN 1
#ifndef NOMINMAX
#define NOMINMAX
#endif
Expand Down
6 changes: 0 additions & 6 deletions src/util/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,6 @@
#pragma warning(disable:4717)
#endif

#ifdef _WIN32_IE
#undef _WIN32_IE
#endif
#define _WIN32_IE 0x0501

#define WIN32_LEAN_AND_MEAN 1
#ifndef NOMINMAX
#define NOMINMAX
#endif
Expand Down
10 changes: 5 additions & 5 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1374,12 +1374,12 @@ void CChainState::InvalidChainFound(CBlockIndex* pindexNew)
pindexBestHeader = m_chain.Tip();
}

LogPrintf("%s: invalid block=%s height=%d log2_work=%.8f date=%s\n", __func__,
LogPrintf("%s: invalid block=%s height=%d log2_work=%f date=%s\n", __func__,
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
log(pindexNew->nChainWork.getdouble())/log(2.0), FormatISO8601DateTime(pindexNew->GetBlockTime()));
CBlockIndex *tip = m_chain.Tip();
assert (tip);
LogPrintf("%s: current best=%s height=%d log2_work=%.8f date=%s\n", __func__,
LogPrintf("%s: current best=%s height=%d log2_work=%f date=%s\n", __func__,
tip->GetBlockHash().ToString(), m_chain.Height(), log(tip->nChainWork.getdouble())/log(2.0),
FormatISO8601DateTime(tip->GetBlockTime()));
CheckForkWarningConditions();
Expand All @@ -1391,12 +1391,12 @@ void CChainState::ConflictingChainFound(CBlockIndex* pindexNew)

statsClient.inc("warnings.ConflictingChainFound", 1.0f);

LogPrintf("%s: conflicting block=%s height=%d log2_work=%.8f date=%s\n", __func__,
LogPrintf("%s: conflicting block=%s height=%d log2_work=%f date=%s\n", __func__,
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
log(pindexNew->nChainWork.getdouble())/log(2.0), FormatISO8601DateTime(pindexNew->GetBlockTime()));
CBlockIndex *tip = m_chain.Tip();
assert (tip);
LogPrintf("%s: current best=%s height=%d log2_work=%.8f date=%s\n", __func__,
LogPrintf("%s: current best=%s height=%d log2_work=%f date=%s\n", __func__,
tip->GetBlockHash().ToString(), m_chain.Height(), log(tip->nChainWork.getdouble())/log(2.0),
FormatISO8601DateTime(tip->GetBlockTime()));
CheckForkWarningConditions();
Expand Down Expand Up @@ -2704,7 +2704,7 @@ void CChainState::UpdateTip(const CBlockIndex* pindexNew)
}
}
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
LogPrintf("%s: new best=%s height=%d version=0x%08x log2_work=%.8g tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo) evodb_cache=%.1fMiB%s\n", __func__,
LogPrintf("%s: new best=%s height=%d version=0x%08x log2_work=%f tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo) evodb_cache=%.1fMiB%s\n", __func__,
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion,
log(pindexNew->nChainWork.getdouble())/log(2.0), (unsigned long)pindexNew->nChainTx,
FormatISO8601DateTime(pindexNew->GetBlockTime()),
Expand Down
33 changes: 33 additions & 0 deletions src/wallet/test/wallet_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1360,4 +1360,37 @@ BOOST_FIXTURE_TEST_CASE(dummy_input_size_test, TestChain100Setup)
BOOST_CHECK_EQUAL(CalculateNestedKeyhashInputSize(true), DUMMY_NESTED_P2PKH_INPUT_SIZE + 1);
}

BOOST_FIXTURE_TEST_CASE(ZapSelectTx, TestChain100Setup)
{
auto chain = interfaces::MakeChain(m_node);
auto wallet = TestLoadWallet(m_node);
CKey key;
key.MakeNewKey(true);
AddKey(*wallet, key);

std::string error;
m_coinbase_txns.push_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
auto block_tx = TestSimpleSpend(*m_coinbase_txns[0], 0, coinbaseKey, GetScriptForRawPubKey(key.GetPubKey()));
CreateAndProcessBlock({block_tx}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));

SyncWithValidationInterfaceQueue();

{
auto block_hash = block_tx.GetHash();
auto prev_hash = m_coinbase_txns[0]->GetHash();

LOCK(wallet->cs_wallet);
BOOST_CHECK(wallet->HasWalletSpend(prev_hash));
BOOST_CHECK_EQUAL(wallet->mapWallet.count(block_hash), 1u);

std::vector<uint256> vHashIn{ block_hash }, vHashOut;
BOOST_CHECK_EQUAL(wallet->ZapSelectTx(vHashIn, vHashOut), DBErrors::LOAD_OK);

BOOST_CHECK(!wallet->HasWalletSpend(prev_hash));
BOOST_CHECK_EQUAL(wallet->mapWallet.count(block_hash), 0u);
}

TestUnloadWallet(std::move(wallet));
}

BOOST_AUTO_TEST_SUITE_END()
11 changes: 10 additions & 1 deletion src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,13 @@ std::set<uint256> CWallet::GetConflicts(const uint256& txid) const
return result;
}

bool CWallet::HasWalletSpend(const uint256& txid) const
{
AssertLockHeld(cs_wallet);
auto iter = mapTxSpends.lower_bound(COutPoint(txid, 0));
return (iter != mapTxSpends.end() && iter->first.hash == txid);
}

void CWallet::Flush()
{
GetDatabase().Flush();
Expand Down Expand Up @@ -3912,9 +3919,11 @@ DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256
WalletLogPrintf("ZapSelectTx started for %d transactions...\n", vHashIn.size());

DBErrors nZapSelectTxRet = WalletBatch(GetDatabase()).ZapSelectTx(vHashIn, vHashOut);
for (uint256 hash : vHashOut) {
for (const uint256& hash : vHashOut) {
const auto& it = mapWallet.find(hash);
wtxOrdered.erase(it->second.m_it_wtxOrdered);
for (const auto& txin : it->second.tx->vin)
mapTxSpends.erase(txin.prevout);
mapWallet.erase(it);
NotifyTransactionChanged(this, hash, CT_DELETED);
}
Expand Down
3 changes: 3 additions & 0 deletions src/wallet/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -1190,6 +1190,9 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
//! Get wallet transactions that conflict with given transaction (spend same outputs)
std::set<uint256> GetConflicts(const uint256& txid) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);

//! Check if a given transaction has any of its outputs spent by another transaction in the wallet
bool HasWalletSpend(const uint256& txid) const;

//! Flush wallet (bitdb flush)
void Flush();

Expand Down
6 changes: 6 additions & 0 deletions test/functional/feature_config_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ def test_config_file_parser(self):
with open(inc_conf_file2_path, 'w', encoding='utf-8') as conf:
conf.write('') # clear

def test_invalid_command_line_options(self):
self.nodes[0].assert_start_raises_init_error(
expected_msg='Error: No proxy server specified. Use -proxy=<ip> or -proxy=<ip:port>.',
extra_args=['-proxy'],
)

def test_log_buffer(self):
with self.nodes[0].assert_debug_log(expected_msgs=['Warning: parsed potentially confusing double-negative -connect=0\n']):
Expand Down Expand Up @@ -124,6 +129,7 @@ def run_test(self):


self.test_config_file_parser()
self.test_invalid_command_line_options()

# Remove the -datadir argument so it doesn't override the config file
self.nodes[0].args = [arg for arg in self.nodes[0].args if not arg.startswith("-datadir")]
Expand Down
Loading