Add 'invalidateblock' and 'reconsiderblock' RPC commands.
These can be used for testing reorganizations or for manual intervention in case of chain forks.
This commit is contained in:
@@ -561,3 +561,79 @@ Value getmempoolinfo(const Array& params, bool fHelp)
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user