Skip to content

Commit fbaee1f

Browse files
Merge branch 'develop' of https://github.com/dashpay/dash into develop
2 parents 16fcf0a + 65366a4 commit fbaee1f

12 files changed

Lines changed: 181 additions & 123 deletions

doc/release-notes-7099.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Updated RPCs
2+
------------
3+
4+
* Dash RPCs will no longer permit submitting strings to boolean input fields in line with validation
5+
enforced on upstream RPCs, where this is already the case. Requests must now use unquoted `true`
6+
or `false`.
7+
8+
* The following RPCs are affected, `bls generate`, `bls fromsecret`, `coinjoinsalt generate`,
9+
`coinjoinsalt set`, `masternode connect`, `protx diff`, `protx list`, `protx register`,
10+
`protx register_legacy`, `protx register_evo`, `protx register_fund`, `protx register_fund_legacy`,
11+
`protx register_fund_evo`, `protx revoke`, `protx update_registrar`, `protx update_registrar_legacy`,
12+
`protx update_service`, `protx update_service_evo`, `quorum info`, `quorum platformsign`,
13+
`quorum rotationinfo`, `quorum sign`.
14+
15+
* This restriction can be relaxed by setting `-deprecatedrpc=permissive_bool` at runtime
16+
but is liable to be removed in future versions of Dash Core.

src/rpc/client.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,25 +256,81 @@ static const CRPCConvertParam vRPCConvertParams[] =
256256
{ "verifyislock", 3, "maxHeight" },
257257
{ "submitchainlock", 2, "blockHeight" },
258258
{ "mnauth", 0, "nodeId" },
259+
// Compound RPCs (note: index position is offset by one to account for subcommand)
260+
{ "bls generate", 1, "legacy" },
261+
{ "bls fromsecret", 2, "legacy" },
262+
{ "coinjoinsalt generate", 1, "overwrite" },
263+
{ "coinjoinsalt set", 2, "overwrite" },
264+
{ "gobject list-prepared", 1, "count" },
265+
{ "gobject prepare", 2, "revision" },
266+
{ "gobject prepare", 3, "time" },
267+
{ "gobject prepare", 7, "outputIndex" },
268+
{ "gobject submit", 2, "revision" },
269+
{ "gobject submit", 3, "time" },
270+
{ "masternode connect", 2, "v2transport" },
271+
{ "masternode payments", 2, "count" },
272+
{ "masternode winners", 1, "count" },
273+
{ "protx diff", 3, "extended" },
274+
{ "protx list", 2, "detailed" },
275+
{ "protx list", 3, "height" },
276+
{ "protx register", 2, "collateralIndex" },
259277
{ "protx register", 3, "coreP2PAddrs", true },
278+
{ "protx register", 10, "submit" },
279+
{ "protx register_legacy", 2, "collateralIndex" },
260280
{ "protx register_legacy", 3, "coreP2PAddrs", true },
281+
{ "protx register_legacy", 10, "submit" },
282+
{ "protx register_evo", 2, "collateralIndex" },
261283
{ "protx register_evo", 3, "coreP2PAddrs", true },
262284
{ "protx register_evo", 10, "platformP2PAddrs", true },
263285
{ "protx register_evo", 11, "platformHTTPSAddrs", true },
286+
{ "protx register_evo", 13, "submit" },
264287
{ "protx register_fund", 2, "coreP2PAddrs", true },
288+
{ "protx register_fund", 9, "submit" },
265289
{ "protx register_fund_legacy", 2, "coreP2PAddrs", true },
290+
{ "protx register_fund_legacy", 9, "submit" },
266291
{ "protx register_fund_evo", 2, "coreP2PAddrs", true },
267292
{ "protx register_fund_evo", 9, "platformP2PAddrs", true },
268293
{ "protx register_fund_evo", 10, "platformHTTPSAddrs", true },
294+
{ "protx register_fund_evo", 12, "submit" },
295+
{ "protx register_prepare", 2, "collateralIndex" },
269296
{ "protx register_prepare", 3, "coreP2PAddrs", true },
297+
{ "protx register_prepare_legacy", 2, "collateralIndex" },
270298
{ "protx register_prepare_legacy", 3, "coreP2PAddrs", true },
299+
{ "protx register_prepare_evo", 2, "collateralIndex" },
271300
{ "protx register_prepare_evo", 3, "coreP2PAddrs", true },
272301
{ "protx register_prepare_evo", 10, "platformP2PAddrs", true },
273302
{ "protx register_prepare_evo", 11, "platformHTTPSAddrs", true },
303+
{ "protx revoke", 3, "reason" },
304+
{ "protx revoke", 5, "submit" },
305+
{ "protx update_registrar", 6, "submit" },
306+
{ "protx update_registrar_legacy", 6, "submit" },
274307
{ "protx update_service", 2, "coreP2PAddrs", true },
308+
{ "protx update_service", 6, "submit" },
275309
{ "protx update_service_evo", 2, "coreP2PAddrs", true },
276310
{ "protx update_service_evo", 5, "platformP2PAddrs", true },
277311
{ "protx update_service_evo", 6, "platformHTTPSAddrs", true },
312+
{ "protx update_service_evo", 9, "submit" },
313+
{ "quorum dkgsimerror", 2, "rate" },
314+
{ "quorum dkgstatus", 1, "detail_level" },
315+
{ "quorum getdata", 1, "nodeId" },
316+
{ "quorum getdata", 2, "llmqType" },
317+
{ "quorum getdata", 4, "dataMask" },
318+
{ "quorum getrecsig", 1, "llmqType" },
319+
{ "quorum hasrecsig", 1, "llmqType" },
320+
{ "quorum info", 1, "llmqType" },
321+
{ "quorum info", 3, "includeSkShare" },
322+
{ "quorum isconflicting", 1, "llmqType" },
323+
{ "quorum listextended", 1, "height" },
324+
{ "quorum list", 1, "count" },
325+
{ "quorum memberof", 2, "scanQuorumsCount" },
326+
{ "quorum platformsign", 4, "submit" },
327+
{ "quorum rotationinfo", 2, "extraShare" },
328+
{ "quorum rotationinfo", 3, "baseBlockHashes" },
329+
{ "quorum selectquorum", 1, "llmqType" },
330+
{ "quorum sign", 1, "llmqType" },
331+
{ "quorum sign", 5, "submit" },
332+
{ "quorum verify", 1, "llmqType" },
333+
{ "quorum verify", 6, "signHeight" },
278334
};
279335
// clang-format on
280336

src/rpc/evo.cpp

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ static UniValue protx_register_common_wrapper(const JSONRPCRequest& request,
713713
paramIdx++;
714714
} else {
715715
uint256 collateralHash(ParseHashV(request.params[paramIdx], "collateralHash"));
716-
int32_t collateralIndex = ParseInt32V(request.params[paramIdx + 1], "collateralIndex");
716+
int32_t collateralIndex = request.params[paramIdx + 1].getInt<int>();
717717
if (collateralHash.IsNull() || collateralIndex < 0) {
718718
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("invalid hash or index: %s-%d", collateralHash.ToString(), collateralIndex));
719719
}
@@ -1277,7 +1277,7 @@ static RPCHelpMan protx_revoke()
12771277
CBLSSecretKey keyOperator = ParseBLSSecretKey(request.params[1].get_str(), "operatorKey");
12781278

12791279
if (!request.params[2].isNull()) {
1280-
int32_t nReason = ParseInt32V(request.params[2], "reason");
1280+
int32_t nReason = request.params[2].getInt<int>();
12811281
if (nReason < 0 || nReason > CProUpRevTx::REASON_LAST) {
12821282
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("invalid reason %d, must be between 0 and %d", nReason, CProUpRevTx::REASON_LAST));
12831283
}
@@ -1462,7 +1462,7 @@ static RPCHelpMan protx_list()
14621462
bool detailed = !request.params[1].isNull() ? ParseBoolV(request.params[1], "detailed") : false;
14631463

14641464
LOCK2(wallet->cs_wallet, ::cs_main);
1465-
int height = !request.params[2].isNull() ? ParseInt32V(request.params[2], "height") : chainman.ActiveChain().Height();
1465+
int height = !request.params[2].isNull() ? request.params[2].getInt<int>() : chainman.ActiveChain().Height();
14661466
if (height < 1 || height > chainman.ActiveChain().Height()) {
14671467
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid height specified");
14681468
}
@@ -1495,7 +1495,7 @@ static RPCHelpMan protx_list()
14951495
#else
14961496
LOCK(::cs_main);
14971497
#endif
1498-
int height = !request.params[2].isNull() ? ParseInt32V(request.params[2], "height") : chainman.ActiveChain().Height();
1498+
int height = !request.params[2].isNull() ? request.params[2].getInt<int>() : chainman.ActiveChain().Height();
14991499
if (height < 1 || height > chainman.ActiveChain().Height()) {
15001500
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid height specified");
15011501
}
@@ -1587,20 +1587,43 @@ static uint256 ParseBlock(const UniValue& v, const ChainstateManager& chainman,
15871587
try {
15881588
return ParseHashV(v, strName);
15891589
} catch (...) {
1590-
int h = ParseInt32V(v, strName);
1591-
if (h < 1 || h > chainman.ActiveChain().Height())
1590+
bool fail{false}; int32_t h{0};
1591+
if (v.isNum()) {
1592+
h = v.getInt<int>();
1593+
} else if (!ParseInt32(v.get_str(), &h)) {
1594+
fail = true;
1595+
}
1596+
if (fail || h < 1 || h > chainman.ActiveChain().Height()) {
15921597
throw std::runtime_error(strprintf("%s must be a block hash or chain height and not %s", strName, v.getValStr()));
1598+
}
15931599
return *chainman.ActiveChain()[h]->phashBlock;
15941600
}
15951601
}
15961602

1603+
static const CBlockIndex* ParseBlockIndex(const UniValue& v, const ChainstateManager& chainman, const std::string& strName) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
1604+
{
1605+
AssertLockHeld(::cs_main);
1606+
1607+
try {
1608+
const auto hash{ParseBlock(v, chainman, strName)};
1609+
const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(hash);
1610+
if (!pindex) {
1611+
throw std::runtime_error(strprintf("Block %s with hash %s not found", strName, v.getValStr()));
1612+
}
1613+
return pindex;
1614+
} catch (...) {
1615+
// Same phrasing as ParseBlock() as it can parse heights
1616+
throw std::runtime_error(strprintf("%s must be a block hash or chain height and not %s", strName, v.getValStr()));
1617+
}
1618+
}
1619+
15971620
static RPCHelpMan protx_diff()
15981621
{
15991622
return RPCHelpMan{"protx diff",
16001623
"\nCalculates a diff between two deterministic masternode lists. The result also contains proof data.\n",
16011624
{
1602-
{"baseBlock", RPCArg::Type::NUM, RPCArg::Optional::NO, "The starting block height."},
1603-
{"block", RPCArg::Type::NUM, RPCArg::Optional::NO, "The ending block height."},
1625+
{"baseBlock", RPCArg::Type::STR, RPCArg::Optional::NO, "The starting block hash or height."},
1626+
{"block", RPCArg::Type::STR, RPCArg::Optional::NO, "The ending block hash or height."},
16041627
{"extended", RPCArg::Type::BOOL, RPCArg::Optional::OMITTED, "Show additional fields."},
16051628
},
16061629
CSimplifiedMNListDiff::GetJsonHelp(/*key=*/"", /*optional=*/false),
@@ -1635,31 +1658,13 @@ static RPCHelpMan protx_diff()
16351658
};
16361659
}
16371660

1638-
static const CBlockIndex* ParseBlockIndex(const UniValue& v, const ChainstateManager& chainman, const std::string& strName) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
1639-
{
1640-
AssertLockHeld(::cs_main);
1641-
1642-
try {
1643-
uint256 hash = ParseHashV(v, strName);
1644-
const CBlockIndex* pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
1645-
if (!pblockindex)
1646-
throw std::runtime_error(strprintf("Block %s with hash %s not found", strName, v.getValStr()));
1647-
return pblockindex;
1648-
} catch (...) {
1649-
int h = ParseInt32V(v, strName);
1650-
if (h < 1 || h > chainman.ActiveChain().Height())
1651-
throw std::runtime_error(strprintf("%s must be a chain height and not %s", strName, v.getValStr()));
1652-
return chainman.ActiveChain()[h];
1653-
}
1654-
}
1655-
16561661
static RPCHelpMan protx_listdiff()
16571662
{
16581663
return RPCHelpMan{"protx listdiff",
16591664
"\nCalculate a full MN list diff between two masternode lists.\n",
16601665
{
1661-
{"baseBlock", RPCArg::Type::NUM, RPCArg::Optional::NO, "The starting block height."},
1662-
{"block", RPCArg::Type::NUM, RPCArg::Optional::NO, "The ending block height."},
1666+
{"baseBlock", RPCArg::Type::STR, RPCArg::Optional::NO, "The starting block hash or height."},
1667+
{"block", RPCArg::Type::STR, RPCArg::Optional::NO, "The ending block hash or height."},
16631668
},
16641669
RPCResult {
16651670
RPCResult::Type::OBJ, "", "",
@@ -1834,8 +1839,8 @@ static RPCHelpMan evodb_verify()
18341839
"This is a read-only operation that does not modify the database.\n"
18351840
"If no heights are specified, defaults to the full range from DIP0003 activation to chain tip.\n",
18361841
{
1837-
{"startBlock", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The starting block height (defaults to DIP0003 activation height)."},
1838-
{"stopBlock", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The ending block height (defaults to current chain tip)."},
1842+
{"startBlock", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "The starting block hash or height (defaults to DIP0003 activation height)."},
1843+
{"stopBlock", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "The ending block hash or height (defaults to current chain tip)."},
18391844
},
18401845
RPCResult{
18411846
RPCResult::Type::OBJ, "", "",
@@ -1872,8 +1877,8 @@ static RPCHelpMan evodb_repair()
18721877
"If verification fails, recalculates diffs from blockchain data and replaces corrupted records.\n"
18731878
"If no heights are specified, defaults to the full range from DIP0003 activation to chain tip.\n",
18741879
{
1875-
{"startBlock", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The starting block height (defaults to DIP0003 activation height)."},
1876-
{"stopBlock", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The ending block height (defaults to current chain tip)."},
1880+
{"startBlock", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "The starting block hash or height (defaults to DIP0003 activation height)."},
1881+
{"stopBlock", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "The ending block hash or height (defaults to current chain tip)."},
18771882
},
18781883
RPCResult{
18791884
RPCResult::Type::OBJ, "", "",

src/rpc/governance.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ static RPCHelpMan gobject_prepare()
176176
hashParent = ParseHashV(request.params[0], "parent-hash");
177177
}
178178

179-
int nRevision = ParseInt32V(request.params[1], "revision");
180-
int64_t nTime = ParseInt64V(request.params[2], "time");
179+
int nRevision = request.params[1].getInt<int>();
180+
int64_t nTime = request.params[2].getInt<int64_t>();
181181
std::string strDataHex = request.params[3].get_str();
182182

183183
// CREATE A NEW COLLATERAL TRANSACTION FOR THIS SPECIFIC OBJECT
@@ -225,7 +225,7 @@ static RPCHelpMan gobject_prepare()
225225
outpoint.SetNull();
226226
if (!request.params[5].isNull() && !request.params[6].isNull()) {
227227
uint256 collateralHash(ParseHashV(request.params[5], "outputHash"));
228-
int32_t collateralIndex = ParseInt32V(request.params[6], "outputIndex");
228+
int32_t collateralIndex = request.params[6].getInt<int>();
229229
if (collateralHash.IsNull() || collateralIndex < 0) {
230230
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("invalid hash or index: %s-%d", collateralHash.ToString(), collateralIndex));
231231
}
@@ -278,7 +278,7 @@ static RPCHelpMan gobject_list_prepared()
278278
if (!wallet) return UniValue::VNULL;
279279
EnsureWalletIsUnlocked(*wallet);
280280

281-
int64_t nCount = request.params.empty() ? 10 : ParseInt64V(request.params[0], "count");
281+
int64_t nCount = request.params.empty() ? 10 : request.params[0].getInt<int64_t>();
282282
if (nCount < 0) {
283283
throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
284284
}
@@ -361,8 +361,8 @@ static RPCHelpMan gobject_submit()
361361

362362
// GET THE PARAMETERS FROM USER
363363

364-
int nRevision = ParseInt32V(request.params[1], "revision");
365-
int64_t nTime = ParseInt64V(request.params[2], "time");
364+
int nRevision = request.params[1].getInt<int>();
365+
int64_t nTime = request.params[2].getInt<int64_t>();
366366
std::string strDataHex = request.params[3].get_str();
367367

368368
CGovernanceObject govobj(hashParent, nRevision, nTime, txidFee, strDataHex);

src/rpc/masternode.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ static RPCHelpMan masternode_winners()
288288
std::string strFilter;
289289

290290
if (!request.params[0].isNull()) {
291-
nCount = LocaleIndependentAtoi<int>(request.params[0].get_str());
291+
nCount = request.params[0].getInt<int>();
292292
}
293293

294294
if (!request.params[1].isNull()) {
@@ -378,7 +378,7 @@ static RPCHelpMan masternode_payments()
378378
}
379379
}
380380

381-
int64_t nCount = request.params.size() > 1 ? ParseInt64V(request.params[1], "count") : 1;
381+
int64_t nCount = request.params.size() > 1 ? request.params[1].getInt<int64_t>() : 1;
382382

383383
// A temporary vector which is used to sort results properly (there is no "reverse" in/for UniValue)
384384
std::vector<UniValue> vecPayments;

0 commit comments

Comments
 (0)