diff --git a/contrib/devtools/chainparams/chainparams_main.txt b/contrib/devtools/chainparams/chainparams_main.txt index 44b1a568c..37f8a0230 100644 --- 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 index 74cabcf4f..f6a348689 100644 --- 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 index 40f426598..4f758ed7f 100755 --- a/contrib/devtools/chainparams/generate_chainparams_constants.py +++ b/contrib/devtools/chainparams/generate_chainparams_constants.py @@ -1,74 +1,80 @@ #!/usr/bin/env python3 # Copyright (c) 2019 The Bitcoin developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' Script to generate list of chainparams constants (ie. assumevalid and minimum chainwork). This script expects a text file for each chain in the directory that is passed as an argument: chainparams_main.txt chainparams_test.txt These files must consist of lines in the format + + The outputted constants should be pasted into `src/chainparamsconstants.h`. ''' import sys import os def process_constants(indir, file_name): 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] def main(): if len(sys.argv) != 2: print('Usage: {} '.format( sys.argv[0]), file=sys.stderr) sys.exit(1) indir = sys.argv[1] print('''\ #ifndef BITCOIN_CHAINPARAMSCONSTANTS_H #define BITCOIN_CHAINPARAMSCONSTANTS_H /** * Chain params constants for each tracked chain. * @{} by contrib/devtools/chainparams/generate_chainparams_constants.py */ #include #include 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\ '''.format( # 'generated' is split out so this file is not identified as generated. "generated", *process_constants(indir, 'chainparams_main.txt'), *process_constants(indir, 'chainparams_test.txt')) ) if __name__ == '__main__': main() diff --git a/contrib/devtools/chainparams/make_chainparams.py b/contrib/devtools/chainparams/make_chainparams.py index 1a42b88c6..dd83c8369 100755 --- a/contrib/devtools/chainparams/make_chainparams.py +++ b/contrib/devtools/chainparams/make_chainparams.py @@ -1,108 +1,119 @@ #!/usr/bin/env python3 # Copyright (c) 2019 The Bitcoin developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. from enum import Enum import argparse +import math import os.path import re import sys sys.path.append('../../../test/functional/test_framework') from authproxy import AuthServiceProxy # noqa: E402 class Chain(Enum): MainNet = "MAINNET" TestNet = "TESTNET" +GIGABYTE = 1024 * 1024 * 1024 + + def get_chainparams(rpc_caller, block): # Fetch initial chain info chaininfo = rpc_caller.getblockchaininfo() if chaininfo['chain'] == 'main': chain = Chain.MainNet else: chain = Chain.TestNet # Use highest valid chainwork. This doesn't need to match the block hash # used by assume valid. chainwork = chaininfo['chainwork'] if not re.match('^[0-9a-z]{64}$', chainwork): raise Exception("Chain work is not a valid uint256 hex value.") # Default to N blocks from the chain tip, depending on which chain we're on if not block: block = chaininfo['blocks'] if chain == Chain.MainNet: block -= 10 else: block -= 2000 block = str(block) if not re.match('^[0-9a-z]{64}$', block): if re.match('^[0-9]*$', block): # Fetch block hash using block height block = rpc_caller.getblockhash(int(block)) else: raise Exception("Block hash is not a valid block hash or height.") # Make sure the block hash is part of the chain. This call with raise an # 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__": parser = argparse.ArgumentParser(description=( "Make chainparams file.\n" "Prerequisites: RPC access to a bitcoind node.\n\n"), formatter_class=argparse.RawTextHelpFormatter) parser.add_argument('--address', '-a', default="127.0.0.1:8332", help="Node address for making RPC calls.\n" "The chain (MainNet or TestNet) will be automatically detected.\n" "Default: '127.0.0.1:8332'") parser.add_argument('--block', '-b', help="The block hash or height to use for fetching chainparams.\n" "MainNet default: 10 blocks from the chain tip." "TestNet default: 2000 blocks from the chain tip.") parser.add_argument('--config', '-c', default="~/.bitcoin/bitcoin.conf", help="Path to bitcoin.conf for RPC authentication arguments (rpcuser & rpcpassword).\n" "Default: ~/.bitcoin/bitcoin.conf") args = parser.parse_args() args.config = os.path.expanduser(args.config) # Get user and password from config user = None password = None if os.path.isfile(args.config): with open(args.config, 'r', encoding='utf8') as f: for line in f: if line.startswith("rpcuser="): # Ensure that there is only one rpcuser line assert user is None user = line.split("=")[1].strip("\n") if line.startswith("rpcpassword="): # Ensure that there is only one rpcpassword line assert password is None password = line.split("=")[1].strip("\n") else: raise FileNotFoundError("Missing bitcoin.conf") if user is None: raise ValueError("Config is missing rpcuser") if password is None: 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 index e4dd70060..970ab822a 100755 --- a/contrib/devtools/chainparams/test_make_chainparams.py +++ b/contrib/devtools/chainparams/test_make_chainparams.py @@ -1,172 +1,237 @@ #!/usr/bin/env python3 # Copyright (c) 2019 The Bitcoin developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. import unittest from make_chainparams import main as GenerateChainParams 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): return { "chain": self.chain, "blocks": self.numBlocks, "headers": self.numBlocks, "bestblockhash": "0000000000000000039c96605d7fca74a5e185ea5634198346e9e07fd235b666", "difficulty": 274412074285.6605, "mediantime": 1562168718, "verificationprogress": 0.9999958005632363, "initialblockdownload": False, "chainwork": self.chainWork, - "size_on_disk": 952031444, + "size_on_disk": self.blockchainSize, "pruned": True, "pruneheight": 582974, "automatic_pruning": True, "prune_target_size": 1048576000, } def getblockhash(self, block): # Tests should always request the right block height. Even though a # real node will rarely raise an exception for this call, we are # more strict during testing. self.test.assertEqual(block, self.expectedBlock, "Called 'getblockhash {}' when expected was 'getblockhash {}'".format( block, self.expectedBlock)) return self.blockHash def getblockheader(self, blockHash): # Make sure to raise an exception in the same way a real node would # when calling 'getblockheader' on a block hash that is not part of # the chain. self.test.assertEqual(blockHash, self.blockHash, "Called 'getblockheader {}' when expected was 'getblockheader {}'".format( blockHash, self.blockHash)) return { "hash": blockHash, "confirmations": 1, "height": 591463, "version": 536870912, "versionHex": "20000000", "merkleroot": "51c898f034b6c5a5513a7c35912e86d009188311e550bb3096e04afb11f40aba", "time": 1563212034, "mediantime": 1563208994, "nonce": 3501699724, "bits": "18040cd6", "difficulty": 271470800310.0635, "chainwork": "000000000000000000000000000000000000000000f4c5e639fa012518a48a57", "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): self.failCounter -= 1 if self.failCounter < 0: raise Exception("""error code: -99 error message: mock error""") def getblockchaininfo(self): self.checkFailCounter() return super().getblockchaininfo() def getblockhash(self, block): self.checkFailCounter() return super().getblockhash(block) def getblockheader(self, blockHash): 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: GenerateChainParams(args) test.assertIn(errorMessage, str(context.exception)) class GenerateChainParamsTests(unittest.TestCase): maxDiff = None def setUp(self): self.blockHash1 = '0000000000000000003ef673ae12bc6017481830d37b9c52ce1e79c080e812b8' self.chainWork1 = '000000000000000000000000000000000000000000f2537ccf2e07bbe15e70e1' self.blockHash2 = '0000000000000298a9fa227f0ec32f2b7585f3e64c8b3369e7f8b4fd8ea3d836' 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, } CheckMockFailure( self, args, "expected was 'getblockheader 0000000000000000003ef673ae12bc6017481830d37b9c52ce1e79c080e812b8'") def test_bitcoin_cli_failures_testnet(self): for chain in ['main', 'test']: expectedBlock = 133990 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, } CheckMockFailure(self, argsFail) unittest.main() diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 704b90757..78c3ca6e4 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -1,669 +1,673 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2016 The Bitcoin Core developers // Copyright (c) 2017-2020 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include #include #include #include #include #include #include static CBlock CreateGenesisBlock(const char *pszTimestamp, const CScript &genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const Amount genesisReward) { CMutableTransaction txNew; txNew.nVersion = 1; txNew.vin.resize(1); txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << std::vector((const uint8_t *)pszTimestamp, (const uint8_t *)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = genesisReward; txNew.vout[0].scriptPubKey = genesisOutputScript; CBlock genesis; genesis.nTime = nTime; genesis.nBits = nBits; genesis.nNonce = nNonce; genesis.nVersion = nVersion; genesis.vtx.push_back(MakeTransactionRef(std::move(txNew))); genesis.hashPrevBlock.SetNull(); genesis.hashMerkleRoot = BlockMerkleRoot(genesis); return genesis; } /** * Build the genesis block. Note that the output of its generation transaction * cannot be spent since it did not originally exist in the database. * * CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, * hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, * vtx=1) * CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0) * CTxIn(COutPoint(000000, -1), coinbase * 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73) * CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) * vMerkleTree: 4a5e1e */ CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const Amount genesisReward) { const char *pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; const CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909" "a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112" "de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward); } /** * Main network */ class CMainParams : public CChainParams { public: CMainParams() { strNetworkID = CBaseChainParams::MAIN; consensus.nSubsidyHalvingInterval = 210000; // 00000000000000ce80a7e057163a4db1d5ad7b20fb6f598c9597b9665c8fb0d4 - // April 1, 2012 consensus.BIP16Height = 173805; consensus.BIP34Height = 227931; consensus.BIP34Hash = BlockHash::fromHex( "000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8"); // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0 consensus.BIP65Height = 388381; // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931 consensus.BIP66Height = 363725; // 000000000000000004a1b34462cb8aeebd5799177f7a29cf28f2d1961716b5b5 consensus.CSVHeight = 419328; consensus.powLimit = uint256S( "00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // two weeks consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; consensus.nPowTargetSpacing = 10 * 60; consensus.fPowAllowMinDifficultyBlocks = false; consensus.fPowNoRetargeting = false; // nPowTargetTimespan / nPowTargetSpacing consensus.nMinerConfirmationWindow = 2016; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY] = { .bit = 28, // 95% of 2016 .nActivationThreshold = 1916, // January 1, 2008 .nStartTime = 1199145601, // December 31, 2008 .nTimeout = 1230767999, }; consensus.vDeployments[Consensus::DEPLOYEMENT_MINER_FUND] = { .bit = 0, // 66% of 2016 .nActivationThreshold = 1344, // Nov 15, 2019 12:00:00 UTC .nStartTime = 1573819200, // May 15, 2020 12:00:00 UTC .nTimeout = 1589544000, }; consensus.vDeployments[Consensus::DEPLOYEMENT_MINER_FUND_ABC] = { .bit = 1, // 66% of 2016 .nActivationThreshold = 1344, // Nov 15, 2019 12:00:00 UTC .nStartTime = 1573819200, // May 15, 2020 12:00:00 UTC .nTimeout = 1589544000, }; consensus.vDeployments[Consensus::DEPLOYEMENT_MINER_FUND_BCHD] = { .bit = 2, // 66% of 2016 .nActivationThreshold = 1344, // Nov 15, 2019 12:00:00 UTC .nStartTime = 1573819200, // May 15, 2020 12:00:00 UTC .nTimeout = 1589544000, }; consensus .vDeployments[Consensus::DEPLOYEMENT_MINER_FUND_ELECTRON_CASH] = { .bit = 3, // 66% of 2016 .nActivationThreshold = 1344, // Nov 15, 2019 12:00:00 UTC .nStartTime = 1573819200, // May 15, 2020 12:00:00 UTC .nTimeout = 1589544000, }; // The miner fund is enabled by default on mainnet. consensus.enableMinerFund = true; // The best chain should have at least this much work. consensus.nMinimumChainWork = ChainParamsConstants::MAINNET_MINIMUM_CHAIN_WORK; // By default assume that the signatures in ancestors of this block are // valid. consensus.defaultAssumeValid = ChainParamsConstants::MAINNET_DEFAULT_ASSUME_VALID; // August 1, 2017 hard fork consensus.uahfHeight = 478558; // November 13, 2017 hard fork consensus.daaHeight = 504031; // November 15, 2018 hard fork consensus.magneticAnomalyHeight = 556766; // November 15, 2019 protocol upgrade consensus.gravitonHeight = 609135; // May 15, 2020 12:00:00 UTC protocol upgrade consensus.phononActivationTime = 1589544000; // Nov 15, 2020 12:00:00 UTC protocol upgrade consensus.axionActivationTime = 1605441600; /** * The message start string is designed to be unlikely to occur in * normal data. The characters are rarely used upper ASCII, not valid as * UTF-8, and produce a large 32-bit integer with any alignment. */ diskMagic[0] = 0xf9; diskMagic[1] = 0xbe; diskMagic[2] = 0xb4; diskMagic[3] = 0xd9; netMagic[0] = 0xe3; netMagic[1] = 0xe1; netMagic[2] = 0xf3; 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); consensus.hashGenesisBlock = genesis.GetHash(); assert(consensus.hashGenesisBlock == uint256S("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1" "b60a8ce26f")); assert(genesis.hashMerkleRoot == uint256S("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b" "7afdeda33b")); // Note that of those which support the service bits prefix, most only // support a subset of possible options. This is fine at runtime as // we'll fall back to using them as a oneshot if they don't support the // service bits we want, but we should get them updated to support all // service bits wanted by any release ASAP to avoid it where possible. // Bitcoin ABC seeder vSeeds.emplace_back("seed.bitcoinabc.org"); // bitcoinforks seeders vSeeds.emplace_back("seed-abc.bitcoinforks.org"); // BU backed seeder vSeeds.emplace_back("btccash-seeder.bitcoinunlimited.info"); // Jason B. Cox vSeeds.emplace_back("seeder.jasonbcox.com"); // Amaury SÉCHET vSeeds.emplace_back("seed.deadalnix.me"); // BCHD vSeeds.emplace_back("seed.bchd.cash"); base58Prefixes[PUBKEY_ADDRESS] = std::vector(1, 0); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1, 5); base58Prefixes[SECRET_KEY] = std::vector(1, 128); base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E}; base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4}; cashaddrPrefix = "bitcoincash"; vFixedSeeds = std::vector( pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main)); fDefaultConsistencyChecks = false; fRequireStandard = true; m_is_test_chain = false; checkpointData = { .mapCheckpoints = { {11111, BlockHash::fromHex("0000000069e244f73d78e8fd29ba2fd2ed6" "18bd6fa2ee92559f542fdb26e7c1d")}, {33333, BlockHash::fromHex("000000002dd5588a74784eaa7ab0507a18a" "d16a236e7b1ce69f00d7ddfb5d0a6")}, {74000, BlockHash::fromHex("0000000000573993a3c9e41ce34471c079d" "cf5f52a0e824a81e7f953b8661a20")}, {105000, BlockHash::fromHex("00000000000291ce28027faea320c8d2b0" "54b2e0fe44a773f3eefb151d6bdc97")}, {134444, BlockHash::fromHex("00000000000005b12ffd4cd315cd34ffd4" "a594f430ac814c91184a0d42d2b0fe")}, {168000, BlockHash::fromHex("000000000000099e61ea72015e79632f21" "6fe6cb33d7899acb35b75c8303b763")}, {193000, BlockHash::fromHex("000000000000059f452a5f7340de6682a9" "77387c17010ff6e6c3bd83ca8b1317")}, {210000, BlockHash::fromHex("000000000000048b95347e83192f69cf03" "66076336c639f9b7228e9ba171342e")}, {216116, BlockHash::fromHex("00000000000001b4f4b433e81ee46494af" "945cf96014816a4e2370f11b23df4e")}, {225430, BlockHash::fromHex("00000000000001c108384350f74090433e" "7fcf79a606b8e797f065b130575932")}, {250000, BlockHash::fromHex("000000000000003887df1f29024b06fc22" "00b55f8af8f35453d7be294df2d214")}, {279000, BlockHash::fromHex("0000000000000001ae8c72a0b0c301f67e" "3afca10e819efa9041e458e9bd7e40")}, {295000, BlockHash::fromHex("00000000000000004d9b4ef50f0f9d686f" "d69db2e03af35a100370c64632a983")}, // UAHF fork block. {478558, BlockHash::fromHex("0000000000000000011865af4122fe3b14" "4e2cbeea86142e8ff2fb4107352d43")}, // Nov, 13 DAA activation block. {504031, BlockHash::fromHex("0000000000000000011ebf65b60d0a3de8" "0b8175be709d653b4c1a1beeb6ab9c")}, // Monolith activation. {530359, BlockHash::fromHex("0000000000000000011ada8bd08f46074f" "44a8f155396f43e38acf9501c49103")}, // Magnetic anomaly activation. {556767, BlockHash::fromHex("0000000000000000004626ff6e3b936941" "d341c5932ece4357eeccac44e6d56c")}, // Great wall activation. {582680, BlockHash::fromHex("000000000000000001b4b8e36aec7d4f96" "71a47872cb9a74dc16ca398c7dcc18")}, // Graviton activation. {609136, BlockHash::fromHex("000000000000000000b48bb207faac5ac6" "55c313e41ac909322eaa694f5bc5b1")}, // Phonon activation. {635259, BlockHash::fromHex("00000000000000000033dfef1fc2d6a5d5" "520b078c55193a9bf498c5b27530f7")}, }}; // Data as of block // 000000000000000001d2ce557406b017a928be25ee98906397d339c3f68eec5d // (height 523992). chainTxData = ChainTxData{ // UNIX timestamp of last known number of transactions. 1522608016, // Total number of transactions between genesis and that timestamp // (the tx=... number in the ChainStateFlushed debug.log lines) 248589038, // Estimated number of transactions per second after that timestamp. 3.2, }; } }; /** * Testnet (v3) */ class CTestNetParams : public CChainParams { public: CTestNetParams() { strNetworkID = CBaseChainParams::TESTNET; consensus.nSubsidyHalvingInterval = 210000; // 00000000040b4e986385315e14bee30ad876d8b47f748025b26683116d21aa65 consensus.BIP16Height = 514; consensus.BIP34Height = 21111; consensus.BIP34Hash = BlockHash::fromHex( "0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8"); // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6 consensus.BIP65Height = 581885; // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182 consensus.BIP66Height = 330776; // 00000000025e930139bac5c6c31a403776da130831ab85be56578f3fa75369bb consensus.CSVHeight = 770112; consensus.powLimit = uint256S( "00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // two weeks consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; consensus.nPowTargetSpacing = 10 * 60; consensus.fPowAllowMinDifficultyBlocks = true; consensus.fPowNoRetargeting = false; // nPowTargetTimespan / nPowTargetSpacing consensus.nMinerConfirmationWindow = 2016; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY] = { .bit = 28, // 75% of 2016 .nActivationThreshold = 1512, // January 1, 2008 .nStartTime = 1199145601, // December 31, 2008 .nTimeout = 1230767999, }; consensus.vDeployments[Consensus::DEPLOYEMENT_MINER_FUND] = { .bit = 0, // 66% of 2016 .nActivationThreshold = 1344, // Nov 15, 2019 12:00:00 UTC .nStartTime = 1573819200, // May 15, 2020 12:00:00 UTC .nTimeout = 1589544000, }; consensus.vDeployments[Consensus::DEPLOYEMENT_MINER_FUND_ABC] = { .bit = 1, // 66% of 2016 .nActivationThreshold = 1344, // Nov 15, 2019 12:00:00 UTC .nStartTime = 1573819200, // May 15, 2020 12:00:00 UTC .nTimeout = 1589544000, }; consensus.vDeployments[Consensus::DEPLOYEMENT_MINER_FUND_BCHD] = { .bit = 2, // 66% of 2016 .nActivationThreshold = 1344, // Nov 15, 2019 12:00:00 UTC .nStartTime = 1573819200, // May 15, 2020 12:00:00 UTC .nTimeout = 1589544000, }; consensus .vDeployments[Consensus::DEPLOYEMENT_MINER_FUND_ELECTRON_CASH] = { .bit = 3, // 66% of 2016 .nActivationThreshold = 1344, // Nov 15, 2019 12:00:00 UTC .nStartTime = 1573819200, // May 15, 2020 12:00:00 UTC .nTimeout = 1589544000, }; // The miner fund is disabled by default on testnet. consensus.enableMinerFund = false; // The best chain should have at least this much work. consensus.nMinimumChainWork = ChainParamsConstants::TESTNET_MINIMUM_CHAIN_WORK; // By default assume that the signatures in ancestors of this block are // valid. consensus.defaultAssumeValid = ChainParamsConstants::TESTNET_DEFAULT_ASSUME_VALID; // August 1, 2017 hard fork consensus.uahfHeight = 1155875; // November 13, 2017 hard fork consensus.daaHeight = 1188697; // November 15, 2018 hard fork consensus.magneticAnomalyHeight = 1267996; // November 15, 2019 protocol upgrade consensus.gravitonHeight = 1341711; // May 15, 2020 12:00:00 UTC protocol upgrade consensus.phononActivationTime = 1589544000; // Nov 15, 2020 12:00:00 UTC protocol upgrade consensus.axionActivationTime = 1605441600; diskMagic[0] = 0x0b; diskMagic[1] = 0x11; diskMagic[2] = 0x09; diskMagic[3] = 0x07; netMagic[0] = 0xf4; netMagic[1] = 0xe5; netMagic[2] = 0xf3; 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); consensus.hashGenesisBlock = genesis.GetHash(); assert(consensus.hashGenesisBlock == uint256S("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526" "f8d77f4943")); assert(genesis.hashMerkleRoot == uint256S("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b" "7afdeda33b")); vFixedSeeds.clear(); vSeeds.clear(); // nodes with support for servicebits filtering should be at the top // Bitcoin ABC seeder vSeeds.emplace_back("testnet-seed.bitcoinabc.org"); // bitcoinforks seeders vSeeds.emplace_back("testnet-seed-abc.bitcoinforks.org"); // Amaury SÉCHET vSeeds.emplace_back("testnet-seed.deadalnix.me"); // BCHD vSeeds.emplace_back("testnet-seed.bchd.cash"); base58Prefixes[PUBKEY_ADDRESS] = std::vector(1, 111); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1, 196); base58Prefixes[SECRET_KEY] = std::vector(1, 239); base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF}; base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94}; cashaddrPrefix = "bchtest"; vFixedSeeds = std::vector( pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test)); fDefaultConsistencyChecks = false; fRequireStandard = false; m_is_test_chain = true; checkpointData = { .mapCheckpoints = { {546, BlockHash::fromHex("000000002a936ca763904c3c35fce2f3556c5" "59c0214345d31b1bcebf76acb70")}, // UAHF fork block. {1155875, BlockHash::fromHex("00000000f17c850672894b9a75b63a1e72830bbd5f" "4c8889b5c1a80e7faef138")}, // Nov, 13. DAA activation block. {1188697, BlockHash::fromHex("0000000000170ed0918077bde7b4d36cc4c91be69f" "a09211f748240dabe047fb")}, // Great wall activation. {1303885, BlockHash::fromHex("00000000000000479138892ef0e4fa478ccc938fb9" "4df862ef5bde7e8dee23d3")}, // Graviton activation. {1341712, BlockHash::fromHex("00000000fffc44ea2e202bd905a9fbbb9491ef9e9d" "5a9eed4039079229afa35b")}, // Phonon activation. {1378461, BlockHash::fromHex( "0000000099f5509b5f36b1926bcf82b21d936ebeade" "e811030dfbbb7fae915d7")}, }}; // Data as of block // 000000000005b07ecf85563034d13efd81c1a29e47e22b20f4fc6919d5b09cd6 // (height 1223263) chainTxData = ChainTxData{1522608381, 15052068, 0.15}; } }; /** * Regression test */ class CRegTestParams : public CChainParams { public: CRegTestParams() { strNetworkID = CBaseChainParams::REGTEST; consensus.nSubsidyHalvingInterval = 150; // always enforce P2SH BIP16 on regtest consensus.BIP16Height = 0; // BIP34 has not activated on regtest (far in the future so block v1 are // not rejected in tests) consensus.BIP34Height = 100000000; consensus.BIP34Hash = BlockHash(); // BIP65 activated on regtest (Used in rpc activation tests) consensus.BIP65Height = 1351; // BIP66 activated on regtest (Used in rpc activation tests) consensus.BIP66Height = 1251; // CSV activated on regtest (Used in rpc activation tests) consensus.CSVHeight = 576; consensus.powLimit = uint256S( "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // two weeks consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; consensus.nPowTargetSpacing = 10 * 60; consensus.fPowAllowMinDifficultyBlocks = true; consensus.fPowNoRetargeting = true; // Faster than normal for regtest (144 instead of 2016) consensus.nMinerConfirmationWindow = 144; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY] = { .bit = 28, // 75% of 144 .nActivationThreshold = 108, }; consensus.vDeployments[Consensus::DEPLOYEMENT_MINER_FUND] = { .bit = 0, // 66% of 144 .nActivationThreshold = 96, // Nov 15, 2019 12:00:00 UTC .nStartTime = 1573819200, // May 15, 2020 12:00:00 UTC .nTimeout = 1589544000, }; consensus.vDeployments[Consensus::DEPLOYEMENT_MINER_FUND_ABC] = { .bit = 1, // 66% of 144 .nActivationThreshold = 96, // Nov 15, 2019 12:00:00 UTC .nStartTime = 1573819200, // May 15, 2020 12:00:00 UTC .nTimeout = 1589544000, }; consensus.vDeployments[Consensus::DEPLOYEMENT_MINER_FUND_BCHD] = { .bit = 2, // 66% of 144 .nActivationThreshold = 96, // Nov 15, 2019 12:00:00 UTC .nStartTime = 1573819200, // May 15, 2020 12:00:00 UTC .nTimeout = 1589544000, }; consensus .vDeployments[Consensus::DEPLOYEMENT_MINER_FUND_ELECTRON_CASH] = { .bit = 3, // 66% of 144 .nActivationThreshold = 96, // Nov 15, 2019 12:00:00 UTC .nStartTime = 1573819200, // May 15, 2020 12:00:00 UTC .nTimeout = 1589544000, }; // The miner fund is disabled by default on regnet. consensus.enableMinerFund = false; // The best chain should have at least this much work. consensus.nMinimumChainWork = uint256S("0x00"); // By default assume that the signatures in ancestors of this block are // valid. consensus.defaultAssumeValid = BlockHash(); // UAHF is always enabled on regtest. consensus.uahfHeight = 0; // November 13, 2017 hard fork is always on on regtest. consensus.daaHeight = 0; // November 15, 2018 hard fork is always on on regtest. consensus.magneticAnomalyHeight = 0; // November 15, 2019 protocol upgrade consensus.gravitonHeight = 0; // May 15, 2020 12:00:00 UTC protocol upgrade consensus.phononActivationTime = 1589544000; // Nov 15, 2020 12:00:00 UTC protocol upgrade consensus.axionActivationTime = 1605441600; diskMagic[0] = 0xfa; diskMagic[1] = 0xbf; diskMagic[2] = 0xb5; diskMagic[3] = 0xda; netMagic[0] = 0xda; netMagic[1] = 0xb5; netMagic[2] = 0xbf; netMagic[3] = 0xfa; nDefaultPort = 18444; nPruneAfterHeight = 1000; m_assumed_blockchain_size = 0; m_assumed_chain_state_size = 0; genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b" "1a11466e2206")); assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab212" "7b7afdeda33b")); //! Regtest mode doesn't have any fixed seeds. vFixedSeeds.clear(); //! Regtest mode doesn't have any DNS seeds. vSeeds.clear(); fDefaultConsistencyChecks = true; fRequireStandard = true; m_is_test_chain = true; checkpointData = { .mapCheckpoints = { {0, BlockHash::fromHex("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb4" "36012afca590b1a11466e2206")}, }}; chainTxData = ChainTxData{0, 0, 0}; base58Prefixes[PUBKEY_ADDRESS] = std::vector(1, 111); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1, 196); base58Prefixes[SECRET_KEY] = std::vector(1, 239); base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF}; base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94}; cashaddrPrefix = "bchreg"; } }; static std::unique_ptr globalChainParams; const CChainParams &Params() { assert(globalChainParams); return *globalChainParams; } std::unique_ptr CreateChainParams(const std::string &chain) { if (chain == CBaseChainParams::MAIN) { return std::make_unique(); } if (chain == CBaseChainParams::TESTNET) { return std::make_unique(); } if (chain == CBaseChainParams::REGTEST) { return std::make_unique(); } throw std::runtime_error( strprintf("%s: Unknown chain %s.", __func__, chain)); } void SelectParams(const std::string &network) { SelectBaseParams(network); globalChainParams = CreateChainParams(network); } diff --git a/src/chainparamsconstants.h b/src/chainparamsconstants.h index c3a4ccd16..a8234ab4d 100644 --- a/src/chainparamsconstants.h +++ b/src/chainparamsconstants.h @@ -1,19 +1,23 @@ #ifndef BITCOIN_CHAINPARAMSCONSTANTS_H #define BITCOIN_CHAINPARAMSCONSTANTS_H /** * Chain params constants for each tracked chain. * @generated by contrib/devtools/chainparams/generate_chainparams_constants.py */ #include #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