mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 20:12:57 +01:00
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:
commit
a78c28d572
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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)) {
|
||||||
|
13
src/base58.h
13
src/base58.h
@ -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
|
||||||
|
@ -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> {
|
||||||
|
@ -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
|
||||||
|
@ -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};
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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()),
|
||||||
|
@ -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()
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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")]
|
||||||
|
Loading…
Reference in New Issue
Block a user