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#17946, #18663, #18946, #18975, #19004, #19115, #19152, #19173, partial #18735 #5802

Merged
merged 9 commits into from
Jan 9, 2024
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ The `master` branch is meant to be stable. Development is normally done in separ
[Tags](https://github.com/dashpay/dash/tags) are created to indicate new official,
stable release versions of Dash Core.

The `develop` branch is regularly built (see doc/build-*.md for instructions) and tested, but is not guaranteed to be
completely stable.

The contribution workflow is described in [CONTRIBUTING.md](CONTRIBUTING.md)
and useful hints for developers can be found in [doc/developer-notes.md](doc/developer-notes.md).

Expand Down
6 changes: 4 additions & 2 deletions ci/test/00_setup_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8

# The root dir.
# The ci system copies this folder.
# This is where the build is done (depends and dist).
# This is where the depends build is done.
BASE_ROOT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../../ >/dev/null 2>&1 && pwd )
export BASE_ROOT_DIR

Expand Down Expand Up @@ -59,8 +59,10 @@ export CCACHE_DIR=${CCACHE_DIR:-$CACHE_DIR/ccache}
# The depends dir.
# This folder exists on the ci host and ci guest. Changes are propagated back and forth.
export DEPENDS_DIR=${DEPENDS_DIR:-$BASE_ROOT_DIR/depends}
# Folder where the build is done (bin and lib).
# Folder where the build result is put (bin and lib).
export BASE_OUTDIR=${BASE_OUTDIR:-$BASE_SCRATCH_DIR/out/$HOST}
# Folder where the build is done (dist and out-of-tree build).
export BASE_BUILD_DIR=${BASE_BUILD_DIR:-$BASE_SCRATCH_DIR/build-ci}
export PREVIOUS_RELEASES_DIR=${PREVIOUS_RELEASES_DIR:-$BASE_ROOT_DIR/releases/$HOST}
export SDK_URL=${SDK_URL:-https://bitcoincore.org/depends-sources/sdks}
export DOCKER_PACKAGES=${DOCKER_PACKAGES:-build-essential libtool autotools-dev automake pkg-config bsdmainutils curl ca-certificates ccache python3 rsync git procps}
Expand Down
2 changes: 1 addition & 1 deletion ci/test/04_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ if [ "$TRAVIS_OS_NAME" == "osx" ]; then
${CI_RETRY_EXE} pip3 install $PIP_PACKAGES
fi

mkdir -p "${BASE_SCRATCH_DIR}"
# Create folders that are mounted into the docker
mkdir -p "${CCACHE_DIR}"
mkdir -p "${PREVIOUS_RELEASES_DIR}"

Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1871,7 +1871,7 @@ echo " gprof enabled = $enable_gprof"
echo " werror = $enable_werror"
echo
echo " target os = $TARGET_OS"
echo " build os = $BUILD_OS"
echo " build os = $build_os"
echo
echo " CC = $CC"
echo " CFLAGS = $PTHREAD_CFLAGS $CFLAGS"
Expand Down
8 changes: 4 additions & 4 deletions doc/fuzzing.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ To quickly get started fuzzing Dash Core using [libFuzzer](https://llvm.org/docs
$ git clone https://github.com/dashpay/dash
$ cd dash/
$ ./autogen.sh
$ CC=clang CXX=clang++ ./configure --enable-fuzz --with-sanitizers=address,fuzzer,undefined --enable-c++17
$ CC=clang CXX=clang++ ./configure --enable-fuzz --with-sanitizers=address,fuzzer,undefined
# macOS users: If you have problem with this step then make sure to read "macOS hints for
# libFuzzer" on https://github.com/dashpay/dash/blob/develop/doc/fuzzing.md#macos-hints-for-libfuzzer
$ make
Expand Down Expand Up @@ -123,7 +123,7 @@ You may also need to take care of giving the correct path for `clang` and
Full configure that was tested on macOS Catalina with `brew` installed `llvm`:

```sh
./configure --enable-fuzz --with-sanitizers=fuzzer,address,undefined CC=/usr/local/opt/llvm/bin/clang CXX=/usr/local/opt/llvm/bin/clang++ --disable-asm --enable-c++17
./configure --enable-fuzz --with-sanitizers=fuzzer,address,undefined CC=/usr/local/opt/llvm/bin/clang CXX=/usr/local/opt/llvm/bin/clang++ --disable-asm
```

Read the [libFuzzer documentation](https://llvm.org/docs/LibFuzzer.html) for more information. This [libFuzzer tutorial](https://github.com/google/fuzzing/blob/master/tutorial/libFuzzerTutorial.md) might also be of interest.
Expand All @@ -142,7 +142,7 @@ $ make -C AFLplusplus/ source-only
$ ./autogen.sh
# If afl-clang-lto is not available, see
# https://github.com/AFLplusplus/AFLplusplus#a-selecting-the-best-afl-compiler-for-instrumenting-the-target
$ CC=$(pwd)/AFLplusplus/afl-clang-lto CXX=$(pwd)/AFLplusplus/afl-clang-lto++ ./configure --enable-fuzz --enable-c++17
$ CC=$(pwd)/AFLplusplus/afl-clang-lto CXX=$(pwd)/AFLplusplus/afl-clang-lto++ ./configure --enable-fuzz
$ make
# For macOS you may need to ignore x86 compilation checks when running "make". If so,
# try compiling using: AFL_NO_X86=1 make
Expand All @@ -169,7 +169,7 @@ $ git clone https://github.com/google/honggfuzz
$ cd honggfuzz/
$ make
$ cd ..
$ CC=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang CXX=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang++ ./configure --enable-fuzz --with-sanitizers=address,undefined --enable-c++17
$ CC=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang CXX=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang++ ./configure --enable-fuzz --with-sanitizers=address,undefined
$ make
$ mkdir -p inputs/
$ FUZZ=process_message honggfuzz/honggfuzz -i inputs/ -- src/test/fuzz/fuzz
Expand Down
8 changes: 8 additions & 0 deletions doc/release-notes-bitcoin-17219.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Wallet
------


- The wallet can create a transaction without change even when the keypool is
empty. Previously it failed. (#17219)


3 changes: 2 additions & 1 deletion src/bitcoin-cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <memory>
#include <optional>
#include <stdio.h>
#include <string>
#include <tuple>

#include <event2/buffer.h>
Expand Down Expand Up @@ -172,7 +173,7 @@ struct HTTPReply
std::string body;
};

static const char *http_errorstring(int code)
static std::string http_errorstring(int code)
{
switch(code) {
#if LIBEVENT_VERSION_NUMBER >= 0x02010300
Expand Down
6 changes: 3 additions & 3 deletions src/core_read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <version.h>

#include <algorithm>
#include <string>

namespace {

Expand All @@ -31,10 +32,9 @@ opcodetype ParseOpCode(const std::string& s)
if (op < OP_NOP && op != OP_RESERVED)
continue;

const char* name = GetOpName(static_cast<opcodetype>(op));
if (strcmp(name, "OP_UNKNOWN") == 0)
std::string strName = GetOpName(static_cast<opcodetype>(op));
if (strName == "OP_UNKNOWN")
continue;
std::string strName(name);
mapOpNames[strName] = static_cast<opcodetype>(op);
// Convenience: OP_ADD and just ADD are both recognized:
if (strName.compare(0, 3, "OP_") == 0) { // strName starts with "OP_"
Expand Down
1 change: 1 addition & 0 deletions src/rpc/mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
result.pushKV("capabilities", aCaps);

UniValue aRules(UniValue::VARR);
aRules.push_back("csv");
UdjinM6 marked this conversation as resolved.
Show resolved Hide resolved
UniValue vbavailable(UniValue::VOBJ);
for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
Consensus::DeploymentPos pos = Consensus::DeploymentPos(j);
Expand Down
4 changes: 3 additions & 1 deletion src/script/script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
#include <script/script.h>
#include <util/strencodings.h>

const char* GetOpName(opcodetype opcode)
#include <string>

std::string GetOpName(opcodetype opcode)
{
switch (opcode)
{
Expand Down
2 changes: 1 addition & 1 deletion src/script/script.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ enum opcodetype
// Maximum value that an opcode can be
static const unsigned int MAX_OPCODE = OP_CHECKDATASIGVERIFY;

const char* GetOpName(opcodetype opcode);
std::string GetOpName(opcodetype opcode);

class scriptnum_error : public std::runtime_error
{
Expand Down
4 changes: 3 additions & 1 deletion src/script/script_error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

#include <script/script_error.h>

const char* ScriptErrorString(const ScriptError serror)
#include <string>

std::string ScriptErrorString(const ScriptError serror)
{
switch (serror)
{
Expand Down
4 changes: 3 additions & 1 deletion src/script/script_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#ifndef BITCOIN_SCRIPT_SCRIPT_ERROR_H
#define BITCOIN_SCRIPT_SCRIPT_ERROR_H

#include <string>

typedef enum ScriptError_t
{
SCRIPT_ERR_OK = 0,
Expand Down Expand Up @@ -73,6 +75,6 @@ typedef enum ScriptError_t

#define SCRIPT_ERR_LAST SCRIPT_ERR_ERROR_COUNT

const char* ScriptErrorString(const ScriptError error);
std::string ScriptErrorString(const ScriptError error);

#endif // BITCOIN_SCRIPT_SCRIPT_ERROR_H
6 changes: 4 additions & 2 deletions src/script/standard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <pubkey.h>
#include <script/script.h>

#include <string>

typedef std::vector<unsigned char> valtype;

bool fAcceptDatacarrier = DEFAULT_ACCEPT_DATACARRIER;
Expand All @@ -27,7 +29,7 @@ CKeyID ToKeyID(const PKHash& key_hash)
return CKeyID{static_cast<uint160>(key_hash)};
}

const char* GetTxnOutputType(TxoutType t)
std::string GetTxnOutputType(TxoutType t)
{
switch (t)
{
Expand All @@ -38,7 +40,7 @@ const char* GetTxnOutputType(TxoutType t)
case TxoutType::MULTISIG: return "multisig";
case TxoutType::NULL_DATA: return "nulldata";
} // no default case, so the compiler can warn about missing cases
return nullptr;
assert(false);
}

static bool MatchPayToPubkey(const CScript& script, valtype& pubkey)
Expand Down
4 changes: 3 additions & 1 deletion src/script/standard.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <util/hash_type.h>

#include <variant>
#include <string>


static const bool DEFAULT_ACCEPT_DATACARRIER = true;

Expand Down Expand Up @@ -103,7 +105,7 @@ using CTxDestination = std::variant<CNoDestination, PKHash, ScriptHash>;
bool IsValidDestination(const CTxDestination& dest);

/** Get the name of a TxoutType as a C string, or nullptr if unknown. */
const char* GetTxnOutputType(TxoutType t);
std::string GetTxnOutputType(TxoutType t);

/**
* Parse a scriptPubKey and identify script type for standard scripts. If
Expand Down
4 changes: 2 additions & 2 deletions src/test/script_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ static ScriptErrorDesc script_errors[]={
{SCRIPT_ERR_SIG_FINDANDDELETE, "SIG_FINDANDDELETE"},
};

static const char *FormatScriptError(ScriptError_t err)
static std::string FormatScriptError(ScriptError_t err)
{
for (const auto& script_error : script_errors) {
if (script_error.err == err) {
Expand Down Expand Up @@ -132,7 +132,7 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, uint32_t flag
CMutableTransaction tx = BuildSpendingTransaction(scriptSig, txCredit);
CMutableTransaction tx2 = tx;
BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue), &err) == expect, message);
BOOST_CHECK_MESSAGE(err == scriptError, std::string(FormatScriptError(err)) + " where " + std::string(FormatScriptError((ScriptError_t)scriptError)) + " expected: " + message);
BOOST_CHECK_MESSAGE(err == scriptError, FormatScriptError(err) + " where " + FormatScriptError((ScriptError_t)scriptError) + " expected: " + message);

// Verify that removing flags from a passing test or adding flags to a failing test does not change the result.
for (int i = 0; i < 16; ++i) {
Expand Down
2 changes: 1 addition & 1 deletion src/test/validationinterface_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ BOOST_AUTO_TEST_CASE(unregister_validation_interface_race)
// Start thread to generate notifications
std::thread gen{[&] {
const CBlock block_dummy;
const BlockValidationState state_dummy;
BlockValidationState state_dummy;
while (generate) {
GetMainSignals().BlockChecked(block_dummy, state_dummy);
}
Expand Down
34 changes: 17 additions & 17 deletions src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1583,15 +1583,15 @@ static UniValue listsinceblock(const JSONRPCRequest& request)
},
}.Check(request);

std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
if (!wallet) return NullUniValue;
const CWallet* const pwallet = wallet.get();
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
if (!pwallet) return NullUniValue;

const CWallet& wallet = *pwallet;
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
pwallet->BlockUntilSyncedToCurrentChain();
wallet.BlockUntilSyncedToCurrentChain();

LOCK(pwallet->cs_wallet);
LOCK(wallet.cs_wallet);

std::optional<int> height; // Height of the specified block or the common ancestor, if the block provided was in a deactivated chain.
std::optional<int> altheight; // Height of the specified block, even if it's in a deactivated chain.
Expand All @@ -1601,9 +1601,9 @@ static UniValue listsinceblock(const JSONRPCRequest& request)
uint256 blockId;
if (!request.params[0].isNull() && !request.params[0].get_str().empty()) {
blockId = ParseHashV(request.params[0], "blockhash");
height.emplace();
altheight.emplace();
if (!pwallet->chain().findCommonAncestor(blockId, pwallet->GetLastBlockHash(), /* ancestor out */ FoundBlock().height(*height), /* blockId out */ FoundBlock().height(*altheight))) {
height = int{};
altheight = int{};
if (!wallet.chain().findCommonAncestor(blockId, wallet.GetLastBlockHash(), /* ancestor out */ FoundBlock().height(*height), /* blockId out */ FoundBlock().height(*altheight))) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
}
Expand All @@ -1616,21 +1616,21 @@ static UniValue listsinceblock(const JSONRPCRequest& request)
}
}

if (ParseIncludeWatchonly(request.params[2], *pwallet)) {
if (ParseIncludeWatchonly(request.params[2], wallet)) {
filter |= ISMINE_WATCH_ONLY;
}

bool include_removed = (request.params[3].isNull() || request.params[3].get_bool());

int depth = height ? pwallet->GetLastBlockHeight() + 1 - *height : -1;
int depth = height ? wallet.GetLastBlockHeight() + 1 - *height : -1;

UniValue transactions(UniValue::VARR);

for (const std::pair<const uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
for (const std::pair<const uint256, CWalletTx>& pairWtx : wallet.mapWallet) {
const CWalletTx& tx = pairWtx.second;

if (depth == -1 || abs(tx.GetDepthInMainChain()) < depth) {
ListTransactions(pwallet, tx, 0, true, transactions, filter, nullptr /* filter_label */);
ListTransactions(&wallet, tx, 0, true, transactions, filter, nullptr /* filter_label */);
}
}

Expand All @@ -1639,23 +1639,23 @@ static UniValue listsinceblock(const JSONRPCRequest& request)
UniValue removed(UniValue::VARR);
while (include_removed && altheight && *altheight > *height) {
CBlock block;
if (!pwallet->chain().findBlock(blockId, FoundBlock().data(block)) || block.IsNull()) {
if (!wallet.chain().findBlock(blockId, FoundBlock().data(block)) || block.IsNull()) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
}
for (const CTransactionRef& tx : block.vtx) {
auto it = pwallet->mapWallet.find(tx->GetHash());
if (it != pwallet->mapWallet.end()) {
auto it = wallet.mapWallet.find(tx->GetHash());
if (it != wallet.mapWallet.end()) {
// We want all transactions regardless of confirmation count to appear here,
// even negative confirmation ones, hence the big negative.
ListTransactions(pwallet, it->second, -100000000, true, removed, filter, nullptr /* filter_label */);
ListTransactions(&wallet, it->second, -100000000, true, removed, filter, nullptr /* filter_label */);
}
}
blockId = block.hashPrevBlock;
--*altheight;
}

uint256 lastblock;
CHECK_NONFATAL(pwallet->chain().findAncestorByHeight(pwallet->GetLastBlockHash(), pwallet->GetLastBlockHeight() + 1 - target_confirms, FoundBlock().hash(lastblock)));
CHECK_NONFATAL(wallet.chain().findAncestorByHeight(wallet.GetLastBlockHash(), wallet.GetLastBlockHeight() + 1 - target_confirms, FoundBlock().hash(lastblock)));

UniValue ret(UniValue::VOBJ);
ret.pushKV("transactions", transactions);
Expand Down
Loading