Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions ci/dash/test_integrationtests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ fi

export LD_LIBRARY_PATH=$DEPENDS_DIR/$HOST/lib

if [ -n "$PREVIOUS_RELEASES_TO_DOWNLOAD" ]; then
echo "Downloading previous releases: $PREVIOUS_RELEASES_TO_DOWNLOAD"
if [ "$DOWNLOAD_PREVIOUS_RELEASES" = "true" ]; then
echo "Downloading previous releases..."
# shellcheck disable=SC2086
./test/get_previous_releases.py -b -t "$PREVIOUS_RELEASES_DIR" ${PREVIOUS_RELEASES_TO_DOWNLOAD}
./test/get_previous_releases.py -b -t "$PREVIOUS_RELEASES_DIR"
fi

cd "build-ci/dashcore-$BUILD_TARGET"
Expand Down
2 changes: 1 addition & 1 deletion ci/test/00_setup_env_native_qt5.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ export TEST_RUNNER_EXTRA="--previous-releases --coverage --extended --exclude fe
export RUN_UNIT_TESTS_SEQUENTIAL="true"
export RUN_UNIT_TESTS="false"
export GOAL="install"
export PREVIOUS_RELEASES_TO_DOWNLOAD="v0.12.1.5 v0.15.0.0 v0.16.1.1 v0.17.0.3 v18.2.2 v19.3.0 v20.1.1 v21.1.1"
export DOWNLOAD_PREVIOUS_RELEASES="true"
export BITCOIN_CONFIG="--enable-zmq --with-libs=no --enable-reduce-exports LDFLAGS=-static-libstdc++ --with-boost-process"
4 changes: 2 additions & 2 deletions ci/test/05_before_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ if [ -z "$NO_DEPENDS" ]; then
fi
CI_EXEC "$SHELL_OPTS" make "$MAKEJOBS" -C depends HOST="$HOST" "$DEP_OPTS" LOG=1
fi
if [ -n "$PREVIOUS_RELEASES_TO_DOWNLOAD" ]; then
CI_EXEC test/get_previous_releases.py -b -t "$PREVIOUS_RELEASES_DIR" "${PREVIOUS_RELEASES_TO_DOWNLOAD}"
if [ "$DOWNLOAD_PREVIOUS_RELEASES" = "true" ]; then
CI_EXEC test/get_previous_releases.py -b -t "$PREVIOUS_RELEASES_DIR"
fi
2 changes: 2 additions & 0 deletions contrib/guix/libexec/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,8 @@ mkdir -p "$DISTSRC"
# has not been run before buildling, this file will be a stub
cp "${DISTSRC}/contrib/debian/examples/dash.conf" "${DISTNAME}/"

cp -r "${DISTSRC}/share/rpcauth" "${DISTNAME}/share/"

# Finally, deterministically produce {non-,}debug binary tarballs ready
# for release
case "$HOST" in
Expand Down
5 changes: 5 additions & 0 deletions share/setup.nsi.in
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ Section -Main SEC0000
File @abs_top_builddir@/release/@BITCOIN_GUI_NAME@@EXEEXT@
File /oname=COPYING.txt @abs_top_srcdir@/COPYING
File /oname=readme.txt @abs_top_srcdir@/doc/README_windows.txt
File @abs_top_srcdir@/contrib/debian/examples/dash.conf
SetOutPath $INSTDIR\share\rpcauth
File @abs_top_srcdir@/share/rpcauth/*.*
SetOutPath $INSTDIR\daemon
File @abs_top_builddir@/release/@BITCOIN_DAEMON_NAME@@EXEEXT@
File @abs_top_builddir@/release/@BITCOIN_CLI_NAME@@EXEEXT@
Expand Down Expand Up @@ -127,6 +130,8 @@ Section /o -un.Main UNSEC0000
Delete /REBOOTOK $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@
Delete /REBOOTOK $INSTDIR\COPYING.txt
Delete /REBOOTOK $INSTDIR\readme.txt
Delete /REBOOTOK $INSTDIR\dash.conf
RMDir /r /REBOOTOK $INSTDIR\share
RMDir /r /REBOOTOK $INSTDIR\daemon
DeleteRegValue HKCU "${REGKEY}\Components" Main
SectionEnd
Expand Down
2 changes: 1 addition & 1 deletion src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ test_fuzz_fuzz_SOURCES = \
test/fuzz/locale.cpp \
test/fuzz/merkleblock.cpp \
test/fuzz/message.cpp \
test/fuzz/miniscript_decode.cpp \
test/fuzz/miniscript.cpp \
test/fuzz/minisketch.cpp \
test/fuzz/muhash.cpp \
test/fuzz/multiplication_overflow.cpp \
Expand Down
1 change: 1 addition & 0 deletions src/key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ ECDHSecret CKey::ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift, c
}

bool CExtKey::Derive(CExtKey &out, unsigned int _nChild) const {
if (nDepth == std::numeric_limits<unsigned char>::max()) return false;
out.nDepth = nDepth + 1;
CKeyID id = key.GetPubKey().GetID();
memcpy(out.vchFingerprint, &id, 4);
Expand Down
4 changes: 2 additions & 2 deletions src/key.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class CKey
bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const;

//! Derive BIP32 child key.
bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
[[nodiscard]] bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;

/**
* Verify thoroughly whether a private key and a public key match.
Expand Down Expand Up @@ -186,7 +186,7 @@ struct CExtKey {

void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
bool Derive(CExtKey& out, unsigned int nChild) const;
[[nodiscard]] bool Derive(CExtKey& out, unsigned int nChild) const;
CExtPubKey Neuter() const;
void SetSeed(Span<const std::byte> seed);
};
Expand Down
2 changes: 1 addition & 1 deletion src/outputtype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
static const std::string OUTPUT_TYPE_STRING_LEGACY = "legacy";
static const std::string OUTPUT_TYPE_STRING_UNKNOWN = "unknown";

const std::array<OutputType, 2> OUTPUT_TYPES = {OutputType::LEGACY, OutputType::UNKNOWN};
const std::array<OutputType, 1> OUTPUT_TYPES = {OutputType::LEGACY};

bool ParseOutputType(const std::string& type, OutputType& output_type)
{
Expand Down
2 changes: 1 addition & 1 deletion src/outputtype.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ enum class OutputType {
UNKNOWN,
};

extern const std::array<OutputType, 2> OUTPUT_TYPES;
extern const std::array<OutputType, 1> OUTPUT_TYPES;

[[nodiscard]] bool ParseOutputType(const std::string& str, OutputType& output_type);
const std::string& FormatOutputType(OutputType type);
Expand Down
1 change: 1 addition & 0 deletions src/pubkey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ void CExtPubKey::DecodeWithVersion(const unsigned char code[BIP32_EXTKEY_WITH_VE
}

bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const {
if (nDepth == std::numeric_limits<unsigned char>::max()) return false;
out.nDepth = nDepth + 1;
CKeyID id = pubkey.GetID();
memcpy(out.vchFingerprint, &id, 4);
Expand Down
4 changes: 2 additions & 2 deletions src/pubkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ class CPubKey
bool Decompress();

//! Derive BIP32 child pubkey.
bool Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
[[nodiscard]] bool Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
};

/** An ElligatorSwift-encoded public key. */
Expand Down Expand Up @@ -281,7 +281,7 @@ struct CExtPubKey {
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
void EncodeWithVersion(unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE]) const;
void DecodeWithVersion(const unsigned char code[BIP32_EXTKEY_WITH_VERSION_SIZE]);
bool Derive(CExtPubKey& out, unsigned int nChild) const;
[[nodiscard]] bool Derive(CExtPubKey& out, unsigned int nChild) const;

void Serialize(CSizeComputer& s) const
{
Expand Down
44 changes: 13 additions & 31 deletions src/rest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -620,51 +620,34 @@ static bool rest_chaininfo(const CoreContext& context, HTTPRequest* req, const s
}
}

static bool rest_mempool_info(const CoreContext& context, HTTPRequest* req, const std::string& strURIPart)
static bool rest_mempool(const CoreContext& context, HTTPRequest* req, const std::string& str_uri_part)
{
if (!CheckWarmup(req))
return false;
const CTxMemPool* mempool = GetMemPool(context, req);
if (!mempool) return false;
std::string param;
const RESTResponseFormat rf = ParseDataFormat(param, strURIPart);

switch (rf) {
case RESTResponseFormat::JSON: {
const LLMQContext* llmq_ctx = GetLLMQContext(context, req);
if (!llmq_ctx) return false;

UniValue mempoolInfoObject = MempoolInfoToJSON(*mempool, *llmq_ctx->isman);

std::string strJSON = mempoolInfoObject.write() + "\n";
req->WriteHeader("Content-Type", "application/json");
req->WriteReply(HTTP_OK, strJSON);
return true;
}
default: {
return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");
}
std::string param;
const RESTResponseFormat rf = ParseDataFormat(param, str_uri_part);
if (param != "contents" && param != "info") {
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid URI format. Expected /rest/mempool/<info|contents>.json");
}
Comment on lines +630 to 632
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: URI validation logic should verify format includes the .json extension, not just the path component. Current check allows /rest/mempool/info without format suffix, which ParseDataFormat would return as RESTResponseFormat::UNDEF. Should this endpoint require an explicit format suffix like .json, or is the format suffix optional (defaulting to UNDEF)?

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/rest.cpp
Line: 630:632

Comment:
**logic:** URI validation logic should verify format includes the `.json` extension, not just the path component. Current check allows `/rest/mempool/info` without format suffix, which ParseDataFormat would return as RESTResponseFormat::UNDEF. Should this endpoint require an explicit format suffix like `.json`, or is the format suffix optional (defaulting to UNDEF)?

How can I resolve this? If you propose a fix, please make it concise.

}

static bool rest_mempool_contents(const CoreContext& context, HTTPRequest* req, const std::string& strURIPart)
{
if (!CheckWarmup(req)) return false;
const CTxMemPool* mempool = GetMemPool(context, req);
if (!mempool) return false;
std::string param;
const RESTResponseFormat rf = ParseDataFormat(param, strURIPart);

switch (rf) {
case RESTResponseFormat::JSON: {
const LLMQContext* llmq_ctx = GetLLMQContext(context, req);
if (!llmq_ctx) return false;

UniValue mempoolObject = MempoolToJSON(*mempool, llmq_ctx->isman.get(), true);
std::string str_json;
if (param == "contents") {
str_json = MempoolToJSON(*mempool, llmq_ctx->isman.get(), true).write() + "\n";
} else {
str_json = MempoolInfoToJSON(*mempool, *llmq_ctx->isman).write() + "\n";
}

std::string strJSON = mempoolObject.write() + "\n";
req->WriteHeader("Content-Type", "application/json");
req->WriteReply(HTTP_OK, strJSON);
req->WriteReply(HTTP_OK, str_json);
return true;
}
default: {
Expand Down Expand Up @@ -982,8 +965,7 @@ static const struct {
{"/rest/blockfilter/", rest_block_filter},
{"/rest/blockfilterheaders/", rest_filter_header},
{"/rest/chaininfo", rest_chaininfo},
{"/rest/mempool/info", rest_mempool_info},
{"/rest/mempool/contents", rest_mempool_contents},
{"/rest/mempool/", rest_mempool},
{"/rest/headers/", rest_headers},
{"/rest/getutxos", rest_getutxos},
{"/rest/blockhashbyheight/", rest_blockhash_by_height},
Expand Down
8 changes: 4 additions & 4 deletions src/rpc/output_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ static RPCHelpMan validateaddress()
RPCResult::Type::OBJ, "", "",
{
{RPCResult::Type::BOOL, "isvalid", "If the address is valid or not"},
{RPCResult::Type::STR, "address", /* optional */ true, "The Dash address validated"},
{RPCResult::Type::STR_HEX, "scriptPubKey", /* optional */ true, "The hex-encoded scriptPubKey generated by the address"},
{RPCResult::Type::BOOL, "isscript", /* optional */ true, "If the key is a script"},
{RPCResult::Type::STR, "error", /* optional */ true, "Error message, if any"},
{RPCResult::Type::STR, "address", /*optional=*/true, "The Dash address validated"},
{RPCResult::Type::STR_HEX, "scriptPubKey", /*optional=*/true, "The hex-encoded scriptPubKey generated by the address"},
{RPCResult::Type::BOOL, "isscript", /*optional=*/true, "If the key is a script"},
{RPCResult::Type::STR, "error", /*optional=*/true, "Error message, if any"},
}
},
RPCExamples{
Expand Down
11 changes: 5 additions & 6 deletions src/script/descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ class BIP32PubkeyProvider final : public PubkeyProvider
{
if (!GetExtKey(arg, xprv)) return false;
for (auto entry : m_path) {
xprv.Derive(xprv, entry);
if (!xprv.Derive(xprv, entry)) return false;
if (entry >> 31) {
last_hardened = xprv;
}
Expand Down Expand Up @@ -364,14 +364,13 @@ class BIP32PubkeyProvider final : public PubkeyProvider
}
} else {
for (auto entry : m_path) {
der = parent_extkey.Derive(parent_extkey, entry);
assert(der);
if (!parent_extkey.Derive(parent_extkey, entry)) return false;
}
final_extkey = parent_extkey;
if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
assert(m_derive != DeriveType::HARDENED);
}
assert(der);
if (!der) return false;

final_info_out = final_info_out_tmp;
key_out = final_extkey.pubkey;
Expand Down Expand Up @@ -474,8 +473,8 @@ class BIP32PubkeyProvider final : public PubkeyProvider
CExtKey extkey;
CExtKey dummy;
if (!GetDerivedExtKey(arg, extkey, dummy)) return false;
if (m_derive == DeriveType::UNHARDENED) extkey.Derive(extkey, pos);
if (m_derive == DeriveType::HARDENED) extkey.Derive(extkey, pos | 0x80000000UL);
if (m_derive == DeriveType::UNHARDENED && !extkey.Derive(extkey, pos)) return false;
if (m_derive == DeriveType::HARDENED && !extkey.Derive(extkey, pos | 0x80000000UL)) return false;
key = extkey.key;
return true;
}
Expand Down
Loading
Loading