diff --git a/contrib/devtools/chainparams/chainparams_main.txt b/contrib/devtools/chainparams/chainparams_main.txt --- a/contrib/devtools/chainparams/chainparams_main.txt +++ b/contrib/devtools/chainparams/chainparams_main.txt @@ -1,2 +1,4 @@ -0000000000000000005e9e3efdbbfee84d3ff492ae757b88091f8536a172dee5 -00000000000000000000000000000000000000000133614146328e4aa5822f60 +000000000000000002c180da0bbeac37e2a327a29c0ef354017b41f9d71b6693 +00000000000000000000000000000000000000000133b5ab7723a16bd0d489f5 +203 +3 diff --git a/contrib/devtools/chainparams/chainparams_test.txt b/contrib/devtools/chainparams/chainparams_test.txt --- a/contrib/devtools/chainparams/chainparams_test.txt +++ b/contrib/devtools/chainparams/chainparams_test.txt @@ -1,2 +1,4 @@ -0000000000005f4dc89bceb493197ca9fdf22b8ee2b86c191ea980e9a36033c1 -00000000000000000000000000000000000000000000005acaacb4b966e6dc4a +0000000000006ffea6e9d1e3c9ceea81ccc73f83d8ee1ce1fa1f157cdc2eb277 +00000000000000000000000000000000000000000000005d3e6f5fcb1e75fb2b +56 +2 diff --git a/contrib/devtools/chainparams/generate_chainparams_constants.py b/contrib/devtools/chainparams/generate_chainparams_constants.py --- a/contrib/devtools/chainparams/generate_chainparams_constants.py +++ b/contrib/devtools/chainparams/generate_chainparams_constants.py @@ -16,6 +16,8 @@ + + The outputted constants should be pasted into `src/chainparamsconstants.h`. ''' @@ -28,8 +30,8 @@ with open(os.path.join(indir, file_name), 'r', encoding="utf8") as f: constants = f.readlines() - # Ensure only two lines are read from the file. - assert(len(constants) == 2) + # Ensure only the expected number of lines are read from the file + assert(len(constants) == 4) return [line.rstrip() for line in constants] @@ -56,9 +58,13 @@ namespace ChainParamsConstants {{ const BlockHash MAINNET_DEFAULT_ASSUME_VALID = BlockHash::fromHex("{}"); const uint256 MAINNET_MINIMUM_CHAIN_WORK = uint256S("{}"); + const uint64_t MAINNET_ASSUMED_BLOCKCHAIN_SIZE = {}; + const uint64_t MAINNET_ASSUMED_CHAINSTATE_SIZE = {}; const BlockHash TESTNET_DEFAULT_ASSUME_VALID = BlockHash::fromHex("{}"); const uint256 TESTNET_MINIMUM_CHAIN_WORK = uint256S("{}"); + const uint64_t TESTNET_ASSUMED_BLOCKCHAIN_SIZE = {}; + const uint64_t TESTNET_ASSUMED_CHAINSTATE_SIZE = {}; }} // namespace ChainParamsConstants #endif // BITCOIN_CHAINPARAMSCONSTANTS_H\ diff --git a/contrib/devtools/chainparams/make_chainparams.py b/contrib/devtools/chainparams/make_chainparams.py --- a/contrib/devtools/chainparams/make_chainparams.py +++ b/contrib/devtools/chainparams/make_chainparams.py @@ -5,6 +5,7 @@ from enum import Enum import argparse +import math import os.path import re import sys @@ -18,6 +19,9 @@ TestNet = "TESTNET" +GIGABYTE = 1024 * 1024 * 1024 + + def get_chainparams(rpc_caller, block): # Fetch initial chain info chaininfo = rpc_caller.getblockchaininfo() @@ -52,13 +56,20 @@ # exception if not. rpc_caller.getblockheader(block) - return (chainwork, block) + # Block size on disk (in GB) with some margin for growth + diskSizeBlocks = str( + int(math.ceil(chaininfo['size_on_disk'] / GIGABYTE * 1.3))) + + # Chainstate size on disk (in GB) with some margin for growth + utxos = rpc_caller.gettxoutsetinfo() + diskSizeChainstate = str( + int(math.ceil(utxos['disk_size'] / GIGABYTE * 1.3))) + + return (block, chainwork, diskSizeBlocks, diskSizeChainstate) def main(args): - (chainwork, blockhash) = get_chainparams(args['rpc'], args['block']) - output = "{}\n{}".format(blockhash, chainwork) - return output + return "\n".join(get_chainparams(args['rpc'], args['block'])) if __name__ == "__main__": @@ -102,7 +113,7 @@ raise ValueError("Config is missing rpcpassword") args.rpc = AuthServiceProxy( - 'http://{}:{}@{}'.format(user, password, args.address)) + service_url='http://{}:{}@{}'.format(user, password, args.address), timeout=1200) output = main(vars(args)) if output: print(output) diff --git a/contrib/devtools/chainparams/test_make_chainparams.py b/contrib/devtools/chainparams/test_make_chainparams.py --- a/contrib/devtools/chainparams/test_make_chainparams.py +++ b/contrib/devtools/chainparams/test_make_chainparams.py @@ -9,13 +9,15 @@ class MockRPC: - def __init__(self, test, chain, numBlocks, - expectedBlock, blockHash, chainWork): + def __init__(self, test, chain, numBlocks, expectedBlock, + blockHash, chainWork, blockchainSize, chainstateSize): self.test = test self.chain = chain self.numBlocks = numBlocks self.expectedBlock = expectedBlock + self.blockchainSize = blockchainSize self.blockHash = blockHash + self.chainstateSize = chainstateSize self.chainWork = chainWork def getblockchaininfo(self): @@ -29,7 +31,7 @@ "verificationprogress": 0.9999958005632363, "initialblockdownload": False, "chainwork": self.chainWork, - "size_on_disk": 952031444, + "size_on_disk": self.blockchainSize, "pruned": True, "pruneheight": 582974, "automatic_pruning": True, @@ -66,13 +68,33 @@ "previousblockhash": "00000000000000000307b45e4a6cf8d49e70b9012ea1d72a5ce334a4213f66bd", } + def gettxoutsetinfo(self): + return { + "height": 636013, + "bestblock": "00000000000000000250a6ab6c6c4778086807f5b39910a8c108efa511282280", + "transactions": 19360831, + "txouts": 42145889, + "bogosize": 3187119531, + "hash_serialized": "1b1cc457771e8b6f849ac21c4da43ebe5c614df9e61a943252978437ad774ce5", + "disk_size": self.chainstateSize, + "total_amount": 18412423.42452419, + } + class MockFailRPC(MockRPC): # Provides a fail counter to fail after the Nth RPC command - def __init__(self, test, chain, numBlocks, expectedBlock, - blockHash, chainWork, failCounter): - super().__init__(test, chain, numBlocks, expectedBlock, blockHash, chainWork) + def __init__(self, test, chain, numBlocks, expectedBlock, blockHash, + chainWork, blockchainSize, chainstateSize, failCounter): + super().__init__( + test, + chain, + numBlocks, + expectedBlock, + blockHash, + chainWork, + blockchainSize, + chainstateSize) self.failCounter = failCounter def checkFailCounter(self): @@ -94,6 +116,10 @@ self.checkFailCounter() return super().getblockheader(blockHash) + def gettxoutsetinfo(self): + self.checkFailCounter() + return super().gettxoutsetinfo() + def CheckMockFailure(test, args, errorMessage='error code: -99'): with test.assertRaises(Exception) as context: @@ -111,41 +137,72 @@ self.chainWork2 = '00000000000000000000000000000000000000000000004fdb4795a837f19671' def test_happy_path_mainnet(self): - mockRPC = MockRPC(test=self, chain='main', numBlocks=123000, - expectedBlock=122990, blockHash=self.blockHash1, chainWork=self.chainWork1) + mockRPC = MockRPC( + test=self, + chain='main', + numBlocks=123000, + expectedBlock=122990, + blockHash=self.blockHash1, + chainWork=self.chainWork1, + blockchainSize=160111222333, + chainstateSize=2000111222) args = { 'rpc': mockRPC, 'block': None, } - self.assertEqual(GenerateChainParams(args), "{}\n{}".format( + self.assertEqual(GenerateChainParams(args), "\n".join([ "0000000000000000003ef673ae12bc6017481830d37b9c52ce1e79c080e812b8", - "000000000000000000000000000000000000000000f2537ccf2e07bbe15e70e1")) + "000000000000000000000000000000000000000000f2537ccf2e07bbe15e70e1", + "194", "3"])) def test_happy_path_testnet(self): - mockRPC = MockRPC(test=self, chain='test', numBlocks=234000, - expectedBlock=232000, blockHash=self.blockHash1, chainWork=self.chainWork1) + mockRPC = MockRPC( + test=self, + chain='test', + numBlocks=234000, + expectedBlock=232000, + blockHash=self.blockHash1, + chainWork=self.chainWork1, + blockchainSize=50111222333, + chainstateSize=1000111222) args = { 'rpc': mockRPC, 'block': None, } - self.assertEqual(GenerateChainParams(args), "{}\n{}".format( + self.assertEqual(GenerateChainParams(args), "\n".join([ "0000000000000000003ef673ae12bc6017481830d37b9c52ce1e79c080e812b8", - "000000000000000000000000000000000000000000f2537ccf2e07bbe15e70e1")) + "000000000000000000000000000000000000000000f2537ccf2e07bbe15e70e1", + "61", "2"])) def test_specific_block(self): - mockRPC = MockRPC(test=self, chain='main', numBlocks=123000, - expectedBlock=122990, blockHash=self.blockHash1, chainWork=self.chainWork1) + mockRPC = MockRPC( + test=self, + chain='main', + numBlocks=123000, + expectedBlock=122990, + blockHash=self.blockHash1, + chainWork=self.chainWork1, + blockchainSize=160111222333, + chainstateSize=2000111222) args = { 'rpc': mockRPC, 'block': self.blockHash1, } - self.assertEqual(GenerateChainParams(args), "{}\n{}".format( + self.assertEqual(GenerateChainParams(args), "\n".join([ "0000000000000000003ef673ae12bc6017481830d37b9c52ce1e79c080e812b8", - "000000000000000000000000000000000000000000f2537ccf2e07bbe15e70e1")) + "000000000000000000000000000000000000000000f2537ccf2e07bbe15e70e1", + "194", "3"])) def test_wrong_chain(self): - mockRPC = MockRPC(test=self, chain='main', numBlocks=123000, - expectedBlock=122990, blockHash=self.blockHash1, chainWork=self.chainWork1) + mockRPC = MockRPC( + test=self, + chain='main', + numBlocks=123000, + expectedBlock=122990, + blockHash=self.blockHash1, + chainWork=self.chainWork1, + blockchainSize=160111222333, + chainstateSize=2000111222) args = { 'rpc': mockRPC, 'block': self.blockHash2, @@ -159,9 +216,17 @@ if chain == 'test': expectedBlock = 132000 - for failCounter in range(3): - mockFailRPC = MockFailRPC(test=self, chain=chain, numBlocks=134000, expectedBlock=expectedBlock, - blockHash=self.blockHash1, chainWork=self.chainWork1, failCounter=failCounter) + for failCounter in range(4): + mockFailRPC = MockFailRPC( + test=self, + chain=chain, + numBlocks=134000, + expectedBlock=expectedBlock, + blockHash=self.blockHash1, + chainWork=self.chainWork1, + failCounter=failCounter, + blockchainSize=160111222333, + chainstateSize=2000111222) argsFail = { 'rpc': mockFailRPC, 'block': None, diff --git a/src/chainparams.cpp b/src/chainparams.cpp --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -192,8 +192,10 @@ netMagic[3] = 0xe8; nDefaultPort = 8333; nPruneAfterHeight = 100000; - m_assumed_blockchain_size = 200; - m_assumed_chain_state_size = 3; + m_assumed_blockchain_size = + ChainParamsConstants::MAINNET_ASSUMED_BLOCKCHAIN_SIZE; + m_assumed_chain_state_size = + ChainParamsConstants::MAINNET_ASSUMED_CHAINSTATE_SIZE; genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50 * COIN); @@ -419,8 +421,10 @@ netMagic[3] = 0xf4; nDefaultPort = 18333; nPruneAfterHeight = 1000; - m_assumed_blockchain_size = 20; - m_assumed_chain_state_size = 2; + m_assumed_blockchain_size = + ChainParamsConstants::TESTNET_ASSUMED_BLOCKCHAIN_SIZE; + m_assumed_chain_state_size = + ChainParamsConstants::TESTNET_ASSUMED_CHAINSTATE_SIZE; genesis = CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN); diff --git a/src/chainparamsconstants.h b/src/chainparamsconstants.h --- a/src/chainparamsconstants.h +++ b/src/chainparamsconstants.h @@ -9,11 +9,15 @@ #include namespace ChainParamsConstants { - const BlockHash MAINNET_DEFAULT_ASSUME_VALID = BlockHash::fromHex("0000000000000000005e9e3efdbbfee84d3ff492ae757b88091f8536a172dee5"); - const uint256 MAINNET_MINIMUM_CHAIN_WORK = uint256S("00000000000000000000000000000000000000000133614146328e4aa5822f60"); + const BlockHash MAINNET_DEFAULT_ASSUME_VALID = BlockHash::fromHex("0000000000000000012917d2e9d3570ede61541bc935184c200bdfb3eba98ec0"); + const uint256 MAINNET_MINIMUM_CHAIN_WORK = uint256S("000000000000000000000000000000000000000001338fb4ae33617274c063b3"); + const uint64_t MAINNET_ASSUMED_BLOCKCHAIN_SIZE = 203; + const uint64_t MAINNET_ASSUMED_CHAINSTATE_SIZE = 3; - const BlockHash TESTNET_DEFAULT_ASSUME_VALID = BlockHash::fromHex("0000000000005f4dc89bceb493197ca9fdf22b8ee2b86c191ea980e9a36033c1"); - const uint256 TESTNET_MINIMUM_CHAIN_WORK = uint256S("00000000000000000000000000000000000000000000005acaacb4b966e6dc4a"); + const BlockHash TESTNET_DEFAULT_ASSUME_VALID = BlockHash::fromHex("00000000000008844d7f0cfbd63b04309d9a558e06d204de9bf74c5240e3db24"); + const uint256 TESTNET_MINIMUM_CHAIN_WORK = uint256S("00000000000000000000000000000000000000000000005b24953a1acaa81bce"); + const uint64_t TESTNET_ASSUMED_BLOCKCHAIN_SIZE = 56; + const uint64_t TESTNET_ASSUMED_CHAINSTATE_SIZE = 2; } // namespace ChainParamsConstants #endif // BITCOIN_CHAINPARAMSCONSTANTS_H