Skip to content

Commit

Permalink
Merge #6074: backport: merge bitcoin#18344, bitcoin#20867, bitcoin#20286
Browse files Browse the repository at this point in the history
, bitcoin#21359, bitcoin#21910, bitcoin#19651, bitcoin#21934, bitcoin#22722, bitcoin#20295, bitcoin#23702, partial bitcoin#23706 (rpc backports)

b23d94b partial bitcoin#23706: getblockfrompeer followups (Kittywhiskers Van Gogh)
7e5cc5e merge bitcoin#23702: Add missing optional to getblockfrompeer (Kittywhiskers Van Gogh)
c294457 merge bitcoin#20295: getblockfrompeer (Kittywhiskers Van Gogh)
63ac87f merge bitcoin#22722: update estimatesmartfee rpc to return max of estimateSmartFee, mempoolMinFee and minRelayTxFee. (Kittywhiskers Van Gogh)
07e4c2c merge bitcoin#21934: Include versionbits signalling details during LOCKED_IN (Kittywhiskers Van Gogh)
960e768 merge bitcoin#19651: importdescriptors update existing (Kittywhiskers Van Gogh)
1f31823 merge bitcoin#21910: remove redundant fOnlySafe argument (Kittywhiskers Van Gogh)
69c5aa8 merge bitcoin#21359: include_unsafe option for fundrawtransaction (Kittywhiskers Van Gogh)
169dce7 merge bitcoin#20286: deprecate addresses and reqSigs from rpc outputs (Kittywhiskers Van Gogh)
7cddf70 merge bitcoin#20867: Support up to 20 keys for multisig under Segwit context (Kittywhiskers Van Gogh)
7c59923 merge bitcoin#18344: Fix nit in getblockchaininfo (Kittywhiskers Van Gogh)
ec0803a refactor: align `TxToUniv` argument list with upstream (Kittywhiskers Van Gogh)

Pull request description:

  ## Additional Information

  * Closes #6000

  * `TxToUniv`'s argument list needed to be rearranged to match upstream as closely as possible (i.e. placing Dash-specific arguments at the end of the list to allow for code to be backported unmodified, relying on default arguments instead of having to modify each invocation to insert the default argument in between).

    This was due to a new `TxToUniv` variant being introduced in [bitcoin#20286](bitcoin#20286)

  * The maximum number of public keys in a multisig remains the same. The upper limit for bare multisigs is and always has been `MAX_PUBKEYS_PER_MULTISIG` ([source](https://github.com/dashpay/dash/blob/19512988c6e6e8641245bd9c5fab21dd737561f0/src/script/interpreter.cpp#L1143-L1144)), which has always been 20 ([source](https://github.com/dashpay/dash/blob/19512988c6e6e8641245bd9c5fab21dd737561f0/src/script/script.h#L28-L29)). The limit of up to 16 comes from P2SH overhead ([source](https://github.com/dashpay/dash/blob/19512988c6e6e8641245bd9c5fab21dd737561f0/src/script/descriptor.cpp#L877-L880)) and that hasn't changed.

    In effect, what [bitcoin#20867](bitcoin#20867) does to Dash Core is change the error from "too many public keys" (as we'll be testing against the bare multisig limit) to "excessive redeemScript size" ([source](https://github.com/dashpay/dash/blob/19512988c6e6e8641245bd9c5fab21dd737561f0/src/rpc/util.cpp#L223-L225)) (which is the _true_ limitation).

  * Backporting [bitcoin#21934](bitcoin#21934) required a minor change in the condition needed to emit `activation_height` as `has_signal` in the preceding block will evaluate true for both `STARTED` and `LOCKED_IN` while earlier it would only for `STARTED`.

  * In [bitcoin#22722](bitcoin#22722), a `self.stop_node` had to be added to account for the absurd fee warning that a new test condition introduces.

  * [bitcoin#23706](bitcoin#23706) is partial due to commits in it that rely on RPC type enforcement, which is currently not implemented in Dash Core.

  * `feature_dip3_deterministicmns.py` depends on the reporting of `addresses` to validate multisigs containing expected payees. There is no replacement RPC call to report the pubkeys that compose a multisig address. In the interm, the `-deprecatedrpc=addresses` flag has been enabled to allow the test to run otherwise unmodified.

  ## Breaking Changes

  * The following RPCs:  `gettxout`, `getrawtransaction`, `decoderawtransaction`, `decodescript`, `gettransaction`, and REST endpoints: `/rest/tx`, `/rest/getutxos`, `/rest/block` deprecated the following fields (which are no longer returned in the responses by default): `addresses`, `reqSigs`.

    The `-deprecatedrpc=addresses` flag must be passed for these fields to be included in the RPC response. Note that these fields are attributes of the `scriptPubKey` object returned in the RPC response. However, in the response of `decodescript` these fields are top-level attributes, and included again as attributes of the `scriptPubKey` object.

  * When creating a hex-encoded Dash transaction using the `dash-tx` utility with the `-json` option set, the following fields: `addresses`, `reqSigs` are no longer returned in the tx output of the response.

  * The error message for attempts at making multisigs with >16 pubkeys will change to an "excessive redeemScript size" instead of the previous "too many public keys".

  ## Checklist:

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)**
  - [x] I have added or updated relevant unit/integration/functional/e2e tests
  - [x] I have made corresponding changes to the documentation
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  UdjinM6:
    utACK b23d94b
  PastaPastaPasta:
    utACK b23d94b

Tree-SHA512: 659d9ba3a0a9f8594b307a7056ab172309d5a0d9efec605bc4b345f7e0fb1032ad303af9e8f51dbd6549e82d0b738ad41eae8a5b3aebf59081f39df0d4b5ec7c
  • Loading branch information
PastaPastaPasta committed Jun 27, 2024
2 parents f542e8e + b23d94b commit 37e026a
Show file tree
Hide file tree
Showing 78 changed files with 1,003 additions and 365 deletions.
5 changes: 1 addition & 4 deletions doc/REST-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,8 @@ $ curl localhost:19998/rest/getutxos/checkmempool/b2cdfd7b89def827ff8af7cd9bff76
"scriptPubKey" : {
"asm" : "OP_DUP OP_HASH160 1c7cebb529b86a04c683dfa87be49de35bcf589e OP_EQUALVERIFY OP_CHECKSIG",
"hex" : "76a9141c7cebb529b86a04c683dfa87be49de35bcf589e88ac",
"reqSigs" : 1,
"type" : "pubkeyhash",
"addresses" : [
"mi7as51dvLJsizWnTMurtRmrP8hG2m1XvD"
]
"address" : "mi7as51dvLJsizWnTMurtRmrP8hG2m1XvD"
}
}
]
Expand Down
16 changes: 16 additions & 0 deletions doc/release-notes-20286.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Updated RPCs
------------

- The following RPCs: `gettxout`, `getrawtransaction`, `decoderawtransaction`,
`decodescript`, `gettransaction`, and REST endpoints: `/rest/tx`,
`/rest/getutxos`, `/rest/block` deprecated the following fields (which are no
longer returned in the responses by default): `addresses`, `reqSigs`.
The `-deprecatedrpc=addresses` flag must be passed for these fields to be
included in the RPC response. Note that these fields are attributes of
the `scriptPubKey` object returned in the RPC response. However, in the response
of `decodescript` these fields are top-level attributes, and included again as attributes
of the `scriptPubKey` object.

- When creating a hex-encoded Dash transaction using the `dash-tx` utility
with the `-json` option set, the following fields: `addresses`, `reqSigs` are no longer
returned in the tx output of the response.
7 changes: 7 additions & 0 deletions doc/release-notes-21359.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Wallet
------

- The `fundrawtransaction`, `send` and `walletcreatefundedpsbt` RPCs now support an `include_unsafe` option
that when `true` allows using unsafe inputs to fund the transaction.
Note that the resulting transaction may become invalid if one of the unsafe inputs disappears.
If that happens, the transaction must be funded with different inputs and republished.
3 changes: 2 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -287,12 +287,12 @@ BITCOIN_CORE_H = \
rpc/blockchain.h \
rpc/client.h \
rpc/mining.h \
rpc/net.h \
rpc/protocol.h \
rpc/rawtransaction_util.h \
rpc/register.h \
rpc/request.h \
rpc/server.h \
rpc/server_util.h \
rpc/util.h \
saltedhasher.h \
scheduler.h \
Expand Down Expand Up @@ -510,6 +510,7 @@ libbitcoin_server_a_SOURCES = \
rpc/quorums.cpp \
rpc/rawtransaction.cpp \
rpc/server.cpp \
rpc/server_util.cpp \
script/sigcache.cpp \
shutdown.cpp \
spork.cpp \
Expand Down
2 changes: 1 addition & 1 deletion src/bitcoin-tx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ static void MutateTx(CMutableTransaction& tx, const std::string& command,
static void OutputTxJSON(const CTransaction& tx)
{
UniValue entry(UniValue::VOBJ);
TxToUniv(tx, uint256(), entry);
TxToUniv(tx, uint256(), /* include_addresses */ false, entry);

std::string jsonOutput = entry.write(4);
tfm::format(std::cout, "%s\n", jsonOutput);
Expand Down
2 changes: 1 addition & 1 deletion src/coinjoin/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1538,7 +1538,7 @@ bool CCoinJoinClientSession::CreateCollateralTransaction(CMutableTransaction& tx
CCoinControl coin_control;
coin_control.nCoinType = CoinType::ONLY_COINJOIN_COLLATERAL;

m_wallet.AvailableCoins(vCoins, true, &coin_control);
m_wallet.AvailableCoins(vCoins, &coin_control);

if (vCoins.empty()) {
strReason = strprintf("%s requires a collateral transaction and could not locate an acceptable input!", gCoinJoinName);
Expand Down
4 changes: 2 additions & 2 deletions src/core_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ UniValue ValueFromAmount(const CAmount amount);
std::string FormatScript(const CScript& script);
std::string EncodeHexTx(const CTransaction& tx);
std::string SighashToStr(unsigned char sighash_type);
void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex, bool include_addresses);
void ScriptToUniv(const CScript& script, UniValue& out, bool include_address);
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex = true, const CSpentIndexTxInfo* ptxSpentInfo = nullptr, const CTxUndo* txundo = nullptr);
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, bool include_addresses, UniValue& entry, bool include_hex = true, const CTxUndo* txundo = nullptr, const CSpentIndexTxInfo* ptxSpentInfo = nullptr);

#endif // BITCOIN_CORE_IO_H
24 changes: 16 additions & 8 deletions src/core_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,13 @@ void ScriptToUniv(const CScript& script, UniValue& out, bool include_address)
}
}

// TODO: from v21 ("addresses" and "reqSigs" deprecated) this method should be refactored to remove the `include_addresses` option
// this method can also be combined with `ScriptToUniv` as they will overlap
void ScriptPubKeyToUniv(const CScript& scriptPubKey,
UniValue& out, bool fIncludeHex)
UniValue& out, bool fIncludeHex, bool include_addresses)
{
TxoutType type;
CTxDestination address;
std::vector<CTxDestination> addresses;
int nRequired;

Expand All @@ -182,17 +185,22 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey,
return;
}

out.pushKV("reqSigs", nRequired);
if (ExtractDestination(scriptPubKey, address)) {
out.pushKV("address", EncodeDestination(address));
}
out.pushKV("type", GetTxnOutputType(type));

UniValue a(UniValue::VARR);
for (const CTxDestination& addr : addresses) {
a.push_back(EncodeDestination(addr));
if (include_addresses) {
UniValue a(UniValue::VARR);
for (const CTxDestination& addr : addresses) {
a.push_back(EncodeDestination(addr));
}
out.pushKV("addresses", a);
out.pushKV("reqSigs", nRequired);
}
out.pushKV("addresses", a);
}

void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex, const CSpentIndexTxInfo* ptxSpentInfo, const CTxUndo* txundo)
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, bool include_addresses, UniValue& entry, bool include_hex, const CTxUndo* txundo, const CSpentIndexTxInfo* ptxSpentInfo)
{
uint256 txid = tx.GetHash();
entry.pushKV("txid", txid.GetHex());
Expand Down Expand Up @@ -260,7 +268,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
out.pushKV("n", (int64_t)i);

UniValue o(UniValue::VOBJ);
ScriptPubKeyToUniv(txout.scriptPubKey, o, true);
ScriptPubKeyToUniv(txout.scriptPubKey, o, true, include_addresses);
out.pushKV("scriptPubKey", o);

// Add spent information if spentindex is enabled
Expand Down
34 changes: 34 additions & 0 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ class PeerManagerImpl final : public PeerManager

/** Implement PeerManager */
void CheckForStaleTipAndEvictPeers() override;
std::optional<std::string> FetchBlock(NodeId peer_id, const CBlockIndex& block_index) override;
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
bool IgnoresIncomingTxs() override { return m_ignore_incoming_txs; }
void SendPings() override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);;
Expand Down Expand Up @@ -1862,6 +1863,39 @@ bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex* pindex)
(GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, m_chainparams.GetConsensus()) < STALE_RELAY_AGE_LIMIT);
}

std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const CBlockIndex& block_index)
{
if (fImporting) return "Importing...";
if (fReindex) return "Reindexing...";

LOCK(cs_main);
// Ensure this peer exists and hasn't been disconnected
CNodeState* state = State(peer_id);
if (state == nullptr) return "Peer does not exist";

// Mark block as in-flight unless it already is (for this peer).
// If a block was already in-flight for a different peer, its BLOCKTXN
// response will be dropped.
const uint256& hash{block_index.GetBlockHash()};
if (!MarkBlockAsInFlight(peer_id, hash, &block_index)) return "Already requested from this peer";

// Construct message to request the block
std::vector<CInv> invs{CInv(MSG_BLOCK, hash)};

// Send block request message to the peer
bool success = m_connman.ForNode(peer_id, [this, &invs](CNode* node) {
const CNetMsgMaker msgMaker(node->GetCommonVersion());
this->m_connman.PushMessage(node, msgMaker.Make(NetMsgType::GETDATA, invs));
return true;
});

if (!success) return "Peer not fully connected";

LogPrint(BCLog::NET, "Requesting block %s from peer=%d\n",
hash.ToString(), peer_id);
return std::nullopt;
}

std::unique_ptr<PeerManager> PeerManager::make(const CChainParams& chainparams, CConnman& connman, AddrMan& addrman, BanMan* banman,
CScheduler &scheduler, ChainstateManager& chainman, CTxMemPool& pool,
CMasternodeMetaMan& mn_metaman, CMasternodeSync& mn_sync,
Expand Down
9 changes: 9 additions & 0 deletions src/net_processing.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ class PeerManager : public CValidationInterface, public NetEventsInterface
const std::unique_ptr<LLMQContext>& llmq_ctx, bool ignore_incoming_txs);
virtual ~PeerManager() { }

/**
* Attempt to manually fetch block from a given peer. We must already have the header.
*
* @param[in] peer_id The peer id
* @param[in] block_index The blockindex
* @returns std::nullopt if a request was successfully made, otherwise an error message
*/
virtual std::optional<std::string> FetchBlock(NodeId peer_id, const CBlockIndex& block_index) = 0;

/** Get statistics from node state */
virtual bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const = 0;

Expand Down
1 change: 1 addition & 0 deletions src/rest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <rpc/blockchain.h>
#include <rpc/protocol.h>
#include <rpc/server.h>
#include <rpc/server_util.h>
#include <streams.h>
#include <sync.h>
#include <txmempool.h>
Expand Down
Loading

0 comments on commit 37e026a

Please sign in to comment.