mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-14 12:43:40 +02:00
Merge 250c8e59d5 into merged_master (Elements PR ElementsProject/elements#1030)
This commit is contained in:
commit
e4c9cc06dc
10 changed files with 164 additions and 199 deletions
101
src/init.cpp
101
src/init.cpp
|
|
@ -603,7 +603,6 @@ void SetupServerArgs(ArgsManager& argsman)
|
|||
argsman.AddArg("-mainchainrpccookiefile=<file>", "The bitcoind cookie auth path which the daemon will use to connect to the trusted mainchain daemon to validate peg-ins. (default: `<datadir>/regtest/.cookie`)", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS);
|
||||
argsman.AddArg("-mainchainrpctimeout=<n>", strprintf("Timeout in seconds during mainchain RPC requests, or 0 for no timeout. (default: %d)", DEFAULT_HTTP_CLIENT_TIMEOUT), ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS);
|
||||
argsman.AddArg("-peginconfirmationdepth=<n>", strprintf("Pegin claims must be this deep to be considered valid. (default: %d)", DEFAULT_PEGIN_CONFIRMATION_DEPTH), ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS);
|
||||
argsman.AddArg("-recheckpeginblockinterval=<n>", strprintf("The interval in seconds at which a peg-in witness failing block is re-evaluated in case of intermittent peg-in witness failure. 0 means never. (default: %u)", 120), ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS);
|
||||
argsman.AddArg("-parentpubkeyprefix", strprintf("The byte prefix, in decimal, of the parent chain's base58 pubkey address. (default: %d)", 111), ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-parentscriptprefix", strprintf("The byte prefix, in decimal, of the parent chain's base58 script address. (default: %d)", 196), ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-parent_bech32_hrp", strprintf("The human-readable part of the parent chain's bech32 encoding. (default: %s)", "bc"), ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
||||
|
|
@ -1101,6 +1100,61 @@ bool AppInitLockDataDirectory()
|
|||
return true;
|
||||
}
|
||||
|
||||
/* This function checks that the RPC connection to the parent chain node
|
||||
* can be attained, and is returning back reasonable answers.
|
||||
*/
|
||||
bool MainchainRPCCheck()
|
||||
{
|
||||
// Check for working and valid rpc
|
||||
// Retry until a non-RPC_IN_WARMUP result
|
||||
while (true) {
|
||||
try {
|
||||
// The first thing we have to check is the version of the node.
|
||||
UniValue params(UniValue::VARR);
|
||||
UniValue reply = CallMainChainRPC("getnetworkinfo", params);
|
||||
UniValue error = reply["error"];
|
||||
if (!error.isNull()) {
|
||||
// On the first call, it's possible to node is still in
|
||||
// warmup; in that case, just wait and retry.
|
||||
if (error["code"].get_int() == RPC_IN_WARMUP) {
|
||||
UninterruptibleSleep(std::chrono::milliseconds{1000});
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
LogPrintf("ERROR: Mainchain daemon RPC check returned 'error' response.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
UniValue result = reply["result"];
|
||||
if (!result.isObject() || !result.get_obj()["version"].isNum() ||
|
||||
result.get_obj()["version"].get_int() < MIN_MAINCHAIN_NODE_VERSION) {
|
||||
LogPrintf("ERROR: Parent chain daemon too old; need Bitcoin Core version 0.16.3 or newer.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Then check the genesis block to correspond to parent chain.
|
||||
params.push_back(UniValue(0));
|
||||
reply = CallMainChainRPC("getblockhash", params);
|
||||
error = reply["error"];
|
||||
if (!error.isNull()) {
|
||||
LogPrintf("ERROR: Mainchain daemon RPC check returned 'error' response.\n");
|
||||
return false;
|
||||
}
|
||||
result = reply["result"];
|
||||
if (!result.isStr() || result.get_str() != Params().ParentGenesisBlockHash().GetHex()) {
|
||||
LogPrintf("ERROR: Invalid parent genesis block hash response via RPC. Contacting wrong parent daemon?\n");
|
||||
return false;
|
||||
}
|
||||
} catch (const std::runtime_error& re) {
|
||||
LogPrintf("ERROR: Failure connecting to mainchain daemon RPC: %s\n", std::string(re.what()));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool AppInitInterfaces(NodeContext& node)
|
||||
{
|
||||
node.chain = interfaces::MakeChain(node);
|
||||
|
|
@ -1857,28 +1911,35 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
// ELEMENTS:
|
||||
if (gArgs.GetBoolArg("-validatepegin", Params().GetConsensus().has_parent_chain)) {
|
||||
uiInterface.InitMessage(_("Awaiting mainchain RPC warmup").translated);
|
||||
}
|
||||
if (!MainchainRPCCheck(true, node.chainman.get())) { //Initial check only
|
||||
const std::string err_msg = "ERROR: elements is set to verify pegins but cannot get a valid response from the mainchain daemon. Please check debug.log for more information.\n\nIf you haven't setup a bitcoind please get the latest stable version from https://bitcoincore.org/en/download/ or if you do not need to validate pegins set in your elements configuration validatepegin=0";
|
||||
// We fail immediately if this node has RPC server enabled
|
||||
if (gArgs.GetBoolArg("-server", false)) {
|
||||
InitError(Untranslated(err_msg));
|
||||
return false;
|
||||
} else {
|
||||
// Or gently warn the user, and continue
|
||||
InitError(Untranslated(err_msg));
|
||||
gArgs.SoftSetArg("-validatepegin", "0");
|
||||
if (!MainchainRPCCheck()) {
|
||||
const std::string err_msg = "ERROR: elements is set to verify pegins but cannot get a valid response from the mainchain daemon. Please check debug.log for more information.\n\nIf you haven't setup a bitcoind please get the latest stable version from https://bitcoincore.org/en/download/ or if you do not need to validate pegins set in your elements configuration validatepegin=0";
|
||||
// We fail immediately if this node has RPC server enabled
|
||||
if (gArgs.GetBoolArg("-server", false)) {
|
||||
InitError(Untranslated(err_msg));
|
||||
return false;
|
||||
} else {
|
||||
// Or gently warn the user, and continue
|
||||
InitError(Untranslated(err_msg));
|
||||
gArgs.SoftSetArg("-validatepegin", "0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start the lightweight block re-evaluation scheduler thread
|
||||
node.reverification_scheduler->m_service_thread = std::thread([&] { util::TraceThread( "reevaluation_scheduler", [&] { node.reverification_scheduler->serviceQueue(); }); });
|
||||
|
||||
CScheduler::Function f2 = std::bind(&MainchainRPCCheck, false, node.chainman.get());
|
||||
unsigned int check_rpc_every = gArgs.GetArg("-recheckpeginblockinterval", 120);
|
||||
if (check_rpc_every) {
|
||||
node.reverification_scheduler->scheduleEvery(f2, std::chrono::seconds(check_rpc_every));
|
||||
}
|
||||
// Call ActivateBestChain every 30 seconds. This is almost always a
|
||||
// harmless no-op. It is necessary in the unusual case where:
|
||||
// (1) Our connection to bitcoind is lost, and
|
||||
// (2) we build up a queue of blocks to validate in the meantime, and then
|
||||
// (3) our connection to bitcoind is restored, but
|
||||
// (4) nothing after that causes ActivateBestChain to be called, including
|
||||
// no further blocks arriving for us to validate.
|
||||
// Unfortunately, this unusual case happens in the functional test suite.
|
||||
ChainstateManager *pchainman = node.chainman.get();
|
||||
node.reverification_scheduler->scheduleEvery([pchainman]{
|
||||
BlockValidationState state;
|
||||
if (!pchainman->ActiveChainstate().ActivateBestChain(state)) {
|
||||
LogPrintf("Failed to periodically activate best chain (%s)\n", state.ToString());
|
||||
}
|
||||
}, std::chrono::seconds{30});
|
||||
|
||||
uiInterface.InitMessage(_("Done loading").translated);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue