Skip to content

Commit 138d55a

Browse files
committed
Merge #425: peg-in re-checking cleanup and fixes
abb7b01 Add some additional comments about BitcoindRPCCheck infra (Gregory Sanders) 62c56f4 don't set CorruptionPossible for peg-in transaction failure (Gregory Sanders) 5d7cd6b parameterize the rpc re-checking of peg-in validation failed blocks (Gregory Sanders) ba8d498 bitcoind rpc check should take main locks for mapBlockIndex, check for key (Gregory Sanders)
2 parents 3634aaf + abb7b01 commit 138d55a

File tree

3 files changed

+33
-12
lines changed

3 files changed

+33
-12
lines changed

qa/rpc-tests/feature_fedpeg.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ def setup_network(self, split=False):
9797
'-peginconfirmationdepth=10',
9898
'-mainchainrpchost=127.0.0.1',
9999
'-mainchainrpcport=%s' % rpc_port(n),
100+
'-recheckpeginblockinterval=15', # Long enough to allow failure and repair before timeout
100101
]
101102
if not self.options.parent_bitcoin:
102103
args.extend([
@@ -319,12 +320,13 @@ def run_test(self):
319320
self.nodes[1] = start_node(1, self.options.tmpdir, self.extra_args[1], binary=self.binary, chain=self.parent_chain, cookie_auth=True)
320321
parent2 = self.nodes[1]
321322
connect_nodes_bi(self.nodes, 0, 1)
322-
time.sleep(5)
323323

324324
# Don't make a block, race condition when pegin-invalid block
325325
# is awaiting further validation, nodes reject subsequent blocks
326326
# even ones they create
327+
print("Now waiting for node to re-evaluate peg-in witness failed block... should take a few seconds")
327328
self.sync_all()
329+
print("Completed!\n")
328330
print("Now send funds out in two stages, partial, and full")
329331
some_btc_addr = get_new_unconfidential_address(parent)
330332
bal_1 = sidechain.getwalletinfo()["balance"]["bitcoin"]

src/init.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,7 @@ std::string HelpMessage(HelpMessageMode mode)
520520
strUsage += HelpMessageOpt("-parentscriptprefix", strprintf(_("The byte prefix, in decimal, of the parent chain's base58 script address. (default: %d)"), 196));
521521
strUsage += HelpMessageOpt("-con_parent_chain_signblockscript", _("Whether parent chain uses pow or signed blocks. If the parent chain uses signed blocks, the challenge (scriptPubKey) script. If not, an empty string. (default: empty script [ie parent uses pow])"));
522522
strUsage += HelpMessageOpt("-con_parent_pegged_asset=<hex>", _("Asset ID (hex) for pegged asset for when parent chain has CA. (default: 0x00)"));
523+
strUsage += HelpMessageOpt("-recheckpeginblockinterval", strprintf(_("The interval in seconds at which a peg-in witness failing block is re-evaluated in case of intermittant peg-in witness failure. 0 means never. (default: %u)"), 120));
523524
}
524525
strUsage += HelpMessageOpt("-validatepegin", strprintf(_("Validate peg-in claims. An RPC connection will be attempted to the trusted bitcoind using the `mainchain*` settings below. All functionaries must run this enabled. (default: %u)"), DEFAULT_VALIDATE_PEGIN));
525526
strUsage += HelpMessageOpt("-mainchainrpchost=<addr>", strprintf("The address which the daemon will try to connect to the trusted bitcoind to validate peg-ins, if enabled. (default: cookie auth)"));
@@ -1691,7 +1692,10 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
16911692
SetRPCWarmupFinished();
16921693

16931694
CScheduler::Function f2 = boost::bind(&BitcoindRPCCheck, false);
1694-
scheduler.scheduleEvery(f2, 120);
1695+
unsigned int check_rpc_every = GetArg("-recheckpeginblockinterval", 120);
1696+
if (check_rpc_every) {
1697+
scheduler.scheduleEvery(f2, check_rpc_every);
1698+
}
16951699

16961700
uiInterface.InitMessage(_("Awaiting bitcoind RPC warmup"));
16971701

src/validation.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1870,7 +1870,7 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins
18701870
if (tx.vin[i].m_is_pegin) {
18711871
// Check existence and validity of pegin witness
18721872
if (tx.wit.vtxinwit.size() <= i || !IsValidPeginWitness(tx.wit.vtxinwit[i].m_pegin_witness, prevout)) {
1873-
return state.DoS(0, false, REJECT_PEGIN, "bad-pegin-witness", true);
1873+
return state.DoS(0, false, REJECT_PEGIN, "bad-pegin-witness");
18741874
}
18751875
std::pair<uint256, COutPoint> pegin = std::make_pair(uint256(tx.wit.vtxinwit[i].m_pegin_witness.stack[2]), prevout);
18761876
if (inputs.IsWithdrawSpent(pegin)) {
@@ -2212,6 +2212,13 @@ void ThreadScriptCheck() {
22122212
scriptcheckqueue.Thread();
22132213
}
22142214

2215+
/* This function has two major purposes:
2216+
* 1) Checks that the RPC connection to the parent chain node
2217+
* can be attained, and is returning back reasonable answers.
2218+
* 2) Re-evaluates a list of blocks that have been deemed "bad"
2219+
* from the perspective of peg-in witness validation. Blocks are
2220+
* added to this queue in ConnectTip based on the error code returned.
2221+
*/
22152222
bool BitcoindRPCCheck(const bool init)
22162223
{
22172224
//First, we can clear out any blocks thatsomehow are now deemed valid
@@ -2220,9 +2227,12 @@ bool BitcoindRPCCheck(const bool init)
22202227
pblocktree->ReadInvalidBlockQueue(vblocksToReconsider);
22212228
std::vector<uint256> vblocksToReconsiderAgain;
22222229
BOOST_FOREACH(uint256& blockhash, vblocksToReconsider) {
2223-
CBlockIndex* pblockindex = mapBlockIndex[blockhash];
2224-
if ((pblockindex->nStatus & BLOCK_FAILED_MASK)) {
2225-
vblocksToReconsiderAgain.push_back(blockhash);
2230+
LOCK(cs_main);
2231+
if (mapBlockIndex.count(blockhash)) {
2232+
CBlockIndex* pblockindex = mapBlockIndex[blockhash];
2233+
if ((pblockindex->nStatus & BLOCK_FAILED_MASK)) {
2234+
vblocksToReconsiderAgain.push_back(blockhash);
2235+
}
22262236
}
22272237
}
22282238
vblocksToReconsider = vblocksToReconsiderAgain;
@@ -2312,11 +2322,14 @@ bool BitcoindRPCCheck(const bool init)
23122322

23132323
//Now to clear out now-valid blocks
23142324
BOOST_FOREACH(const uint256& blockhash, vblocksToReconsider) {
2315-
CBlockIndex* pblockindex = mapBlockIndex[blockhash];
2325+
LOCK(cs_main);
2326+
if (mapBlockIndex.count(blockhash)) {
2327+
CBlockIndex* pblockindex = mapBlockIndex[blockhash];
23162328

2317-
//Marked as invalid still, put back into queue
2318-
if((pblockindex->nStatus & BLOCK_FAILED_MASK)) {
2319-
vblocksToReconsiderAgain.push_back(blockhash);
2329+
//Marked as invalid still, put back into queue
2330+
if((pblockindex->nStatus & BLOCK_FAILED_MASK)) {
2331+
vblocksToReconsiderAgain.push_back(blockhash);
2332+
}
23202333
}
23212334
}
23222335

@@ -3224,8 +3237,10 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams,
32243237
if (!rv) {
32253238
if (state.IsInvalid()) {
32263239
InvalidBlockFound(pindexNew, state);
3227-
//Possibly result of RPC to bitcoind failure
3228-
//or unseen Bitcoin blocks.
3240+
// Possibly result of RPC to bitcoind failure
3241+
// or unseen Bitcoin blocks.
3242+
// These blocks are later re-evaluated at an interval
3243+
// set by `-recheckpeginblockinterval`.
32293244
if (state.GetRejectCode() == REJECT_PEGIN) {
32303245
//Write queue of invalid blocks that
32313246
//must be cleared to continue operation

0 commit comments

Comments
 (0)