diff --git a/contrib/merge-prs.sh b/contrib/merge-prs.sh index 67e390b807..1c1c9e96e2 100755 --- a/contrib/merge-prs.sh +++ b/contrib/merge-prs.sh @@ -3,38 +3,58 @@ export LC_ALL=C set -eo pipefail +# Setup base branch and Bitcoin/Elements remote names. BASE_ORIG=merged-master BASE="${BASE_ORIG}" BITCOIN_UPSTREAM_REMOTE=bitcoin -BITCOIN_UPSTREAM="${BITCOIN_UPSTREAM_REMOTE}/master" -# ELEMENTS_UPSTREAM_REMOTE=upstream -# ELEMENTS_UPSTREAM="${ELEMENTS_UPSTREAM_REMOTE}/master" +export BITCOIN_UPSTREAM="${BITCOIN_UPSTREAM_REMOTE}/master" +ELEMENTS_UPSTREAM_REMOTE=upstream +export ELEMENTS_UPSTREAM="${ELEMENTS_UPSTREAM_REMOTE}/master" +# START USER CONFIG: +# Set your target upstream here +TARGET_UPSTREAM=$BITCOIN_UPSTREAM +TARGET_NAME="Bitcoin" +PR_PREFIX="bitcoin/bitcoin" +# TARGET_UPSTREAM=$ELEMENTS_UPSTREAM +# TARGET_NAME="Elements" +# PR_PREFIX="ElementsProject/elements" + +# Set your git worktree location here. This is where the merges will be done, and where you should checkout the merged-master branch. +WORKTREE="/home/byron/code/elements-worktree" + +# Set your parallellism during build/test. You probably want as many cores as possible. +# Parallel functional tests can somewhat exceed your core count, depends on the build machine CPU/RAM. +PARALLEL_BUILD=23 # passed to make -j +PARALLEL_TEST=46 # passed to test_runner.py --jobs +PARALLEL_FUZZ=12 # passed to test_runner.py -j when fuzzing + +# Setup a ccache dir if necessary. +#export CCACHE_DIR="/tmp/ccache" +#export CCACHE_MAXSIZE="20G" + +# Set and export a WEBHOOK environment variable to a Discord webhook URL outside of this script to get notifications of progress and failures. + +# We don't currently fuzz during merging. Check fuzzing and CI after a merge run. # Replace this with the location where we should put the fuzz test corpus -BITCOIN_QA_ASSETS="${HOME}/.tmp/bitcoin/qa-assets" -FUZZ_CORPUS="${BITCOIN_QA_ASSETS}/fuzz_seed_corpus/" -mkdir -p "$(dirname "${BITCOIN_QA_ASSETS}")" +# BITCOIN_QA_ASSETS="${HOME}/code/bitcoin/qa-assets" +# FUZZ_CORPUS="${BITCOIN_QA_ASSETS}/fuzz_seed_corpus/" -# BEWARE: On some systems /tmp/ gets periodically cleaned, which may cause -# random files from this directory to disappear based on timestamp, and -# make git very confused -WORKTREE="${HOME}/.tmp/elements-merge-worktree" -mkdir -p "${HOME}/.tmp" - -# These should be tuned to your machine; below values are for an 8-core -# 16-thread macbook pro -PARALLEL_BUILD=4 # passed to make -j -PARALLEL_TEST=12 # passed to test_runner.py --jobs -PARALLEL_FUZZ=8 # passed to test_runner.py -j when fuzzing +# END USER CONFIG +# Script SKIP_MERGE=0 DO_BUILD=1 KEEP_GOING=1 +DO_TEST=1 +DO_FUZZ=0 +NUM=15 +COUNT=0 if [[ "$1" == "setup" ]]; then echo "Setting up..." echo - git config remote.upstream.url >/dev/null || remote add upstream "https://github.com/ElementsProject/elements.git" + git config remote.upstream.url >/dev/null || git remote add upstream "https://github.com/ElementsProject/elements.git" git config remote.bitcoin.url >/dev/null || git remote add bitcoin "https://github.com/bitcoin/bitcoin.git" if git worktree list --porcelain | grep --silent prunable; then echo "You have stale git worktrees, please either fix them or run 'git worktree prune'." @@ -45,14 +65,7 @@ if [[ "$1" == "setup" ]]; then echo "Fetching all remotes..." echo git fetch --all - echo - #echo "Cloning fuzz test corpus..." - #echo - #if [[ ! -d "${BITCOIN_QA_ASSETS}" ]]; then - # cd "$(dirname ${BITCOIN_QA_ASSETS})" && git clone https://github.com/bitcoin-core/qa-assets.git - #fi - #echo - echo "Done! Remember to also check out merged-master, and push it back up when finished." + echo "Done! Remember to also checkout merged-master at ${WORKTREE}" exit 0 elif [[ "$1" == "continue" ]]; then SKIP_MERGE=1 @@ -62,17 +75,35 @@ elif [[ "$1" == "list-only" ]]; then DO_BUILD=0 elif [[ "$1" == "step" ]]; then KEEP_GOING=0 +elif [[ "$1" == "merge-only" ]]; then + SKIP_MERGE=0 + KEEP_GOING=0 + DO_BUILD=0 + DO_TEST=0 elif [[ "$1" == "step-continue" ]]; then SKIP_MERGE=1 KEEP_GOING=0 +elif [[ "$1" == "step-test" ]]; then + SKIP_MERGE=1 + KEEP_GOING=0 + DO_BUILD=0 +elif [[ "$1" == "step-fuzz" ]]; then + SKIP_MERGE=1 + KEEP_GOING=0 + DO_BUILD=0 + DO_TEST=0 +elif [[ "$1" == "analyze" ]]; then + DO_BUILD=0 + DO_TEST=0 else - echo "Usage: $0 " + echo "Usage: $0 " echo " setup will configure your repository for the first run of this script" echo " list-only will simply list all the PRs yet to be done" echo " go will try to merge every PR, building/testing each" echo " continue assumes the first git-merge has already happened, and starts with building" echo " step will try to merge/build/test a single PR" echo " step-continue assumes the first git-merge has already happened, and will try to build/test a single PR" + echo " analyze will analyze the next $NUM PRs and count conflicts NB: DO NOT CTRL+C THIS PROCESS" echo echo "Prior to use, please create a git worktree for the elements repo at:" echo " $WORKTREE" @@ -101,54 +132,95 @@ if [[ "$SKIP_MERGE" == "1" ]]; then fi ## Get full list of merges -# for elements -# COMMITS=$(git -C "$WORKTREE" log "$ELEMENTS_UPSTREAM" --not $BASE --merges --first-parent --pretty='format:%ct %cI %h Elements %s') -# for bitcoin -COMMITS=$(git -C "$WORKTREE" log "$BITCOIN_UPSTREAM" --not $BASE --merges --first-parent --pretty='format:%ct %cI %h Bitcoin %s') +COMMITS=$(git -C "$WORKTREE" log "$TARGET_UPSTREAM" --not $BASE --merges --first-parent --pretty="format:%ct %cI %h $TARGET_NAME %s") -cd "$WORKTREE" +cd "$WORKTREE" || exit 1 VERBOSE=1 +echo start > merge.log + quietly () { if [[ "$VERBOSE" == "1" ]]; then - "$@" + date | tee --append merge.log + time "$@" 2>&1 | tee --append merge.log else chronic "$@" fi } +notify () { + local MESSAGE="$1" + local JSON="{\"content\": \"$MESSAGE\"}" + if [ -n "$WEBHOOK" ]; then + curl -d "$JSON" -H "Content-Type: application/json" "$WEBHOOK" + else + echo "$MESSAGE" + fi + if [[ "$2" == "1" ]]; then + exit 1 + fi +} + ## Sort by unix timestamp and iterate over them -#echo "$ELT_COMMITS" "$BTC_COMMITS" | sort -n -k1 | while read line echo "$COMMITS" | tac | while read -r line do - echo - echo "=-=-=-=-=-=-=-=-=-=-=" - echo - - echo -e "$line" ## Extract data and output what we're doing - DATE=$(echo "$line" | cut -d ' ' -f 2) HASH=$(echo "$line" | cut -d ' ' -f 3) CHAIN=$(echo "$line" | cut -d ' ' -f 4) - PR_ID=$(echo "$line" | cut -d ' ' -f 6 | tr -d :) - PR_ID_ALT=$(echo "$line" | cut -d ' ' -f 8 | tr -d :) + PR_ID=$(echo "$line" | grep -o -P "#\d+") - if [[ "$PR_ID" == "pull" ]]; then - PR_ID="${PR_ID_ALT}" - fi - echo -e "$CHAIN PR \e[37m$PR_ID \e[33m$HASH\e[0m on \e[32m$DATE\e[0m " + GIT_HEAD=$(git rev-parse HEAD) ## Do it if [[ "$1" == "list-only" ]]; then + echo -e "$line" continue fi + if [[ "$1" == "analyze" ]]; then + COUNT=$((COUNT + 1)) + # todo: count conflicts in critical files + # CRITICAL_FILES=("src/wallet/spend.h", "src/wallet/spend.cpp") + MERGE_FILE="/tmp/$HASH.merge" + DIFF_FILE="/tmp/$HASH.diff" + git -C "$WORKTREE" merge "$HASH" --no-ff -m "Merge $HASH into merged_master ($CHAIN PR $PR_PREFIX$PR_ID)" > "$MERGE_FILE" || true + git -C "$WORKTREE" diff > "$DIFF_FILE" + git -C "$WORKTREE" reset --hard "$GIT_HEAD" > /dev/null + # FILES=$(grep "CONFLICT" "$MERGE_FILE") + NUM_FILES=$(grep -c "CONFLICT" "$MERGE_FILE") + NUM_CONFLICTS=$(grep -c "<<<<<<<" "$DIFF_FILE") + echo "$COUNT. Merge up to $PR_ID ($HASH) has $NUM_CONFLICTS conflicts in $NUM_FILES files." + if [[ "$COUNT" == "$NUM" ]]; then + exit 0 + else + continue + fi + fi + notify "starting merge of $PR_ID" + + # check for stoppers and halt if found + # a stopper is normally the PR after the version has been changed + # ie. the branch point we want to stop at for this version + STOPPERS=( + "#30716" # bitcoin v28 + "#32041" # bitcoin v29 + ) + for STOPPER in "${STOPPERS[@]}" + do + if [[ "$PR_ID" == *"$STOPPER"* ]]; then + echo "Found $STOPPER in $PR_ID! Exiting." + notify "hit stopper, exiting" + exit 1 + else + echo "Didn't find $STOPPER in $PR_ID. Continuing." + fi + done if [[ "$SKIP_MERGE" == "1" ]]; then echo -e "Continuing build of \e[37m$PR_ID\e[0m at $(date)" else echo -e "Start merge/build of \e[37m$PR_ID\e[0m at $(date)" - git -C "$WORKTREE" merge "$HASH" --no-ff -m "Merge $HASH into merged_master ($CHAIN PR $PR_ID)" + git -C "$WORKTREE" merge "$HASH" --no-ff -m "Merge $HASH into merged_master ($CHAIN PR $PR_PREFIX$PR_ID)" || notify "fail merge" 1 fi # FIXME: ELEMENTS, move make building process into CMake one? @@ -164,35 +236,43 @@ do # The following is an expansion of `make check` that skips the libsecp # tests and also the benchmarks (though it does build them!) echo "Building" - quietly make -j"$PARALLEL_BUILD" -k -# quietly make -j1 check - echo "Linting" - quietly ./ci/lint/06_script.sh + quietly make -j"$PARALLEL_BUILD" -k || notify "fail build" 1 + # todo: fix linting step + # echo "Linting" + # quietly ./ci/lint/06_script.sh || notify "fail lint" + fi + + if [[ "$DO_TEST" == "1" ]]; then echo "Testing" - quietly ./src/qt/test/test_elements-qt - quietly ./src/test/test_bitcoin - quietly ./src/bench/bench_bitcoin - quietly ./test/util/bitcoin-util-test.py - quietly ./test/util/rpcauth-test.py - quietly make -C src/univalue/ check + quietly ./src/qt/test/test_elements-qt || notify "fail test qt" 1 + quietly ./src/test/test_bitcoin || notify "fail test bitcoin" 1 + quietly ./src/bench/bench_bitcoin || notify "fail test bench" 1 + quietly ./test/util/test_runner.py || notify "fail test util" 1 + quietly ./test/util/rpcauth-test.py || notify "fail test rpc" 1 echo "Functional testing" - quietly ./test/functional/test_runner.py --jobs="$PARALLEL_TEST" + quietly ./test/functional/test_runner.py --jobs="$PARALLEL_TEST" || notify "fail test runner" 1 + fi + + if [[ "$DO_FUZZ" == "1" ]]; then echo "Cleaning for fuzz" quietly make distclean || true quietly git -C "$WORKTREE" clean -xf echo "Building for fuzz" quietly ./autogen.sh # TODO turn on `,integer` after this rebase - quietly ./configure --with-incompatible-bdb --enable-fuzz --with-sanitizers=address,fuzzer,undefined CC=clang CXX=clang++ + quietly ./configure --enable-fuzz --with-sanitizers=address,fuzzer,undefined CC="ccache clang" CXX="ccache clang++" quietly make -j"$PARALLEL_BUILD" -k echo "Fuzzing" - quietly ./test/fuzz/test_runner.py -j"$PARALLEL_FUZZ" "${FUZZ_CORPUS}" + quietly ./test/fuzz/test_runner.py -j"$PARALLEL_FUZZ" "${FUZZ_CORPUS}" || notify "fail fuzz" 1 fi if [[ "$KEEP_GOING" == "0" ]]; then - exit 1 + notify "$PR_ID done, exiting" + exit 0 + else + echo "$PR_ID done, continuing" fi -# bummer1.sh SKIP_MERGE=0 + echo "end" >> merge.log done diff --git a/doc/github-merge-script.md b/doc/github-merge-script.md index 87dba3abfe..f83f2f5f5d 100644 --- a/doc/github-merge-script.md +++ b/doc/github-merge-script.md @@ -24,8 +24,8 @@ github-merge.py For example for PR 1518 I see this output: ``` -ElementsProject/elements#1518 Avoid Simplicity header dependency propogation into master -* 6c7788adf373cd8f0dc5c4fe2b7674625631721e Avoid Simplicity header dependency propogation (Russell O'Connor) (upstream/simplicity, pull/1518/head) +ElementsProject/elements#1518 Avoid Simplicity header dependency propagation into master +* 6c7788adf373cd8f0dc5c4fe2b7674625631721e Avoid Simplicity header dependency propagation (Russell O'Connor) (upstream/simplicity, pull/1518/head) Dropping you on a shell so you can try building/testing the merged source. Run 'git diff HEAD~' to show the changes being merged. @@ -47,10 +47,10 @@ exit In our example this results in the following output: ``` -[pull/1518/local-merge 5e1a950e52] Merge ElementsProject/elements#1518: Avoid Simplicity header dependency propogation +[pull/1518/local-merge 5e1a950e52] Merge ElementsProject/elements#1518: Avoid Simplicity header dependency propagation Date: Thu Jan 22 14:49:26 2026 +0200 -ElementsProject/elements#1518 Avoid Simplicity header dependency propogation into master -* 6c7788adf373cd8f0dc5c4fe2b7674625631721e Avoid Simplicity header dependency propogation (Russell O'Connor) (upstream/simplicity, pull/1518/head) +ElementsProject/elements#1518 Avoid Simplicity header dependency propagation into master +* 6c7788adf373cd8f0dc5c4fe2b7674625631721e Avoid Simplicity header dependency propagation (Russell O'Connor) (upstream/simplicity, pull/1518/head) ACKs: * ACK 6c7788a; built and tested locally (delta1) * ACK 6c7788adf373cd8f0dc5c4fe2b7674625631721e; successfully ran local tests (apoelstra) diff --git a/src/init.cpp b/src/init.cpp index 460010ec9a..971796080e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1834,6 +1834,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) index_cache_sizes.filter_index * (1.0 / 1024 / 1024), BlockFilterTypeName(filter_type)); } LogInfo("* Using %.1f MiB for chain state database", kernel_cache_sizes.coins_db * (1.0 / 1024 / 1024)); + LogInfo("ELIP 203 is%s active\n", (chainparams.GetAcceptUnlimitedIssuances())?"":" not"); assert(!node.mempool); assert(!node.chainman); diff --git a/src/kernel/chainparams.cpp b/src/kernel/chainparams.cpp index 22e5e550e7..c677917adc 100644 --- a/src/kernel/chainparams.cpp +++ b/src/kernel/chainparams.cpp @@ -1293,6 +1293,7 @@ public: default_signblockscript = "51210217e403ddb181872c32a0cd468c710040b2f53d8cac69f18dad07985ee37e9a7151ae"; create_discount_ct = false; accept_discount_ct = true; + accept_unlimited_issuances = true; UpdateFromArgs(args); multi_data_permitted = true; SetGenesisBlock(); @@ -1402,7 +1403,7 @@ public: enforce_pak = true; - accept_unlimited_issuances = args.GetBoolArg("-acceptunlimitedissuances", false); + accept_unlimited_issuances = args.GetBoolArg("-acceptunlimitedissuances", true); multi_data_permitted = true; create_discount_ct = args.GetBoolArg("-creatediscountct", false); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 9494715551..84ceaafa29 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -639,34 +639,34 @@ static RPCHelpMan getblockheader() {RPCResult::Type::STR_HEX, "merkleroot", "The merkle root"}, {RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME}, {RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME}, - {RPCResult::Type::NUM, "nonce", /*optional=*/true, "The nonce"}, // Not for elements + {RPCResult::Type::NUM, "nonce", /*optional=*/true, "The nonce"}, {RPCResult::Type::STR_HEX, "bits", /*optional=*/true, "The bits"}, {RPCResult::Type::STR_HEX, "target", /*optional=*/true, "The difficulty target"}, - {RPCResult::Type::NUM, "difficulty", /*optional=*/true, "The difficulty"}, // Not for elements - {RPCResult::Type::STR_HEX, "chainwork", /*optional=*/true, "Expected number of hashes required to produce the current chain"}, // Not for elements + {RPCResult::Type::NUM, "difficulty", /*optional=*/true, "The difficulty"}, + {RPCResult::Type::STR_HEX, "chainwork", /*optional=*/true, "Expected number of hashes required to produce the current chain"}, {RPCResult::Type::NUM, "nTx", "The number of transactions in the block"}, - {RPCResult::Type::STR, "signblock_challenge", /*optional=*/true, "The challenge for blocksigning (pre-dynafed)"}, {RPCResult::Type::STR, "signblock_witness_asm", /*optional=*/true, "ASM of sign block witness data"}, - {RPCResult::Type::STR_HEX, "signblock_witness_hex", "Hex of sign block witness data", {}, /*skip_type_check=*/true}, + {RPCResult::Type::STR_HEX, "signblock_witness_hex", /*optional=*/true, "Hex of sign block witness data"}, + {RPCResult::Type::STR_HEX, "signblock_challenge", /*optional=*/true, "Hex of sign block challenge"}, + {RPCResult::Type::STR, "warning", /*optional=*/true, "Warning message if block was not loaded cleanly"}, {RPCResult::Type::OBJ, "dynamic_parameters", /*optional=*/true, "Dynamic federation parameters in the block, if any", { - {RPCResult::Type::OBJ, "current", "enforced dynamic federation parameters. The signblockscript is published for each block, while others are published only at epoch start", + {RPCResult::Type::OBJ, "current", "enforced dynamic federation parameters", { - {RPCResult::Type::STR_HEX, "signblockscript", "signblock script"}, - {RPCResult::Type::NUM, "max_block_witness", "Maximum serialized size of the block witness stack"}, - {RPCResult::Type::STR_HEX, "fedpegscript", /*optional=*/true, "fedpeg script"}, - {RPCResult::Type::STR_HEX, "fedpeg_program", /*optional=*/true, "fedpeg program"}, - {RPCResult::Type::STR_HEX, "root", "The Merkle root"}, - {RPCResult::Type::STR_HEX, "extra_root", "extra Merkle root"}, - {RPCResult::Type::STR, "type", "type of parameter encoding (null, compact, full)"}, - {RPCResult::Type::ARR, "extension_space", /*optional=*/true, "array of hex-encoded strings", + {RPCResult::Type::STR_HEX, "root", /*optional=*/true, "parameter root"}, + {RPCResult::Type::STR_HEX, "signblockscript", /*optional=*/true, "signblock script as hex"}, + {RPCResult::Type::NUM, "max_block_witness", /*optional=*/true, "maximum serialized size of the block witness stack"}, + {RPCResult::Type::STR_HEX, "extra_root", /*optional=*/true, "extra root"}, + {RPCResult::Type::STR_HEX, "fedpeg_program", /*optional=*/true, "fedpeg program scriptPubKey in hex"}, + {RPCResult::Type::STR_HEX, "fedpegscript", /*optional=*/true, "fedpeg script in hex"}, + {RPCResult::Type::ARR, "extension_space", /*optional=*/true, "extension space as hex strings", { {RPCResult::Type::ELISION, "", ""} }} }}, {RPCResult::Type::OBJ, "proposed", "Proposed parameters. Unenforced. Must be published in full", { - {RPCResult::Type::ELISION, "", "same entries as current"} + {RPCResult::Type::ELISION, "", "same entries as \"current\""} }}, }}, {RPCResult::Type::STR_HEX, "previousblockhash", /*optional=*/true, "The hash of the previous block (if available)"}, @@ -841,29 +841,35 @@ static RPCHelpMan getblock() {{RPCResult::Type::STR_HEX, "", "The transaction id"}}}, {RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME}, {RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME}, - {RPCResult::Type::NUM, "nonce", "The nonce"}, - {RPCResult::Type::STR_HEX, "bits", "nBits: compact representation of the block difficulty target"}, - {RPCResult::Type::STR_HEX, "target", "The difficulty target"}, - {RPCResult::Type::NUM, "difficulty", "The difficulty"}, - {RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the chain up to this block (in hex)"}, + {RPCResult::Type::NUM, "nonce", /*optional=*/true, "The nonce"}, + {RPCResult::Type::STR_HEX, "bits", /*optional=*/true, "The bits"}, + {RPCResult::Type::STR_HEX, "target", /*optional=*/true, "The difficulty target"}, + {RPCResult::Type::NUM, "difficulty", /*optional=*/true, "The difficulty"}, + {RPCResult::Type::STR_HEX, "chainwork", /*optional=*/true, "Expected number of hashes required to produce the chain up to this block"}, {RPCResult::Type::NUM, "nTx", "The number of transactions in the block"}, - {RPCResult::Type::STR, "signblock_witness_asm", "ASM of sign block witness data"}, - {RPCResult::Type::STR_HEX, "signblock_witness_hex", "Hex of sign block witness data"}, - {RPCResult::Type::OBJ, "dynamic_parameters", "Dynamic federation parameters in the block, if any", + {RPCResult::Type::STR, "signblock_witness_asm", /*optional=*/true, "ASM of sign block witness data"}, + {RPCResult::Type::STR_HEX, "signblock_witness_hex", /*optional=*/true, "Hex of sign block witness data"}, + {RPCResult::Type::STR_HEX, "signblock_challenge", /*optional=*/true, "Hex of sign block challenge"}, + {RPCResult::Type::STR, "warning", /*optional=*/true, "Warning message if block was not loaded cleanly"}, + {RPCResult::Type::OBJ, "dynamic_parameters", /*optional=*/true, "Dynamic federation parameters in the block, if any", { {RPCResult::Type::OBJ, "current", "enforced dynamic federation parameters. The signblockscript is published for each block, while others are published only at epoch start", { - {RPCResult::Type::STR_HEX, "signblockscript", "signblock script"}, - {RPCResult::Type::NUM, "max_block_witness", "Maximum serialized size of the block witness stack"}, - {RPCResult::Type::STR_HEX, "fedpegscript", "fedpeg script"}, - {RPCResult::Type::ARR, "extension_space", "array of hex-encoded strings", + {RPCResult::Type::STR, "type", "one of \"null\", \"compact\", \"full\""}, + {RPCResult::Type::STR_HEX, "root", /*optional=*/true, "parameter root"}, + {RPCResult::Type::STR_HEX, "signblockscript", /*optional=*/true, "signblock script as hex"}, + {RPCResult::Type::NUM, "max_block_witness", /*optional=*/true, "maximum serialized size of the block witness stack"}, + {RPCResult::Type::STR_HEX, "extra_root", /*optional=*/true, "extra root"}, + {RPCResult::Type::STR_HEX, "fedpeg_program", /*optional=*/true, "fedpeg program scriptPubKey in hex"}, + {RPCResult::Type::STR_HEX, "fedpegscript", /*optional=*/true, "fedpeg script in hex"}, + {RPCResult::Type::ARR, "extension_space", /*optional=*/true, "extension space as hex strings", { {RPCResult::Type::ELISION, "", ""} }}, }}, {RPCResult::Type::OBJ, "proposed", "Proposed parameters. Uninforced. Must be published in full", { - {RPCResult::Type::ELISION, "", "same entries as current"} + {RPCResult::Type::ELISION, "", "same entries as \"current\""} }}, }}, {RPCResult::Type::STR_HEX, "previousblockhash", /*optional=*/true, "The hash of the previous block (if available)"}, @@ -1237,11 +1243,11 @@ static RPCHelpMan gettxout() RPCResult{"Otherwise", RPCResult::Type::OBJ, "", "", { {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at the tip of the chain"}, {RPCResult::Type::NUM, "confirmations", "The number of confirmations"}, - {RPCResult::Type::STR_AMOUNT, "value", /*optional=*/true, "The transaction value in " + CURRENCY_UNIT + " if known"}, // ELEMENTS: only known if non-confidential - {RPCResult::Type::STR_HEX, "asset", /*optional=*/true, "The asset of the output, if known"}, - {RPCResult::Type::STR_HEX, "valuecommitment", /*optional=*/true, "The commitment for the value"}, - {RPCResult::Type::STR_HEX, "commitmentnonce", /*optional=*/true, "The commitment nonce"}, - {RPCResult::Type::STR_HEX, "assetcommitment", /*optional=*/true, "Commitment for the asset"}, + {RPCResult::Type::STR_AMOUNT, "value", /*optional=*/true, "The transaction value in " + CURRENCY_UNIT}, + {RPCResult::Type::STR_HEX, "valuecommitment", /*optional=*/true, "Hex-encoded value commitment"}, + {RPCResult::Type::STR_HEX, "asset", /*optional=*/true, "Explicit asset id"}, + {RPCResult::Type::STR_HEX, "assetcommitment", /*optional=*/true, "Hex-encoded asset commitment"}, + {RPCResult::Type::STR_HEX, "commitmentnonce", /*optional=*/true, "Output nonce / commitment field"}, {RPCResult::Type::OBJ, "scriptPubKey", "", { {RPCResult::Type::STR, "asm", "Disassembly of the output script"}, {RPCResult::Type::STR, "desc", "Inferred descriptor for the output"}, @@ -1458,27 +1464,23 @@ RPCHelpMan getblockchaininfo() /* ELEMENTS: not present {RPCResult::Type::STR_HEX, "chainwork", "total amount of work in active chain, in hexadecimal"}, */ {RPCResult::Type::NUM, "size_on_disk", "the estimated size of the block and undo files on disk"}, {RPCResult::Type::BOOL, "pruned", "if the blocks are subject to pruning"}, - {RPCResult::Type::BOOL, "trim_headers", "if trim_headers is enabled"}, - {RPCResult::Type::STR_HEX, "current_params_root", /*optional=*/true, "the root of the currently active dynafed params"}, // present if dynafed is active - {RPCResult::Type::STR, "signblock_asm", /*optional=*/true, "ASM of sign block challenge data from genesis block"}, // not present if dynafed is active - {RPCResult::Type::STR, "signblock_asm", /*optional=*/true, "ASM of sign block challenge data from genesis block"}, // not present if dynafed is active - {RPCResult::Type::STR_HEX, "signblock_hex", /*optional=*/true, "Hex of sign block challenge data from genesis block"}, // not present if dynafed is active - {RPCResult::Type::STR, "current_signblock_asm", /*optional=*/true, "ASM of sign block challenge data enforced on the next block"}, // present if dynafed is active - {RPCResult::Type::STR_HEX, "current_signblock_hex", /*optional=*/true, "Hex of sign block challenge data enforced on the next block"}, // present if dynafed is active - {RPCResult::Type::NUM, "max_block_witness", "maximum sized block witness serialized size for the next block"}, - {RPCResult::Type::NUM, "epoch_length", /*optional=*/true, "length of dynamic federations epoch, or signaling period"}, // present if dynafed is active - {RPCResult::Type::NUM, "total_valid_epochs", /*optional=*/true, "number of epochs a given fedpscript is valid for, defined per chain"}, // present if dynafed is active - {RPCResult::Type::NUM, "epoch_age", /*optional=*/true, "number of blocks into a dynamic federation epoch chain tip is. This number is between 0 to epoch_length-1"}, // present if dynafed is active - {RPCResult::Type::ARR, "extension_space", "array of extension fields in dynamic blockheader", + {RPCResult::Type::BOOL, "trim_headers", "whether header trimming is enabled (-trim-headers)"}, + {RPCResult::Type::STR_HEX, "current_params_root", /*optional=*/true, "the root of the currently active dynafed params"}, + {RPCResult::Type::STR_HEX, "current_fedpeg_program", /*optional=*/true, "The fedpeg program enforced on the next block"}, + {RPCResult::Type::STR_HEX, "current_fedpeg_script", /*optional=*/true, "The fedpeg script enforced on the next block"}, + {RPCResult::Type::STR, "current_signblock_asm", /*optional=*/true, "ASM of sign block challenge data enforced on the next block"}, + {RPCResult::Type::STR_HEX, "current_signblock_hex", /*optional=*/true, "Hex of sign block challenge data enforced on the next block"}, + {RPCResult::Type::NUM, "max_block_witness", /*optional=*/true, "maximum sized block witness serialized size for the next block"}, + {RPCResult::Type::NUM, "epoch_length", /*optional=*/true, "length of dynamic federations epoch, or signaling period"}, + {RPCResult::Type::NUM, "total_valid_epochs", /*optional=*/true, "number of epochs a given fedpegscript is valid for, defined per chain"}, + {RPCResult::Type::NUM, "epoch_age", /*optional=*/true, "number of blocks into a dynamic federation epoch chain tip is. This number is between 0 to epoch_length-1"}, + {RPCResult::Type::ARR, "extension_space", /*optional=*/true, "array of extension fields in dynamic blockheader", { {RPCResult::Type::ELISION, "", ""} }}, - {RPCResult::Type::STR_HEX, "current_fedpeg_program", /*optional=*/true, "Current dynafed fedpeg program"}, - {RPCResult::Type::STR_HEX, "current_fedpeg_script", /*optional=*/true, "Current dynafed fedpeg script"}, - {RPCResult::Type::NUM, "pruneheight", /*optional=*/true, "height of the last block pruned, plus one (only present if pruning is enabled)"}, + {RPCResult::Type::NUM, "pruneheight", /*optional=*/true, "lowest-height complete block stored (only present if pruning is enabled)"}, {RPCResult::Type::BOOL, "automatic_pruning", /*optional=*/true, "whether automatic pruning is enabled (only present if pruning is enabled)"}, {RPCResult::Type::NUM, "prune_target_size", /*optional=*/true, "the target size used by pruning (only present if automatic pruning is enabled)"}, - {RPCResult::Type::STR_HEX, "signet_challenge", /*optional=*/true, "the block challenge (aka. block script), in hexadecimal (only present if the current network is a signet)"}, (IsDeprecatedRPCEnabled("warnings") ? RPCResult{RPCResult::Type::STR, "warnings", "any network and blockchain warnings (DEPRECATED)"} : RPCResult{RPCResult::Type::ARR, "warnings", "any network and blockchain warnings (run with `-deprecatedrpc=warnings` to return the latest warning as a single string)", @@ -2482,7 +2484,7 @@ static RPCHelpMan scantxoutset() {RPCResult::Type::NUM, "confirmations", "Number of confirmations of the unspent transaction output when the scan was done"}, }}, }}, - {RPCResult::Type::STR_AMOUNT, "total_unblinded_bitcoin_amount", "The total amount of all found unspent unblinded outputs in " + CURRENCY_UNIT}, + {RPCResult::Type::STR_AMOUNT, "total_unblinded_bitcoin_amount", /*optional=*/true, "The total amount of all found unspent unblinded outputs in " + CURRENCY_UNIT}, {RPCResult::Type::STR_AMOUNT, "total_amount", /*optional=*/true, "The total amount of all found unspent outputs in " + CURRENCY_UNIT}, }}, scan_result_abort, @@ -3690,6 +3692,12 @@ static RPCHelpMan getsidechaininfo() {RPCResult::Type::STR_HEX, "parent_pegged_asset", /*optional=*/true, "If the parent chain has Confidential Assets, the asset id of the pegged asset in that chain"}, {RPCResult::Type::NUM, "pegin_confirmation_depth", "The number of mainchain confirmations required for a peg-in transaction to become valid"}, {RPCResult::Type::BOOL, "enforce_pak", "If peg-out authorization is being enforced"}, + {RPCResult::Type::STR, "pegin_min_amount", /*optional=*/true, "minimum peg-in amount enforced by consensus"}, + {RPCResult::Type::NUM, "pegin_min_height", /*optional=*/true, "block height from which the minimum peg-in amount applies"}, + {RPCResult::Type::BOOL, "pegin_min_active", /*optional=*/true, "whether the minimum peg-in rule is active at the current tip"}, + {RPCResult::Type::STR, "pegin_subsidy_threshold", /*optional=*/true, "peg-in subsidy threshold amount"}, + {RPCResult::Type::NUM, "pegin_subsidy_height", /*optional=*/true, "block height from which the peg-in subsidy rule applies"}, + {RPCResult::Type::BOOL, "pegin_subsidy_active", /*optional=*/true, "whether the peg-in subsidy rule is active at the current tip"}, }}, RPCExamples{ HelpExampleCli("getsidechaininfo", "") diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 361eb41845..fb191e127c 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -162,6 +162,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "walletcreatefundedpsbt", 3, "changePosition"}, { "walletcreatefundedpsbt", 3, "includeWatching"}, { "walletcreatefundedpsbt", 3, "lockUnspents"}, + { "walletcreatefundedpsbt", 3, "include_explicit"}, { "walletcreatefundedpsbt", 3, "fee_rate"}, { "walletcreatefundedpsbt", 3, "feeRate"}, { "walletcreatefundedpsbt", 3, "subtractFeeFromOutputs"}, diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 1d83112b93..d620a286ff 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -1501,8 +1501,8 @@ static RPCHelpMan consumegetblocktxn() return RPCHelpMan{"consumegetblocktxn", "Consumes a transaction request for a compact block sketch.", { - {"full_block", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Hex serialied block that corresponds to the block request `block_tx_req`."}, - {"block_tx_req", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Hex serialied BlockTransactionsRequest, aka getblocktxn network message."}, + {"full_block", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Hex serialized block that corresponds to the block request `block_tx_req`."}, + {"block_tx_req", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Hex serialized BlockTransactionsRequest, aka getblocktxn network message."}, }, RPCResult{ RPCResult::Type::STR_HEX, "block_transactions", "The serialized list of found transactions aka BlockTransactions", diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 14f8d77e51..bc7081a625 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -626,17 +626,17 @@ static RPCHelpMan getnetworkinfo() {RPCResult::Type::NUM, "version", "the server version"}, {RPCResult::Type::STR, "subversion", "the server subversion string"}, {RPCResult::Type::NUM, "protocolversion", "the protocol version"}, - {RPCResult::Type::STR_HEX, "localservices", "the services we offer to the network"}, - {RPCResult::Type::ARR, "localservicesnames", "the services we offer to the network, in human-readable form", + {RPCResult::Type::STR_HEX, "localservices", /*optional=*/true, "the services we offer to the network"}, + {RPCResult::Type::ARR, "localservicesnames", /*optional=*/true, "the services we offer to the network, in human-readable form", { {RPCResult::Type::STR, "SERVICE_NAME", "the service name"}, }}, - {RPCResult::Type::BOOL, "localrelay", "true if transaction relay is requested from peers"}, + {RPCResult::Type::BOOL, "localrelay", /*optional=*/true, "true if transaction relay is requested from peers"}, {RPCResult::Type::NUM, "timeoffset", "the time offset"}, - {RPCResult::Type::NUM, "connections", "the total number of connections"}, - {RPCResult::Type::NUM, "connections_in", "the number of inbound connections"}, - {RPCResult::Type::NUM, "connections_out", "the number of outbound connections"}, - {RPCResult::Type::BOOL, "networkactive", "whether p2p networking is enabled"}, + {RPCResult::Type::NUM, "connections", /*optional=*/true, "the total number of connections"}, + {RPCResult::Type::NUM, "connections_in", /*optional=*/true, "the number of inbound connections"}, + {RPCResult::Type::NUM, "connections_out", /*optional=*/true, "the number of outbound connections"}, + {RPCResult::Type::BOOL, "networkactive", /*optional=*/true, "whether p2p networking is enabled"}, {RPCResult::Type::ARR, "networks", "information per network", { {RPCResult::Type::OBJ, "", "", diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index cde50b3cea..2ea9c3e21c 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -150,18 +150,19 @@ static std::vector DecodeTxDoc(const std::string& txid_field_doc) { {RPCResult::Type::OBJ, "", "", { - {RPCResult::Type::STR_AMOUNT, "value", /*optional=*/true, "The value in " + CURRENCY_UNIT + " if known"}, // ELEMENTS: present if not confidential - {RPCResult::Type::STR_HEX, "asset", /*optional=*/true, "Asset type for issuance if known"}, - {RPCResult::Type::STR_HEX, "assetcommitment", /*optional=*/true, "Commitment for the asset"}, - {RPCResult::Type::STR_HEX, "commitmentnonce", "The commitment nonce"}, - {RPCResult::Type::BOOL, "commitmentnonce_fully_valid", "Whether the commitment nonce is a valid pubkey"}, - {RPCResult::Type::NUM, "ct-bits", /*optional=*/true, "The mantissa of the range proof"}, - {RPCResult::Type::NUM, "ct-exponent", /*optional=*/true, "The exponent of the range proof"}, + {RPCResult::Type::NUM, "value", "The value in " + CURRENCY_UNIT}, + {RPCResult::Type::STR_AMOUNT, "value", /*optional=*/true, "The value in " + CURRENCY_UNIT}, + {RPCResult::Type::STR_AMOUNT, "value-minimum", /*optional=*/true, "Minimum decoded value for confidential outputs"}, + {RPCResult::Type::STR_AMOUNT, "value-maximum", /*optional=*/true, "Maximum decoded value for confidential outputs"}, + {RPCResult::Type::NUM, "ct-exponent", /*optional=*/true, "Confidential transaction exponent"}, + {RPCResult::Type::NUM, "ct-bits", /*optional=*/true, "Confidential transaction mantissa bits"}, + {RPCResult::Type::STR_HEX, "valuecommitment", /*optional=*/true, "Hex value commitment for confidential outputs"}, + {RPCResult::Type::STR_HEX, "surjectionproof", /*optional=*/true, "Asset surjection proof"}, + {RPCResult::Type::STR_HEX, "asset", /*optional=*/true, "Explicit asset id"}, + {RPCResult::Type::STR_HEX, "assetcommitment", /*optional=*/true, "Asset commitment"}, + {RPCResult::Type::STR_HEX, "commitmentnonce", /*optional=*/true, "Nonce commitment for confidential outputs"}, + {RPCResult::Type::BOOL, "commitmentnonce_fully_valid", /*optional=*/true, "Whether the nonce commitment parses as a valid pubkey"}, {RPCResult::Type::NUM, "n", "index"}, - {RPCResult::Type::STR_HEX, "surjectionproof", /*optional=*/true, "The surjection proof for the output"}, - {RPCResult::Type::NUM, "value-maximum", /*optional=*/true, "The maximum value in the range of the confidential output"}, - {RPCResult::Type::NUM, "value-minimum", /*optional=*/true, "The minimum value in the range of the confidential output"}, - {RPCResult::Type::STR_HEX, "valuecommitment", /*optional=*/true, "The commitment of the value"}, {RPCResult::Type::OBJ, "scriptPubKey", "", ScriptPubKeyDoc()}, }}, }}, @@ -204,12 +205,15 @@ static std::vector CreateTxDoc() }, {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", { - {"vdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The key is \"vdata\", the value is an array of hex encoded data"}, + {"vdata", RPCArg::Type::ARR, RPCArg::Optional::NO, "The key is \"vdata\", the value is an array of hex encoded data", + { + {"", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "Hex-encoded data"}, + }}, }, }, {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", { - {"burn", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "A key-value pair. The key must be \"burn\", the value is the amount that will be burned."}, + {"burn", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "A key-value pair. The key must be \"burn\", the value is the amount that will be burned."}, }, }, {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", @@ -1999,12 +2003,12 @@ static RPCHelpMan createpsbt() {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"}, {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"}, {"sequence", RPCArg::Type::NUM, RPCArg::DefaultHint{"depends on the value of the 'replaceable' and 'locktime' arguments"}, "The sequence number"}, - {"pegin_bitcoin_tx", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The raw bitcoin transaction (in hex) depositing bitcoin to the mainchain_address generated by getpeginaddress"}, - {"pegin_txout_proof", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "A rawtxoutproof (in hex) generated by the mainchain daemon's `gettxoutproof` containing a proof of only bitcoin_tx"}, - {"pegin_claim_script", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The witness program generated by getpeginaddress."}, + {"pegin_bitcoin_tx", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(only for pegin inputs) The raw bitcoin transaction (in hex) depositing bitcoin to the mainchain_address generated by getpeginaddress"}, + {"pegin_txout_proof", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(only for pegin inputs) A rawtxoutproof (in hex) generated by the mainchain daemon's `gettxoutproof` containing a proof of only bitcoin_tx"}, + {"pegin_claim_script", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(only for pegin inputs) The claim script generated by getpeginaddress."}, {"issuance_amount", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The amount to be issued"}, {"issuance_tokens", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The number of asset issuance tokens to generate"}, - {"asset_entropy", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "For new asset issuance, this is any additional entropy to be used in the asset tag calculation. For reissuance, this is the original asaset entropy"}, + {"asset_entropy", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "For new asset issuance, this is any additional entropy to be used in the asset tag calculation. For reissuance, this is the original asset entropy"}, {"asset_blinding_nonce", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "Do not set for new asset issuance. For reissuance, this is the blinding factor for reissuance token output for the asset being reissued"}, {"blind_reissuance", RPCArg::Type::BOOL, RPCArg::Default{true}, "Whether to mark the issuance input for blinding or not. Only affects issuances with re-issuance tokens."}, }, @@ -3134,7 +3138,7 @@ static RPCHelpMan updatepsbtpegin() {"input", RPCArg::Type::NUM, RPCArg::Optional::NO, "The index of the input to update"}, {"value", RPCArg::Type::AMOUNT, RPCArg::Optional::OMITTED, "The value of the peg-in"}, {"bitcoin_tx", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "The raw bitcoin transaction (in hex) depositing bitcoin to the mainchain_address generated by getpeginaddress"}, - {"txout_proof", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A rawtxoutproof (in hex) generated by the mainchain daemon'sgettxoutproof containing a proof of only bitcoin_tx"}, + {"txout_proof", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A rawtxoutproof (in hex) generated by the mainchain daemon's gettxoutproof containing a proof of only bitcoin_tx"}, {"claim_script", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "The witness program generated by getpeginaddress."}, {"genesis_hash", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "The hash of the genesis block of the chain the bitcoin_tx is in"}, }, diff --git a/src/wallet/rpc/addresses.cpp b/src/wallet/rpc/addresses.cpp index 0ebbd2cde8..762f668636 100644 --- a/src/wallet/rpc/addresses.cpp +++ b/src/wallet/rpc/addresses.cpp @@ -28,7 +28,7 @@ RPCHelpMan getnewaddress() "the address type \"blech32\" can still be used to get a blinded address.\n", { {"label", RPCArg::Type::STR, RPCArg::Default{""}, "The label name for the address to be linked to. It can also be set to the empty string \"\" to represent the default label. The label does not need to exist, it will be created if there is no label by the given name."}, - {"address_type", RPCArg::Type::STR, RPCArg::DefaultHint{"set by -addresstype"}, "The address type to use. Options are \"legacy\", \"p2sh-segwit\", \"bech32\", and \"bech32m\"."}, + {"address_type", RPCArg::Type::STR, RPCArg::DefaultHint{"set by -addresstype"}, "The address type to use. Options are \"legacy\", \"p2sh-segwit\", \"bech32\", \"bech32m\", \"blech32\"."}, }, RPCResult{ RPCResult::Type::STR, "address", "The new address" @@ -88,7 +88,7 @@ RPCHelpMan getrawchangeaddress() "\nReturns a new Bitcoin address, for receiving change.\n" "This is for use with raw transactions, NOT normal use.\n", { - {"address_type", RPCArg::Type::STR, RPCArg::DefaultHint{"set by -changetype"}, "The address type to use. Options are \"legacy\", \"p2sh-segwit\", \"bech32\", and \"bech32m\"."}, + {"address_type", RPCArg::Type::STR, RPCArg::DefaultHint{"set by -changetype"}, "The address type to use. Options are \"legacy\", \"p2sh-segwit\", \"bech32\", \"bech32m\", \"blech32\"."}, }, RPCResult{ RPCResult::Type::STR, "address", "The address" diff --git a/src/wallet/rpc/coins.cpp b/src/wallet/rpc/coins.cpp index 55d5da8c08..fd3bddc22a 100644 --- a/src/wallet/rpc/coins.cpp +++ b/src/wallet/rpc/coins.cpp @@ -99,11 +99,17 @@ RPCHelpMan getreceivedbyaddress() {"include_immature_coinbase", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include immature coinbase transactions."}, }, { - RPCResult{RPCResult::Type::OBJ, "amount_map", "The total amount, per asset if none is specified, in " + CURRENCY_UNIT + " received for this wallet.", - { - {RPCResult::Type::ELISION, "", "the amount for each asset"}, - }}, - RPCResult{RPCResult::Type::NUM, "amount", "the total amount for the asset, if one is specified"}, + RPCResult{"if in Elements mode and assetlabel is omitted or empty", + RPCResult::Type::OBJ_DYN, + "", + "Map from asset label or hex asset id to numeric amount in " + CURRENCY_UNIT + ".", + { + {RPCResult::Type::STR_AMOUNT, "n", "amount for the keyed asset"}, + }}, + RPCResult{"if not in Elements mode, or assetlabel is provided", + RPCResult::Type::STR_AMOUNT, + "amount", + "Single total in " + CURRENCY_UNIT + " for the default or requested asset."}, RPCResult{RPCResult::Type::NONE, "", ""}, // in case the wallet is disabled }, RPCExamples{ @@ -151,11 +157,17 @@ RPCHelpMan getreceivedbylabel() {"include_immature_coinbase", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include immature coinbase transactions."}, }, { - RPCResult{RPCResult::Type::OBJ, "amount_map", "The total amount, per asset if none is specified, in " + CURRENCY_UNIT + " received for this wallet.", - { - {RPCResult::Type::ELISION, "", "the amount for each asset"}, - }}, - RPCResult{RPCResult::Type::NUM, "amount", "the total amount for the asset, if one is specified"}, + RPCResult{"if in Elements mode and assetlabel is omitted or empty", + RPCResult::Type::OBJ_DYN, + "", + "Map from asset label or hex asset id to numeric amount in " + CURRENCY_UNIT + ".", + { + {RPCResult::Type::STR_AMOUNT, "n", "amount for the keyed asset"}, + }}, + RPCResult{"if not in Elements mode, or assetlabel is provided", + RPCResult::Type::STR_AMOUNT, + "amount", + "Single total in " + CURRENCY_UNIT + " for the default or requested asset."}, RPCResult{RPCResult::Type::NONE, "", ""}, // in case the wallet is disabled }, RPCExamples{ @@ -206,11 +218,17 @@ RPCHelpMan getbalance() {"assetlabel", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Hex asset id or asset label for balance."}, }, { - RPCResult{RPCResult::Type::OBJ, "amount_map", "The total amount, per asset if none is specified, in " + CURRENCY_UNIT + " received for this wallet.", - { - {RPCResult::Type::ELISION, "", "the amount for each asset"}, - }}, - RPCResult{RPCResult::Type::NUM, "amount", "the total amount for the asset, if one is specified"}, + RPCResult{"if in Elements mode and assetlabel is omitted or empty", + RPCResult::Type::OBJ_DYN, + "", + "Map from asset label or hex asset id to numeric amount in " + CURRENCY_UNIT + ".", + { + {RPCResult::Type::STR_AMOUNT, "n", "amount for the keyed asset"}, + }}, + RPCResult{"if not in Elements mode, or assetlabel is provided", + RPCResult::Type::STR_AMOUNT, + "amount", + "Single total in " + CURRENCY_UNIT + " for the default or requested asset."}, RPCResult{RPCResult::Type::NONE, "", ""}, // in case the wallet is disabled }, RPCExamples{ @@ -265,11 +283,17 @@ RPCHelpMan getunconfirmedbalance() "DEPRECATED\nIdentical to getbalances().mine.untrusted_pending\n", {}, { - RPCResult{RPCResult::Type::OBJ, "amount_map", "The total amount, per asset if none is specified, in " + CURRENCY_UNIT + " received for this wallet.", - { - {RPCResult::Type::ELISION, "", "the amount for each asset"}, - }}, - RPCResult{RPCResult::Type::NUM, "amount", "the total amount for the asset, if one is specified"}, + RPCResult{"if in Elements mode (no asset filter for this RPC)", + RPCResult::Type::OBJ_DYN, + "", + "Map from asset label or hex asset id to numeric amount in " + CURRENCY_UNIT + ".", + { + {RPCResult::Type::STR_AMOUNT, "n", "amount for the keyed asset"}, + }}, + RPCResult{"if not in Elements mode", + RPCResult::Type::STR_AMOUNT, + "amount", + "Single total in " + CURRENCY_UNIT + " for the default asset."}, RPCResult{RPCResult::Type::NONE, "", ""}, // in case the wallet is disabled }, RPCExamples{""}, diff --git a/src/wallet/rpc/elements.cpp b/src/wallet/rpc/elements.cpp index 1a470d1bd3..b32abae753 100644 --- a/src/wallet/rpc/elements.cpp +++ b/src/wallet/rpc/elements.cpp @@ -157,6 +157,12 @@ RPCHelpMan getpeginaddress() { {RPCResult::Type::STR, "mainchain_address", "mainchain deposit address to send bitcoin to"}, {RPCResult::Type::STR_HEX, "claim_script", "claim script committed to by the mainchain address. This may be required in `claimpegin` to retrieve pegged-in funds\n"}, + {RPCResult::Type::STR_AMOUNT, "pegin_min_amount", /*optional=*/true, "Minimum peg-in amount in " + CURRENCY_UNIT}, + {RPCResult::Type::NUM, "pegin_min_height", /*optional=*/true, "Minimum block height for peg-in amount rule"}, + {RPCResult::Type::BOOL, "pegin_min_active", /*optional=*/true, "Whether the peg-in minimum height rule is active at the current tip"}, + {RPCResult::Type::STR_AMOUNT, "pegin_subsidy_threshold", /*optional=*/true, "Peg-in subsidy threshold amount"}, + {RPCResult::Type::NUM, "pegin_subsidy_height", /*optional=*/true, "Block height at which peg-in subsidy activates"}, + {RPCResult::Type::BOOL, "pegin_subsidy_active", /*optional=*/true, "Whether peg-in subsidy is active at the current tip"}, }, }, RPCExamples{ @@ -1695,7 +1701,7 @@ RPCHelpMan listissuances() return RPCHelpMan{"listissuances", "\nList all issuances known to the wallet for the given asset, or for all issued assets if none provided.\n", { - {"asset", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "The asset whose issaunces you wish to list. Accepts either the asset hex or the locally assigned asset label."}, + {"asset", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "The asset whose issuances you wish to list. Accepts either the asset hex or the locally assigned asset label."}, }, RPCResult{ RPCResult::Type::ARR, "", "List of transaction issuances and information in wallet", diff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp index a514eac72d..edfbc4338b 100644 --- a/src/wallet/rpc/spend.cpp +++ b/src/wallet/rpc/spend.cpp @@ -875,7 +875,7 @@ RPCHelpMan fundrawtransaction() {"lockUnspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"}, {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."}, {"feeRate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_UNIT + "/kvB."}, - {"subtractFeeFromOutputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The integers.\n" + {"subtractFeeFromOutputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The zero-based output indices, before a change output is added.\n" "The fee will be equally deducted from the amount of each specified output.\n" "Those recipients will receive less coins than you enter in their corresponding amount field.\n" "If no outputs are specified here, the sender pays the fee.", @@ -1821,12 +1821,12 @@ RPCHelpMan walletcreatefundedpsbt() {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"}, {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"}, {"sequence", RPCArg::Type::NUM, RPCArg::DefaultHint{"depends on the value of the 'locktime' and 'options.replaceable' arguments"}, "The sequence number"}, - {"pegin_bitcoin_tx", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The raw bitcoin transaction (in hex) depositing bitcoin to the mainchain_address generated by getpeginaddress"}, - {"pegin_txout_proof", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "A rawtxoutproof (in hex) generated by the mainchain daemon's `gettxoutproof` containing a proof of only bitcoin_tx"}, - {"pegin_claim_script", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The witness program generated by getpeginaddress."}, - {"issuance_amount", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The amount to be issued"}, - {"issuance_tokens", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The number of asset issuance tokens to generate"}, - {"asset_entropy", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "For new asset issuance, this is any additional entropy to be used in the asset tag calculation. For reissuance, this is the original asaset entropy"}, + {"pegin_bitcoin_tx", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(only for pegin inputs) The raw bitcoin transaction (in hex) depositing bitcoin to the mainchain_address generated by getpeginaddress"}, + {"pegin_txout_proof", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(only for pegin inputs) A rawtxoutproof (in hex) generated by the mainchain daemon's `gettxoutproof` containing a proof of only bitcoin_tx"}, + {"pegin_claim_script", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(only for pegin inputs) The claim script generated by getpeginaddress."}, + {"issuance_amount", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The amount to be issued. If set, issuance_tokens and related fields must be provided consistently"}, + {"issuance_tokens", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The number of asset issuance tokens to generate. If set, issuance_amount and related fields must be provided consistently"}, + {"asset_entropy", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "For new asset issuance, this is any additional entropy to be used in the asset tag calculation. For reissuance, this is the original asset entropy"}, {"asset_blinding_nonce", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "Do not set for new asset issuance. For reissuance, this is the blinding factor for reissuance token output for the asset being reissued"}, {"blind_reissuance", RPCArg::Type::BOOL, RPCArg::Default{true}, "Whether to mark the issuance input for blinding or not. Only affects issuances with re-issuance tokens."}, {"weight", RPCArg::Type::NUM, RPCArg::DefaultHint{"Calculated from wallet and solving data"}, "The maximum weight for this input, " @@ -1856,6 +1856,24 @@ RPCHelpMan walletcreatefundedpsbt() {"data", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "A key-value pair. The key must be \"data\", the value is hex-encoded data"}, }, }, + {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", + { + {"vdata", RPCArg::Type::ARR, RPCArg::Optional::NO, "The key is \"vdata\", the value is an array of hex encoded data", + { + {"", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "Hex-encoded data"}, + }}, + }, + }, + {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", + { + {"burn", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "A key-value pair. The key must be \"burn\", the value is the amount that will be burned."}, + }, + }, + {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", + { + {"fee", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The key is \"fee\", the value the fee output you want to add."}, + }, + }, }, RPCArgOptions{.skip_type_check = true}}, {"locktime", RPCArg::Type::NUM, RPCArg::Default{0}, "Raw locktime. Non-0 value also locktime-activates inputs"}, @@ -1873,9 +1891,10 @@ RPCHelpMan walletcreatefundedpsbt() {"change_type", RPCArg::Type::STR, RPCArg::DefaultHint{"set by -changetype"}, "The output type to use. Only valid if changeAddress is not specified. Options are \"legacy\", \"p2sh-segwit\", \"bech32\", and \"bech32m\"."}, {"includeWatching", RPCArg::Type::BOOL, RPCArg::DefaultHint{"true for watch-only wallets, otherwise false"}, "Also select inputs which are watch only"}, {"lockUnspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"}, + {"include_explicit", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include explicit (unblinded) outputs in the resulting PSBT"}, {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."}, {"feeRate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_UNIT + "/kvB."}, - {"subtractFeeFromOutputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The outputs to subtract the fee from.\n" + {"subtractFeeFromOutputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The zero-based output indices, before a change output is added.\n" "The fee will be equally deducted from the amount of each specified output.\n" "Those recipients will receive less coins than you enter in their corresponding amount field.\n" "If no outputs are specified here, the sender pays the fee.", diff --git a/src/wallet/rpc/transactions.cpp b/src/wallet/rpc/transactions.cpp index d9c67a0473..16d9be9e22 100644 --- a/src/wallet/rpc/transactions.cpp +++ b/src/wallet/rpc/transactions.cpp @@ -260,9 +260,9 @@ RPCHelpMan listreceivedbyaddress() RPCExamples{ HelpExampleCli("listreceivedbyaddress", "") + HelpExampleCli("listreceivedbyaddress", "6 true") - + HelpExampleCli("listreceivedbyaddress", "6 true true \"\" true") + + HelpExampleCli("listreceivedbyaddress", "6 true true \"\" \"\" true") + HelpExampleRpc("listreceivedbyaddress", "6, true, true") - + HelpExampleRpc("listreceivedbyaddress", "6, true, true, \"" + EXAMPLE_ADDRESS[0] + "\", true") + + HelpExampleRpc("listreceivedbyaddress", "6, true, true, \"" + EXAMPLE_ADDRESS[0] + "\", \"\", true") }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { @@ -309,6 +309,7 @@ RPCHelpMan listreceivedbylabel() RPCExamples{ HelpExampleCli("listreceivedbylabel", "") + HelpExampleCli("listreceivedbylabel", "6 true") + + HelpExampleCli("listreceivedbylabel", "6 true true true") + HelpExampleRpc("listreceivedbylabel", "6, true, true, true") }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue @@ -620,6 +621,9 @@ RPCHelpMan listsinceblock() "\"orphan\" Orphaned coinbase transactions received."}, {RPCResult::Type::STR_AMOUNT, "amount", "The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and is positive\n" "for all other categories"}, + {RPCResult::Type::STR_HEX, "amountblinder", "The amount blinding factor in hex"}, + {RPCResult::Type::STR_HEX, "asset", "The asset id in hex"}, + {RPCResult::Type::STR_HEX, "assetblinder", "The asset blinding factor in hex"}, {RPCResult::Type::NUM, "vout", "the vout value"}, {RPCResult::Type::STR_HEX, "amountblinder", /*optional=*/true, "The amount blinder"}, {RPCResult::Type::STR_HEX, "asset", /*optional=*/true, "The asset type"}, @@ -924,7 +928,7 @@ RPCHelpMan rescanblockchain() RPCResult::Type::OBJ, "", "", { {RPCResult::Type::NUM, "start_height", "The block height where the rescan started (the requested height or 0)"}, - {RPCResult::Type::NUM, "stop_height", "The height of the last rescanned block. May be null in rare cases if there was a reorg and the call didn't scan any blocks because they were already scanned in the background."}, + {RPCResult::Type::NUM, "stop_height", /*optional=*/true, "The height of the last rescanned block. May be null in rare cases if there was a reorg and the call didn't scan any blocks because they were already scanned in the background."}, } }, RPCExamples{