Merge pull request #5813 from knst/bp-v21-p7

backport: bitcoin#8456, #15704, #18850, #19241, #19317, #19493, #19739, #19903, #20003
This commit is contained in:
PastaPastaPasta 2024-01-10 19:23:28 -06:00 committed by GitHub
commit a78c28d572
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 80 additions and 41 deletions

View File

@ -691,7 +691,7 @@ case $host in
AC_MSG_ERROR("windres not found") AC_MSG_ERROR("windres not found")
fi 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 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 dnl That breaks our ability to build dll's with static libgcc/libstdc++/libssp. Override

View File

@ -2,9 +2,7 @@ OpenBSD build guide
====================== ======================
(updated for OpenBSD 6.2) (updated for OpenBSD 6.2)
This guide describes how to build dashd and command-line utilities on OpenBSD. This guide describes how to build dashd, dash-qt, 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.
Preparation Preparation
------------- -------------
@ -13,6 +11,7 @@ Run the following as root to install the base dependencies for building:
```bash ```bash
pkg_add git gmake libevent libtool 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 autoconf # (select highest version, e.g. 2.69)
pkg_add automake # (select highest version, e.g. 1.15) pkg_add automake # (select highest version, e.g. 1.15)
pkg_add python # (select highest version, e.g. 3.6) pkg_add python # (select highest version, e.g. 3.6)
@ -75,6 +74,14 @@ To configure without wallet:
./configure --disable-wallet --with-gui=no CC=cc CXX=c++ MAKE=gmake ./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: Build and run the tests:
```bash ```bash
gmake # use -jX here for parallelism gmake # use -jX here for parallelism

View File

@ -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, -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. // Skip leading spaces.
while (*psz && IsSpace(*psz)) while (*psz && IsSpace(*psz))
@ -141,7 +141,7 @@ std::string EncodeBase58Check(Span<const unsigned char> input)
return EncodeBase58(vch); 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) || 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)) { (vchRet.size() < 4)) {

View File

@ -25,13 +25,6 @@
*/ */
std::string EncodeBase58(Span<const unsigned char> input); 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). * Decode a base58-encoded string (str) into a byte vector (vchRet).
* return true if decoding is successful. * return true if decoding is successful.
@ -43,12 +36,6 @@ std::string EncodeBase58(Span<const unsigned char> input);
*/ */
std::string EncodeBase58Check(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 * Decode a base58-encoded string (str) that includes a checksum into a byte
* vector (vchRet), return true if decoding is successful * vector (vchRet), return true if decoding is successful

View File

@ -23,6 +23,11 @@ typedef std::map<int, uint256> MapCheckpoints;
struct CCheckpointData { struct CCheckpointData {
MapCheckpoints mapCheckpoints; MapCheckpoints mapCheckpoints;
int GetHeight() const {
const auto& final_checkpoint = mapCheckpoints.rbegin();
return final_checkpoint->first /* height */;
}
}; };
struct AssumeutxoHash : public BaseHash<uint256> { struct AssumeutxoHash : public BaseHash<uint256> {

View File

@ -11,9 +11,6 @@
#endif #endif
#ifdef WIN32 #ifdef WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#ifndef NOMINMAX #ifndef NOMINMAX
#define NOMINMAX #define NOMINMAX
#endif #endif

View File

@ -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("-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("-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("-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("-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("-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); 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);
@ -1419,6 +1419,10 @@ bool AppInitParameterInteraction(const ArgsManager& args)
nMaxTipAge = args.GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); 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 { try {
const bool fRecoveryEnabled{llmq::utils::QuorumDataRecoveryEnabled()}; const bool fRecoveryEnabled{llmq::utils::QuorumDataRecoveryEnabled()};
const bool fQuorumVvecRequestsEnabled{llmq::utils::GetEnabledQuorumVvecSyncEntries().size() > 0}; const bool fQuorumVvecRequestsEnabled{llmq::utils::GetEnabledQuorumVvecSyncEntries().size() > 0};

View File

@ -27,11 +27,6 @@
#include <cmath> #include <cmath>
#ifdef WIN32 #ifdef WIN32
#ifdef _WIN32_IE
#undef _WIN32_IE
#endif
#define _WIN32_IE 0x0501
#define WIN32_LEAN_AND_MEAN 1
#ifndef NOMINMAX #ifndef NOMINMAX
#define NOMINMAX #define NOMINMAX
#endif #endif

View File

@ -10,7 +10,6 @@
#endif #endif
#ifdef WIN32 #ifdef WIN32
#define WIN32_LEAN_AND_MEAN 1
#ifndef NOMINMAX #ifndef NOMINMAX
#define NOMINMAX #define NOMINMAX
#endif #endif

View File

@ -52,12 +52,6 @@
#pragma warning(disable:4717) #pragma warning(disable:4717)
#endif #endif
#ifdef _WIN32_IE
#undef _WIN32_IE
#endif
#define _WIN32_IE 0x0501
#define WIN32_LEAN_AND_MEAN 1
#ifndef NOMINMAX #ifndef NOMINMAX
#define NOMINMAX #define NOMINMAX
#endif #endif

View File

@ -1374,12 +1374,12 @@ void CChainState::InvalidChainFound(CBlockIndex* pindexNew)
pindexBestHeader = m_chain.Tip(); 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, pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
log(pindexNew->nChainWork.getdouble())/log(2.0), FormatISO8601DateTime(pindexNew->GetBlockTime())); log(pindexNew->nChainWork.getdouble())/log(2.0), FormatISO8601DateTime(pindexNew->GetBlockTime()));
CBlockIndex *tip = m_chain.Tip(); CBlockIndex *tip = m_chain.Tip();
assert (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), tip->GetBlockHash().ToString(), m_chain.Height(), log(tip->nChainWork.getdouble())/log(2.0),
FormatISO8601DateTime(tip->GetBlockTime())); FormatISO8601DateTime(tip->GetBlockTime()));
CheckForkWarningConditions(); CheckForkWarningConditions();
@ -1391,12 +1391,12 @@ void CChainState::ConflictingChainFound(CBlockIndex* pindexNew)
statsClient.inc("warnings.ConflictingChainFound", 1.0f); 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, pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
log(pindexNew->nChainWork.getdouble())/log(2.0), FormatISO8601DateTime(pindexNew->GetBlockTime())); log(pindexNew->nChainWork.getdouble())/log(2.0), FormatISO8601DateTime(pindexNew->GetBlockTime()));
CBlockIndex *tip = m_chain.Tip(); CBlockIndex *tip = m_chain.Tip();
assert (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), tip->GetBlockHash().ToString(), m_chain.Height(), log(tip->nChainWork.getdouble())/log(2.0),
FormatISO8601DateTime(tip->GetBlockTime())); FormatISO8601DateTime(tip->GetBlockTime()));
CheckForkWarningConditions(); CheckForkWarningConditions();
@ -2704,7 +2704,7 @@ void CChainState::UpdateTip(const CBlockIndex* pindexNew)
} }
} }
assert(std::addressof(::ChainstateActive()) == std::addressof(*this)); 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, pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion,
log(pindexNew->nChainWork.getdouble())/log(2.0), (unsigned long)pindexNew->nChainTx, log(pindexNew->nChainWork.getdouble())/log(2.0), (unsigned long)pindexNew->nChainTx,
FormatISO8601DateTime(pindexNew->GetBlockTime()), FormatISO8601DateTime(pindexNew->GetBlockTime()),

View File

@ -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_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() BOOST_AUTO_TEST_SUITE_END()

View File

@ -495,6 +495,13 @@ std::set<uint256> CWallet::GetConflicts(const uint256& txid) const
return result; 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() void CWallet::Flush()
{ {
GetDatabase().Flush(); GetDatabase().Flush();
@ -3912,9 +3919,11 @@ DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256
WalletLogPrintf("ZapSelectTx started for %d transactions...\n", vHashIn.size()); WalletLogPrintf("ZapSelectTx started for %d transactions...\n", vHashIn.size());
DBErrors nZapSelectTxRet = WalletBatch(GetDatabase()).ZapSelectTx(vHashIn, vHashOut); DBErrors nZapSelectTxRet = WalletBatch(GetDatabase()).ZapSelectTx(vHashIn, vHashOut);
for (uint256 hash : vHashOut) { for (const uint256& hash : vHashOut) {
const auto& it = mapWallet.find(hash); const auto& it = mapWallet.find(hash);
wtxOrdered.erase(it->second.m_it_wtxOrdered); wtxOrdered.erase(it->second.m_it_wtxOrdered);
for (const auto& txin : it->second.tx->vin)
mapTxSpends.erase(txin.prevout);
mapWallet.erase(it); mapWallet.erase(it);
NotifyTransactionChanged(this, hash, CT_DELETED); NotifyTransactionChanged(this, hash, CT_DELETED);
} }

View File

@ -1190,6 +1190,9 @@ public:
//! Get wallet transactions that conflict with given transaction (spend same outputs) //! Get wallet transactions that conflict with given transaction (spend same outputs)
std::set<uint256> GetConflicts(const uint256& txid) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); 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) //! Flush wallet (bitdb flush)
void Flush(); void Flush();

View File

@ -81,6 +81,11 @@ class ConfArgsTest(BitcoinTestFramework):
with open(inc_conf_file2_path, 'w', encoding='utf-8') as conf: with open(inc_conf_file2_path, 'w', encoding='utf-8') as conf:
conf.write('') # clear 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): def test_log_buffer(self):
with self.nodes[0].assert_debug_log(expected_msgs=['Warning: parsed potentially confusing double-negative -connect=0\n']): with self.nodes[0].assert_debug_log(expected_msgs=['Warning: parsed potentially confusing double-negative -connect=0\n']):
@ -124,6 +129,7 @@ class ConfArgsTest(BitcoinTestFramework):
self.test_config_file_parser() self.test_config_file_parser()
self.test_invalid_command_line_options()
# Remove the -datadir argument so it doesn't override the config file # 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")] self.nodes[0].args = [arg for arg in self.nodes[0].args if not arg.startswith("-datadir")]