Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13115659
D2102.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
17 KB
Subscribers
None
D2102.diff
View Options
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -1532,7 +1532,7 @@
}
CBlockIndex *pblockindex = mapBlockIndex[hash];
- FinalizeBlock(config, state, pblockindex);
+ FinalizeBlockAndInvalidate(config, state, pblockindex);
}
if (state.IsValid()) {
diff --git a/src/validation.h b/src/validation.h
--- a/src/validation.h
+++ b/src/validation.h
@@ -66,8 +66,9 @@
static const Amount DEFAULT_TRANSACTION_MAXFEE(COIN / 10);
//! Discourage users to set fees higher than this amount (in satoshis) per kB
static const Amount HIGH_TX_FEE_PER_KB(COIN / 100);
-/** -maxtxfee will warn if called with a higher fee than this amount (in
- * satoshis */
+/**
+ * -maxtxfee will warn if called with a higher fee than this amount (in satoshis
+ */
static const Amount HIGH_MAX_TX_FEE(100 * HIGH_TX_FEE_PER_KB);
/** Default for -limitancestorcount, max number of in-mempool ancestors */
static const unsigned int DEFAULT_ANCESTOR_LIMIT = 25;
@@ -93,7 +94,8 @@
static const int MAX_SCRIPTCHECK_THREADS = 16;
/** -par default (number of script-checking threads, 0 = auto) */
static const int DEFAULT_SCRIPTCHECK_THREADS = 0;
-/** Number of blocks that can be requested at any given time from a single peer.
+/**
+ * Number of blocks that can be requested at any given time from a single peer.
*/
static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER = 16;
/**
@@ -191,6 +193,8 @@
/** Default for -stopatheight */
static const int DEFAULT_STOPATHEIGHT = 0;
+/** Default for -maxreorgdepth */
+static const int DEFAULT_MAX_REORG_DEPTH = 10;
extern CScript COINBASE_FLAGS;
extern CCriticalSection cs_main;
@@ -629,8 +633,8 @@
* Mark a block as finalized.
* A finalized block can not be reorged in any way.
*/
-bool FinalizeBlock(const Config &config, CValidationState &state,
- CBlockIndex *pindex);
+bool FinalizeBlockAndInvalidate(const Config &config, CValidationState &state,
+ CBlockIndex *pindex);
/** Mark a block as invalid. */
bool InvalidateBlock(const Config &config, CValidationState &state,
diff --git a/src/validation.cpp b/src/validation.cpp
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -2289,6 +2289,31 @@
}
};
+static bool FinalizeBlockInternal(const Config &config, CValidationState &state,
+ CBlockIndex *pindex) {
+ AssertLockHeld(cs_main);
+ if (pindex->nStatus.isInvalid()) {
+ // We try to finalize an invalid block.
+ return state.DoS(100,
+ error("%s: Trying to finalize invalid block %s",
+ __func__, pindex->GetBlockHash().ToString()),
+ REJECT_INVALID, "finalize-invalid-block");
+ }
+
+ // Check that the request is consistent with current finalization.
+ if (pindexFinalized && !AreOnTheSameFork(pindex, pindexFinalized)) {
+ return state.DoS(
+ 20, error("%s: Trying to finalize block %s which conflicts "
+ "with already finalized block",
+ __func__, pindex->GetBlockHash().ToString()),
+ REJECT_AGAINST_FINALIZED, "bad-fork-prior-finalized");
+ }
+
+ // Our candidate is valid, finalize it.
+ pindexFinalized = pindex;
+ return true;
+}
+
/**
* Connect a new block to chainActive. pblock is either nullptr or a pointer to
* a CBlock corresponding to pindexNew, to bypass loading it again from disk.
@@ -2338,6 +2363,20 @@
FormatStateMessage(state));
}
+ // Update the finalized block.
+ int32_t nHeightToFinalize =
+ pindexNew->nHeight -
+ gArgs.GetArg("-maxreorgdepth", DEFAULT_MAX_REORG_DEPTH);
+ CBlockIndex *pindexToFinalize =
+ pindexNew->GetAncestor(nHeightToFinalize);
+ if (pindexToFinalize &&
+ !FinalizeBlockInternal(config, state, pindexToFinalize)) {
+ state.SetCorruptionPossible();
+ return error("ConnectTip(): FinalizeBlock %s failed (%s)",
+ pindexNew->GetBlockHash().ToString(),
+ FormatStateMessage(state));
+ }
+
nTime3 = GetTimeMicros();
nTimeConnectTotal += nTime3 - nTime2;
LogPrint(BCLog::BENCH, " - Connect total: %.2fms [%.2fs]\n",
@@ -2852,28 +2891,15 @@
return true;
}
-bool FinalizeBlock(const Config &config, CValidationState &state,
- CBlockIndex *pindex) {
+bool FinalizeBlockAndInvalidate(const Config &config, CValidationState &state,
+ CBlockIndex *pindex) {
AssertLockHeld(cs_main);
- if (pindex->nStatus.isInvalid()) {
- // We try to finalize an invalid block.
- return state.DoS(100,
- error("%s: Trying to finalize invalid block %s",
- __func__, pindex->GetBlockHash().ToString()),
- REJECT_INVALID, "finalize-invalid-block");
- }
-
- // Check that the request is consistent with current finalization.
- if (pindexFinalized && !AreOnTheSameFork(pindex, pindexFinalized)) {
- return state.DoS(
- 20, error("%s: Trying to finalize block %s which conflicts "
- "with already finalized block",
- __func__, pindex->GetBlockHash().ToString()),
- REJECT_AGAINST_FINALIZED, "bad-fork-prior-finalized");
+ if (!FinalizeBlockInternal(config, state, pindex)) {
+ // state is set by FinalizeBlockInternal.
+ return false;
}
// We have a valid candidate, make sure it is not parked.
- pindexFinalized = pindex;
if (pindex->nStatus.isOnParkedChain()) {
UnparkBlock(pindex);
}
@@ -4669,6 +4695,7 @@
LOCK(cs_main);
setBlockIndexCandidates.clear();
chainActive.SetTip(nullptr);
+ pindexFinalized = nullptr;
pindexBestInvalid = nullptr;
pindexBestParked = nullptr;
pindexBestHeader = nullptr;
diff --git a/test/functional/abc-parkedchain.py b/test/functional/abc-parkedchain.py
--- a/test/functional/abc-parkedchain.py
+++ b/test/functional/abc-parkedchain.py
@@ -12,7 +12,7 @@
class ParkedChainTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
- self.extra_args = [["-noparkdeepreorg"], []]
+ self.extra_args = [["-noparkdeepreorg"], ["-maxreorgdepth=-1"]]
# There should only be one chaintip, which is expected_tip
def only_valid_tip(self, expected_tip, other_tip_status=None):
diff --git a/test/functional/bip68-sequence.py b/test/functional/bip68-sequence.py
--- a/test/functional/bip68-sequence.py
+++ b/test/functional/bip68-sequence.py
@@ -26,8 +26,8 @@
class BIP68Test(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
- self.extra_args = [["-blockprioritypercentage=0", "-noparkdeepreorg"],
- ["-blockprioritypercentage=0", "-acceptnonstdtxn=0"]]
+ self.extra_args = [["-blockprioritypercentage=0", "-noparkdeepreorg", "-maxreorgdepth=-1"],
+ ["-blockprioritypercentage=0", "-acceptnonstdtxn=0", "-maxreorgdepth=-1"]]
def run_test(self):
self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"]
diff --git a/test/functional/p2p-fullblocktest.py b/test/functional/p2p-fullblocktest.py
--- a/test/functional/p2p-fullblocktest.py
+++ b/test/functional/p2p-fullblocktest.py
@@ -61,7 +61,8 @@
# Change the "outcome" variable from each TestInstance object to only do the comparison.
def set_test_params(self):
self.num_nodes = 1
- self.extra_args = [['-whitelist=127.0.0.1', '-noparkdeepreorg']]
+ self.extra_args = [['-whitelist=127.0.0.1',
+ '-noparkdeepreorg', '-maxreorgdepth=-1']]
self.setup_clean_chain = True
self.block_heights = {}
self.coinbase_key = CECKey()
diff --git a/test/functional/pruning.py b/test/functional/pruning.py
--- a/test/functional/pruning.py
+++ b/test/functional/pruning.py
@@ -38,20 +38,20 @@
# Create nodes 0 and 1 to mine.
# Create node 2 to test pruning.
self.full_node_default_args = ["-maxreceivebuffer=20000", "-blockmaxsize=999000",
- "-checkblocks=5", "-noparkdeepreorg",
+ "-checkblocks=5", "-noparkdeepreorg", "-maxreorgdepth=-1",
"-limitdescendantcount=100", "-limitdescendantsize=5000",
"-limitancestorcount=100", "-limitancestorsize=5000"]
# Create nodes 3 and 4 to test manual pruning (they will be re-started with manual pruning later)
# Create nodes 5 to test wallet in prune mode, but do not connect
self.extra_args = [self.full_node_default_args,
self.full_node_default_args,
- ["-maxreceivebuffer=20000",
- "-prune=550", "-noparkdeepreorg"],
- ["-maxreceivebuffer=20000",
- "-blockmaxsize=999000", "-noparkdeepreorg"],
- ["-maxreceivebuffer=20000",
- "-blockmaxsize=999000", "-noparkdeepreorg"],
- ["-prune=550", "-noparkdeepreorg"]]
+ ["-maxreceivebuffer=20000", "-prune=550",
+ "-noparkdeepreorg", "-maxreorgdepth=-1"],
+ ["-maxreceivebuffer=20000", "-blockmaxsize=999000",
+ "-noparkdeepreorg", "-maxreorgdepth=-1"],
+ ["-maxreceivebuffer=20000", "-blockmaxsize=999000",
+ "-noparkdeepreorg", "-maxreorgdepth=-1"],
+ ["-prune=550"]]
def setup_network(self):
self.setup_nodes()
@@ -152,7 +152,7 @@
self.stop_node(1)
self.start_node(1, extra_args=[
"-maxreceivebuffer=20000", "-blockmaxsize=5000", "-checkblocks=5",
- "-disablesafemode", "-noparkdeepreorg"])
+ "-disablesafemode", "-noparkdeepreorg", "-maxreorgdepth=-1"])
height = self.nodes[1].getblockcount()
self.log.info("Current block height: %d" % height)
@@ -179,7 +179,7 @@
self.stop_node(1)
self.start_node(1, extra_args=[
"-maxreceivebuffer=20000", "-blockmaxsize=5000", "-checkblocks=5",
- "-disablesafemode", "-noparkdeepreorg"])
+ "-disablesafemode", "-noparkdeepreorg", "-maxreorgdepth=-1"])
self.log.info("Generating new longer chain of 300 more blocks")
self.nodes[1].generate(300)
@@ -371,7 +371,8 @@
# check that the pruning node's wallet is still in good shape
self.log.info("Stop and start pruning node to trigger wallet rescan")
self.stop_node(2)
- self.start_node(2, extra_args=["-prune=550", "-noparkdeepreorg"])
+ self.start_node(
+ 2, extra_args=["-prune=550", "-noparkdeepreorg", "-maxreorgdepth=-1"])
self.log.info("Success")
# check that wallet loads loads successfully when restarting a pruned node after IBD.
@@ -381,7 +382,8 @@
nds = [self.nodes[0], self.nodes[5]]
sync_blocks(nds, wait=5, timeout=300)
self.stop_node(5) # stop and start to trigger rescan
- self.start_node(5, extra_args=["-prune=550", "-noparkdeepreorg"])
+ self.start_node(
+ 5, extra_args=["-prune=550", "-noparkdeepreorg", "-maxreorgdepth=-1"])
self.log.info("Success")
def run_test(self):
diff --git a/test/functional/timing.json b/test/functional/timing.json
--- a/test/functional/timing.json
+++ b/test/functional/timing.json
@@ -1,7 +1,7 @@
[
{
"name": "abandonconflict.py",
- "time": 16
+ "time": 17
},
{
"name": "abc-checkdatasig-activation.py",
@@ -11,37 +11,41 @@
"name": "abc-cmdline.py",
"time": 8
},
+ {
+ "name": "abc-finalize-block.py",
+ "time": 4
+ },
{
"name": "abc-high_priority_transaction.py",
- "time": 10
+ "time": 37
},
{
"name": "abc-magnetic-anomaly-activation.py",
- "time": 6
+ "time": 14
},
{
"name": "abc-magnetic-anomaly-mining.py",
- "time": 15
+ "time": 13
},
{
"name": "abc-mempool-accept-txn.py",
- "time": 5
+ "time": 3
},
{
"name": "abc-p2p-compactblocks.py",
- "time": 104
+ "time": 273
},
{
"name": "abc-p2p-fullblocktest.py",
- "time": 81
+ "time": 62
},
{
"name": "abc-parkedchain.py",
- "time": 4
+ "time": 17
},
{
"name": "abc-replay-protection.py",
- "time": 5
+ "time": 4
},
{
"name": "abc-rpc.py",
@@ -53,23 +57,23 @@
},
{
"name": "assumevalid.py",
- "time": 20
+ "time": 17
},
{
"name": "bip65-cltv-p2p.py",
- "time": 5
+ "time": 6
},
{
"name": "bip68-112-113-p2p.py",
- "time": 18
+ "time": 15
},
{
"name": "bip68-sequence.py",
- "time": 18
+ "time": 32
},
{
"name": "bipdersig-p2p.py",
- "time": 7
+ "time": 6
},
{
"name": "bitcoin_cli.py",
@@ -77,15 +81,15 @@
},
{
"name": "blockchain.py",
- "time": 11
+ "time": 19
},
{
"name": "dbcrash.py",
- "time": 756
+ "time": 1292
},
{
"name": "decodescript.py",
- "time": 3
+ "time": 2
},
{
"name": "disablewallet.py",
@@ -93,99 +97,99 @@
},
{
"name": "disconnect_ban.py",
- "time": 8
+ "time": 9
},
{
"name": "example_test.py",
- "time": 4
+ "time": 16
},
{
"name": "fundrawtransaction.py",
- "time": 42
+ "time": 40
},
{
"name": "getblocktemplate_longpoll.py",
- "time": 68
+ "time": 69
},
{
"name": "getchaintips.py",
- "time": 4
+ "time": 5
},
{
"name": "httpbasics.py",
- "time": 3
+ "time": 17
},
{
"name": "import-rescan.py",
- "time": 16
+ "time": 18
},
{
"name": "importmulti.py",
- "time": 12
+ "time": 11
},
{
"name": "importprunedfunds.py",
- "time": 4
+ "time": 5
},
{
"name": "invalidateblock.py",
- "time": 9
+ "time": 8
},
{
"name": "invalidblockrequest.py",
- "time": 4
+ "time": 5
},
{
"name": "invalidtxrequest.py",
- "time": 4
+ "time": 15
},
{
"name": "keypool-topup.py",
- "time": 19
+ "time": 34
},
{
"name": "keypool.py",
- "time": 8
+ "time": 9
},
{
"name": "listsinceblock.py",
- "time": 5
+ "time": 24
},
{
"name": "listtransactions.py",
- "time": 11
+ "time": 23
},
{
"name": "maxuploadtarget.py",
- "time": 37
+ "time": 28
},
{
"name": "mempool_limit.py",
- "time": 5
+ "time": 8
},
{
"name": "mempool_packages.py",
- "time": 28
+ "time": 55
},
{
"name": "mempool_persist.py",
- "time": 16
+ "time": 19
},
{
"name": "mempool_reorg.py",
- "time": 4
+ "time": 6
},
{
"name": "mempool_resurrect_test.py",
- "time": 3
+ "time": 18
},
{
"name": "mempool_spendcoinbase.py",
- "time": 3
+ "time": 5
},
{
"name": "merkle_blocks.py",
- "time": 5
+ "time": 32
},
{
"name": "minchainwork.py",
@@ -193,19 +197,19 @@
},
{
"name": "mining.py",
- "time": 3
+ "time": 5
},
{
"name": "multi_rpc.py",
- "time": 4
+ "time": 18
},
{
"name": "multiwallet.py",
- "time": 9
+ "time": 20
},
{
"name": "net.py",
- "time": 4
+ "time": 13
},
{
"name": "notifications.py",
@@ -213,27 +217,27 @@
},
{
"name": "nulldummy.py",
- "time": 4
+ "time": 5
},
{
"name": "p2p-acceptblock.py",
- "time": 7
+ "time": 14
},
{
"name": "p2p-compactblocks.py",
- "time": 23
+ "time": 22
},
{
"name": "p2p-feefilter.py",
- "time": 63
+ "time": 51
},
{
"name": "p2p-fullblocktest.py",
- "time": 184
+ "time": 148
},
{
"name": "p2p-leaktests.py",
- "time": 7
+ "time": 8
},
{
"name": "p2p-mempool.py",
@@ -245,43 +249,43 @@
},
{
"name": "preciousblock.py",
- "time": 4
+ "time": 5
},
{
"name": "prioritise_transaction.py",
- "time": 6
+ "time": 34
},
{
"name": "proxy_test.py",
- "time": 4
+ "time": 5
},
{
"name": "pruning.py",
- "time": 1040
+ "time": 1511
},
{
"name": "rawtransactions.py",
- "time": 17
+ "time": 16
},
{
"name": "receivedby.py",
- "time": 6
+ "time": 37
},
{
"name": "reindex.py",
- "time": 14
+ "time": 18
},
{
"name": "resendwallettransactions.py",
- "time": 6
+ "time": 18
},
{
"name": "rest.py",
- "time": 11
+ "time": 20
},
{
"name": "rpcbind_test.py",
- "time": 29
+ "time": 28
},
{
"name": "rpcnamedargs.py",
@@ -289,7 +293,7 @@
},
{
"name": "sendheaders.py",
- "time": 22
+ "time": 16
},
{
"name": "signmessages.py",
@@ -301,7 +305,7 @@
},
{
"name": "txn_clone.py",
- "time": 5
+ "time": 8
},
{
"name": "txn_clone.py --mineblock",
@@ -309,46 +313,46 @@
},
{
"name": "txn_doublespend.py",
- "time": 5
+ "time": 7
},
{
"name": "txn_doublespend.py --mineblock",
- "time": 6
+ "time": 7
},
{
"name": "uptime.py",
- "time": 2
+ "time": 3
},
{
"name": "wallet-accounts.py",
- "time": 13
+ "time": 26
},
{
"name": "wallet-dump.py",
- "time": 8
+ "time": 35
},
{
"name": "wallet-encryption.py",
- "time": 9
+ "time": 18
},
{
"name": "wallet-hd.py",
- "time": 111
+ "time": 36
},
{
"name": "wallet.py",
- "time": 56
+ "time": 46
},
{
"name": "walletbackup.py",
- "time": 137
+ "time": 119
},
{
"name": "zapwallettxes.py",
- "time": 15
+ "time": 14
},
{
"name": "zmq_test.py",
"time": 9
}
-]
+]
\ No newline at end of file
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 1, 11:41 (2 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5183581
Default Alt Text
D2102.diff (17 KB)
Attached To
D2102: Auto-finalize block once they reached a certain depth (by default 10)
Event Timeline
Log In to Comment