From a451e832b46bcb984dfcd9478ea8ebb8b3de0c62 Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Wed, 9 Nov 2022 12:07:23 -0500 Subject: [PATCH 1/2] fix: validation: cast now() to seconds for maxtipage comparison Since faf44876db555f7488c8df96db9fa88b793f897c, the maxtipage comparison in IsInitialBlockDownload() has been broken, since the NodeClock::now() time_point is in the system's native denomination (micrcoseconds). Without this patch, specifying the maximum allowable -maxtipage (9223372036854775807) results in a SIGABRT crash. Co-authored-by: MacroFake --- src/validation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/validation.cpp b/src/validation.cpp index debdc2ae7..bd298959f 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1541,7 +1541,7 @@ bool Chainstate::IsInitialBlockDownload() const if (m_chain.Tip()->nChainWork < m_chainman.MinimumChainWork()) { return true; } - if (m_chain.Tip()->Time() < NodeClock::now() - m_chainman.m_options.max_tip_age) { + if (m_chain.Tip()->Time() < Now() - m_chainman.m_options.max_tip_age) { return true; } LogPrintf("Leaving InitialBlockDownload (latching to false)\n"); From e4be0e9b0661a8af49c4e6d5472804913f04b8fc Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Wed, 9 Nov 2022 12:07:32 -0500 Subject: [PATCH 2/2] test: add -maxtipage test for the maximum allowable value --- test/functional/feature_maxtipage.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/test/functional/feature_maxtipage.py b/test/functional/feature_maxtipage.py index ddc210254..51f37ef1e 100755 --- a/test/functional/feature_maxtipage.py +++ b/test/functional/feature_maxtipage.py @@ -22,23 +22,24 @@ def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 2 - def test_maxtipage(self, maxtipage, set_parameter=True): + def test_maxtipage(self, maxtipage, set_parameter=True, test_deltas=True): node_miner = self.nodes[0] node_ibd = self.nodes[1] self.restart_node(1, [f'-maxtipage={maxtipage}'] if set_parameter else None) self.connect_nodes(0, 1) - - # tips older than maximum age -> stay in IBD cur_time = int(time.time()) - node_ibd.setmocktime(cur_time) - for delta in [5, 4, 3, 2, 1]: - node_miner.setmocktime(cur_time - maxtipage - delta) - self.generate(node_miner, 1) - assert_equal(node_ibd.getblockchaininfo()['initialblockdownload'], True) + + if test_deltas: + # tips older than maximum age -> stay in IBD + node_ibd.setmocktime(cur_time) + for delta in [5, 4, 3, 2, 1]: + node_miner.setmocktime(cur_time - maxtipage - delta) + self.generate(node_miner, 1) + assert_equal(node_ibd.getblockchaininfo()['initialblockdownload'], True) # tip within maximum age -> leave IBD - node_miner.setmocktime(cur_time - maxtipage) + node_miner.setmocktime(max(cur_time - maxtipage, 0)) self.generate(node_miner, 1) assert_equal(node_ibd.getblockchaininfo()['initialblockdownload'], False) @@ -51,6 +52,10 @@ def run_test(self): self.log.info(f"Test IBD with maximum tip age of {hours} hours (-maxtipage={maxtipage}).") self.test_maxtipage(maxtipage) + max_long_val = 9223372036854775807 + self.log.info(f"Test IBD with highest allowable maximum tip age ({max_long_val}).") + self.test_maxtipage(max_long_val, test_deltas=False) + if __name__ == '__main__': MaxTipAgeTest().main()