mirror of
https://github.com/dashpay/dash.git
synced 2024-12-27 21:12:48 +01:00
Merge pull request #5316
f86a24b
Move `setmocktime` to hidden category (Wladimir J. van der Laan)bd9aebf
Introduce a hidden category (Pieter Wuille)0dd06b2
Delay writing block indexes in invalidate/reconsider (Pieter Wuille)9b0a8d3
Add 'invalidateblock' and 'reconsiderblock' RPC commands. (Pieter Wuille)
This commit is contained in:
commit
d7c8a830c4
67
src/main.cpp
67
src/main.cpp
@ -2135,6 +2135,73 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
|
||||||
|
AssertLockHeld(cs_main);
|
||||||
|
|
||||||
|
// Mark the block itself as invalid.
|
||||||
|
pindex->nStatus |= BLOCK_FAILED_VALID;
|
||||||
|
setDirtyBlockIndex.insert(pindex);
|
||||||
|
setBlockIndexCandidates.erase(pindex);
|
||||||
|
|
||||||
|
while (chainActive.Contains(pindex)) {
|
||||||
|
CBlockIndex *pindexWalk = chainActive.Tip();
|
||||||
|
pindexWalk->nStatus |= BLOCK_FAILED_CHILD;
|
||||||
|
setDirtyBlockIndex.insert(pindexWalk);
|
||||||
|
setBlockIndexCandidates.erase(pindexWalk);
|
||||||
|
// ActivateBestChain considers blocks already in chainActive
|
||||||
|
// unconditionally valid already, so force disconnect away from it.
|
||||||
|
if (!DisconnectTip(state)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The resulting new best tip may not be in setBlockIndexCandidates anymore, so
|
||||||
|
// add them again.
|
||||||
|
BlockMap::iterator it = mapBlockIndex.begin();
|
||||||
|
while (it != mapBlockIndex.end()) {
|
||||||
|
if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
|
||||||
|
setBlockIndexCandidates.insert(pindex);
|
||||||
|
}
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
|
||||||
|
InvalidChainFound(pindex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex) {
|
||||||
|
AssertLockHeld(cs_main);
|
||||||
|
|
||||||
|
int nHeight = pindex->nHeight;
|
||||||
|
|
||||||
|
// Remove the invalidity flag from this block and all its descendants.
|
||||||
|
BlockMap::iterator it = mapBlockIndex.begin();
|
||||||
|
while (it != mapBlockIndex.end()) {
|
||||||
|
if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
|
||||||
|
it->second->nStatus &= ~BLOCK_FAILED_MASK;
|
||||||
|
setDirtyBlockIndex.insert(it->second);
|
||||||
|
if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
|
||||||
|
setBlockIndexCandidates.insert(it->second);
|
||||||
|
}
|
||||||
|
if (it->second == pindexBestInvalid) {
|
||||||
|
// Reset invalid block marker if it was pointing to one of those.
|
||||||
|
pindexBestInvalid = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the invalidity flag from all ancestors too.
|
||||||
|
while (pindex != NULL) {
|
||||||
|
if (pindex->nStatus & BLOCK_FAILED_MASK) {
|
||||||
|
pindex->nStatus &= ~BLOCK_FAILED_MASK;
|
||||||
|
setDirtyBlockIndex.insert(pindex);
|
||||||
|
}
|
||||||
|
pindex = pindex->pprev;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
|
CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
|
||||||
{
|
{
|
||||||
// Check for duplicate
|
// Check for duplicate
|
||||||
|
@ -607,6 +607,12 @@ public:
|
|||||||
/** Find the last common block between the parameter chain and a locator. */
|
/** Find the last common block between the parameter chain and a locator. */
|
||||||
CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator);
|
CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator);
|
||||||
|
|
||||||
|
/** Mark a block as invalid. */
|
||||||
|
bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex);
|
||||||
|
|
||||||
|
/** Remove invalidity status from a block and its descendants. */
|
||||||
|
bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex);
|
||||||
|
|
||||||
/** The currently-connected chain of blocks. */
|
/** The currently-connected chain of blocks. */
|
||||||
extern CChain chainActive;
|
extern CChain chainActive;
|
||||||
|
|
||||||
|
@ -561,3 +561,79 @@ Value getmempoolinfo(const Array& params, bool fHelp)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value invalidateblock(const Array& params, bool fHelp)
|
||||||
|
{
|
||||||
|
if (fHelp || params.size() != 1)
|
||||||
|
throw runtime_error(
|
||||||
|
"invalidateblock \"hash\"\n"
|
||||||
|
"\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
|
||||||
|
"\nArguments:\n"
|
||||||
|
"1. hash (string, required) the hash of the block to mark as invalid\n"
|
||||||
|
"\nResult:\n"
|
||||||
|
"\nExamples:\n"
|
||||||
|
+ HelpExampleCli("invalidateblock", "\"blockhash\"")
|
||||||
|
+ HelpExampleRpc("invalidateblock", "\"blockhash\"")
|
||||||
|
);
|
||||||
|
|
||||||
|
std::string strHash = params[0].get_str();
|
||||||
|
uint256 hash(strHash);
|
||||||
|
CValidationState state;
|
||||||
|
|
||||||
|
{
|
||||||
|
LOCK(cs_main);
|
||||||
|
if (mapBlockIndex.count(hash) == 0)
|
||||||
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||||
|
|
||||||
|
CBlockIndex* pblockindex = mapBlockIndex[hash];
|
||||||
|
InvalidateBlock(state, pblockindex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.IsValid()) {
|
||||||
|
ActivateBestChain(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state.IsValid()) {
|
||||||
|
throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Value::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value reconsiderblock(const Array& params, bool fHelp)
|
||||||
|
{
|
||||||
|
if (fHelp || params.size() != 1)
|
||||||
|
throw runtime_error(
|
||||||
|
"reconsiderblock \"hash\"\n"
|
||||||
|
"\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
|
||||||
|
"This can be used to undo the effects of invalidateblock.\n"
|
||||||
|
"\nArguments:\n"
|
||||||
|
"1. hash (string, required) the hash of the block to reconsider\n"
|
||||||
|
"\nResult:\n"
|
||||||
|
"\nExamples:\n"
|
||||||
|
+ HelpExampleCli("reconsiderblock", "\"blockhash\"")
|
||||||
|
+ HelpExampleRpc("reconsiderblock", "\"blockhash\"")
|
||||||
|
);
|
||||||
|
|
||||||
|
std::string strHash = params[0].get_str();
|
||||||
|
uint256 hash(strHash);
|
||||||
|
CValidationState state;
|
||||||
|
|
||||||
|
{
|
||||||
|
LOCK(cs_main);
|
||||||
|
if (mapBlockIndex.count(hash) == 0)
|
||||||
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||||
|
|
||||||
|
CBlockIndex* pblockindex = mapBlockIndex[hash];
|
||||||
|
ReconsiderBlock(state, pblockindex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.IsValid()) {
|
||||||
|
ActivateBestChain(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state.IsValid()) {
|
||||||
|
throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Value::null;
|
||||||
|
}
|
||||||
|
@ -160,7 +160,7 @@ string CRPCTable::help(string strCommand) const
|
|||||||
// We already filter duplicates, but these deprecated screw up the sort order
|
// We already filter duplicates, but these deprecated screw up the sort order
|
||||||
if (strMethod.find("label") != string::npos)
|
if (strMethod.find("label") != string::npos)
|
||||||
continue;
|
continue;
|
||||||
if (strCommand != "" && strMethod != strCommand)
|
if ((strCommand != "" || pcmd->category == "hidden") && strMethod != strCommand)
|
||||||
continue;
|
continue;
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
if (pcmd->reqWallet && !pwalletMain)
|
if (pcmd->reqWallet && !pwalletMain)
|
||||||
@ -246,7 +246,6 @@ static const CRPCCommand vRPCCommands[] =
|
|||||||
{ "control", "getinfo", &getinfo, true, false, false }, /* uses wallet if enabled */
|
{ "control", "getinfo", &getinfo, true, false, false }, /* uses wallet if enabled */
|
||||||
{ "control", "help", &help, true, true, false },
|
{ "control", "help", &help, true, true, false },
|
||||||
{ "control", "stop", &stop, true, true, false },
|
{ "control", "stop", &stop, true, true, false },
|
||||||
{ "control", "setmocktime", &setmocktime, true, false, false },
|
|
||||||
|
|
||||||
/* P2P networking */
|
/* P2P networking */
|
||||||
{ "network", "getnetworkinfo", &getnetworkinfo, true, false, false },
|
{ "network", "getnetworkinfo", &getnetworkinfo, true, false, false },
|
||||||
@ -300,6 +299,11 @@ static const CRPCCommand vRPCCommands[] =
|
|||||||
{ "util", "estimatefee", &estimatefee, true, true, false },
|
{ "util", "estimatefee", &estimatefee, true, true, false },
|
||||||
{ "util", "estimatepriority", &estimatepriority, true, true, false },
|
{ "util", "estimatepriority", &estimatepriority, true, true, false },
|
||||||
|
|
||||||
|
/* Not shown in help */
|
||||||
|
{ "hidden", "invalidateblock", &invalidateblock, true, true, false },
|
||||||
|
{ "hidden", "reconsiderblock", &reconsiderblock, true, true, false },
|
||||||
|
{ "hidden", "setmocktime", &setmocktime, true, false, false },
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
/* Wallet */
|
/* Wallet */
|
||||||
{ "wallet", "addmultisigaddress", &addmultisigaddress, true, false, true },
|
{ "wallet", "addmultisigaddress", &addmultisigaddress, true, false, true },
|
||||||
|
@ -222,6 +222,8 @@ extern json_spirit::Value gettxoutsetinfo(const json_spirit::Array& params, bool
|
|||||||
extern json_spirit::Value gettxout(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value gettxout(const json_spirit::Array& params, bool fHelp);
|
||||||
extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHelp);
|
||||||
extern json_spirit::Value getchaintips(const json_spirit::Array& params, bool fHelp);
|
extern json_spirit::Value getchaintips(const json_spirit::Array& params, bool fHelp);
|
||||||
|
extern json_spirit::Value invalidateblock(const json_spirit::Array& params, bool fHelp);
|
||||||
|
extern json_spirit::Value reconsiderblock(const json_spirit::Array& params, bool fHelp);
|
||||||
|
|
||||||
// in rest.cpp
|
// in rest.cpp
|
||||||
extern bool HTTPReq_REST(AcceptedConnection *conn,
|
extern bool HTTPReq_REST(AcceptedConnection *conn,
|
||||||
|
Loading…
Reference in New Issue
Block a user