From 010a0e553a51dc7cfe6ccd78dd5caada4a971195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Thu, 22 Aug 2019 18:17:31 +0200 Subject: [PATCH 01/31] Tests: Use self.chain instead of 'regtest' in all current tests --- test/functional/feature_abortnode.py | 2 +- test/functional/feature_config_args.py | 12 +++++------ test/functional/feature_filelock.py | 2 +- test/functional/feature_logging.py | 2 +- test/functional/feature_pruning.py | 4 ++-- test/functional/interface_rpc.py | 2 +- test/functional/mempool_persist.py | 4 ++-- test/functional/mining_basic.py | 2 +- test/functional/rpc_scantxoutset.py | 2 +- test/functional/tool_wallet.py | 2 +- test/functional/wallet_backup.py | 28 ++++++++++++------------- test/functional/wallet_hd.py | 14 ++++++------- test/functional/wallet_keypool_topup.py | 2 +- test/functional/wallet_multiwallet.py | 4 ++-- test/functional/wallet_reorgsrestore.py | 2 +- 15 files changed, 42 insertions(+), 42 deletions(-) diff --git a/test/functional/feature_abortnode.py b/test/functional/feature_abortnode.py index 62c3eca07defd..874243ec5d633 100755 --- a/test/functional/feature_abortnode.py +++ b/test/functional/feature_abortnode.py @@ -29,7 +29,7 @@ def run_test(self): datadir = get_datadir_path(self.options.tmpdir, 0) # Deleting the undo file will result in reorg failure - os.unlink(os.path.join(datadir, 'regtest', 'blocks', 'rev00000.dat')) + os.unlink(os.path.join(datadir, self.chain, 'blocks', 'rev00000.dat')) # Connecting to a node with a more work chain will trigger a reorg # attempt. diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py index b997c760257d8..1b1ff14151e15 100755 --- a/test/functional/feature_config_args.py +++ b/test/functional/feature_config_args.py @@ -38,7 +38,7 @@ def test_config_file_parser(self): if self.is_wallet_compiled(): with open(inc_conf_file_path, 'w', encoding='utf8') as conf: conf.write("wallet=foo\n") - self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Config setting for -wallet only applied on regtest network when in [regtest] section.') + self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Config setting for -wallet only applied on %s network when in [%s] section.' % (self.chain, self.chain)) with open(inc_conf_file_path, 'w', encoding='utf-8') as conf: conf.write('regtest=0\n') # mainnet @@ -103,7 +103,7 @@ def run_test(self): # Check that using non-existent datadir in conf file fails conf_file = os.path.join(default_data_dir, "bitcoin.conf") - # datadir needs to be set before [regtest] section + # datadir needs to be set before [chain] section conf_file_contents = open(conf_file, encoding='utf8').read() with open(conf_file, 'w', encoding='utf8') as f: f.write("datadir=" + new_data_dir + "\n") @@ -115,17 +115,17 @@ def run_test(self): os.mkdir(new_data_dir) self.start_node(0, ['-conf='+conf_file, '-wallet=w1']) self.stop_node(0) - assert os.path.exists(os.path.join(new_data_dir, 'regtest', 'blocks')) + assert os.path.exists(os.path.join(new_data_dir, self.chain, 'blocks')) if self.is_wallet_compiled(): - assert os.path.exists(os.path.join(new_data_dir, 'regtest', 'wallets', 'w1')) + assert os.path.exists(os.path.join(new_data_dir, self.chain, 'wallets', 'w1')) # Ensure command line argument overrides datadir in conf os.mkdir(new_data_dir_2) self.nodes[0].datadir = new_data_dir_2 self.start_node(0, ['-datadir='+new_data_dir_2, '-conf='+conf_file, '-wallet=w2']) - assert os.path.exists(os.path.join(new_data_dir_2, 'regtest', 'blocks')) + assert os.path.exists(os.path.join(new_data_dir_2, self.chain, 'blocks')) if self.is_wallet_compiled(): - assert os.path.exists(os.path.join(new_data_dir_2, 'regtest', 'wallets', 'w2')) + assert os.path.exists(os.path.join(new_data_dir_2, self.chain, 'wallets', 'w2')) if __name__ == '__main__': diff --git a/test/functional/feature_filelock.py b/test/functional/feature_filelock.py index ba116e41f5df5..89843f84f7c9e 100755 --- a/test/functional/feature_filelock.py +++ b/test/functional/feature_filelock.py @@ -19,7 +19,7 @@ def setup_network(self): self.nodes[0].wait_for_rpc_connection() def run_test(self): - datadir = os.path.join(self.nodes[0].datadir, 'regtest') + datadir = os.path.join(self.nodes[0].datadir, self.chain) self.log.info("Using datadir {}".format(datadir)) self.log.info("Check that we can't start a second bitcoind instance using the same datadir") diff --git a/test/functional/feature_logging.py b/test/functional/feature_logging.py index e6ff21ee9c5ce..4065572510bc1 100755 --- a/test/functional/feature_logging.py +++ b/test/functional/feature_logging.py @@ -16,7 +16,7 @@ def set_test_params(self): self.setup_clean_chain = True def relative_log_path(self, name): - return os.path.join(self.nodes[0].datadir, "regtest", name) + return os.path.join(self.nodes[0].datadir, self.chain, name) def run_test(self): # test default log file name diff --git a/test/functional/feature_pruning.py b/test/functional/feature_pruning.py index 727f4b9589e94..b263232622127 100755 --- a/test/functional/feature_pruning.py +++ b/test/functional/feature_pruning.py @@ -99,7 +99,7 @@ def skip_test_if_missing_module(self): def setup_network(self): self.setup_nodes() - self.prunedir = os.path.join(self.nodes[2].datadir, 'regtest', 'blocks', '') + self.prunedir = os.path.join(self.nodes[2].datadir, self.chain, 'blocks', '') connect_nodes(self.nodes[0], 1) connect_nodes(self.nodes[1], 2) @@ -277,7 +277,7 @@ def prune(index): assert_equal(ret, node.getblockchaininfo()['pruneheight']) def has_block(index): - return os.path.isfile(os.path.join(self.nodes[node_number].datadir, "regtest", "blocks", "blk{:05}.dat".format(index))) + return os.path.isfile(os.path.join(self.nodes[node_number].datadir, self.chain, "blocks", "blk{:05}.dat".format(index))) # should not prune because chain tip of node 3 (995) < PruneAfterHeight (1000) assert_raises_rpc_error(-1, "Blockchain is too short for pruning", node.pruneblockchain, height(500)) diff --git a/test/functional/interface_rpc.py b/test/functional/interface_rpc.py index e99fa2264660f..62f5cd2771506 100755 --- a/test/functional/interface_rpc.py +++ b/test/functional/interface_rpc.py @@ -32,7 +32,7 @@ def test_getrpcinfo(self): command = info['active_commands'][0] assert_equal(command['method'], 'getrpcinfo') assert_greater_than_or_equal(command['duration'], 0) - assert_equal(info['logpath'], os.path.join(self.nodes[0].datadir, 'regtest', 'debug.log')) + assert_equal(info['logpath'], os.path.join(self.nodes[0].datadir, self.chain, 'debug.log')) def test_batch_request(self): self.log.info("Testing basic JSON-RPC batch request...") diff --git a/test/functional/mempool_persist.py b/test/functional/mempool_persist.py index bb0169ee52860..4c9cd76239ded 100755 --- a/test/functional/mempool_persist.py +++ b/test/functional/mempool_persist.py @@ -109,8 +109,8 @@ def run_test(self): wait_until(lambda: self.nodes[0].getmempoolinfo()["loaded"]) assert_equal(len(self.nodes[0].getrawmempool()), 5) - mempooldat0 = os.path.join(self.nodes[0].datadir, 'regtest', 'mempool.dat') - mempooldat1 = os.path.join(self.nodes[1].datadir, 'regtest', 'mempool.dat') + mempooldat0 = os.path.join(self.nodes[0].datadir, self.chain, 'mempool.dat') + mempooldat1 = os.path.join(self.nodes[1].datadir, self.chain, 'mempool.dat') self.log.debug("Remove the mempool.dat file. Verify that savemempool to disk via RPC re-creates it") os.remove(mempooldat0) self.nodes[0].savemempool() diff --git a/test/functional/mining_basic.py b/test/functional/mining_basic.py index 788aabc192c0e..934db53f29fd5 100755 --- a/test/functional/mining_basic.py +++ b/test/functional/mining_basic.py @@ -69,7 +69,7 @@ def assert_submitblock(block, result_str_1, result_str_2=None): self.log.info('getmininginfo') mining_info = node.getmininginfo() assert_equal(mining_info['blocks'], 200) - assert_equal(mining_info['chain'], 'regtest') + assert_equal(mining_info['chain'], self.chain) assert 'currentblocktx' not in mining_info assert 'currentblockweight' not in mining_info assert_equal(mining_info['difficulty'], Decimal('4.656542373906925E-10')) diff --git a/test/functional/rpc_scantxoutset.py b/test/functional/rpc_scantxoutset.py index 9f94d11a93f23..e08731dc97708 100755 --- a/test/functional/rpc_scantxoutset.py +++ b/test/functional/rpc_scantxoutset.py @@ -54,7 +54,7 @@ def run_test(self): self.log.info("Stop node, remove wallet, mine again some blocks...") self.stop_node(0) - shutil.rmtree(os.path.join(self.nodes[0].datadir, "regtest", 'wallets')) + shutil.rmtree(os.path.join(self.nodes[0].datadir, self.chain, 'wallets')) self.start_node(0) self.nodes[0].generate(110) diff --git a/test/functional/tool_wallet.py b/test/functional/tool_wallet.py index 28a65f7823894..f67279fcd2799 100755 --- a/test/functional/tool_wallet.py +++ b/test/functional/tool_wallet.py @@ -196,7 +196,7 @@ def test_getwalletinfo_on_different_wallet(self): self.log.debug('Wallet file shasum unchanged\n') def run_test(self): - self.wallet_path = os.path.join(self.nodes[0].datadir, 'regtest', 'wallets', 'wallet.dat') + self.wallet_path = os.path.join(self.nodes[0].datadir, self.chain, 'wallets', 'wallet.dat') self.test_invalid_tool_commands_and_args() # Warning: The following tests are order-dependent. self.test_tool_wallet_info() diff --git a/test/functional/wallet_backup.py b/test/functional/wallet_backup.py index 55c517e92f98c..d25f3d1789c5d 100755 --- a/test/functional/wallet_backup.py +++ b/test/functional/wallet_backup.py @@ -100,9 +100,9 @@ def stop_three(self): self.stop_node(2) def erase_three(self): - os.remove(os.path.join(self.nodes[0].datadir, 'regtest', 'wallets', 'wallet.dat')) - os.remove(os.path.join(self.nodes[1].datadir, 'regtest', 'wallets', 'wallet.dat')) - os.remove(os.path.join(self.nodes[2].datadir, 'regtest', 'wallets', 'wallet.dat')) + os.remove(os.path.join(self.nodes[0].datadir, self.chain, 'wallets', 'wallet.dat')) + os.remove(os.path.join(self.nodes[1].datadir, self.chain, 'wallets', 'wallet.dat')) + os.remove(os.path.join(self.nodes[2].datadir, self.chain, 'wallets', 'wallet.dat')) def run_test(self): self.log.info("Generating initial blockchain") @@ -160,13 +160,13 @@ def run_test(self): self.erase_three() # Start node2 with no chain - shutil.rmtree(os.path.join(self.nodes[2].datadir, 'regtest', 'blocks')) - shutil.rmtree(os.path.join(self.nodes[2].datadir, 'regtest', 'chainstate')) + shutil.rmtree(os.path.join(self.nodes[2].datadir, self.chain, 'blocks')) + shutil.rmtree(os.path.join(self.nodes[2].datadir, self.chain, 'chainstate')) # Restore wallets from backup - shutil.copyfile(os.path.join(self.nodes[0].datadir, 'wallet.bak'), os.path.join(self.nodes[0].datadir, 'regtest', 'wallets', 'wallet.dat')) - shutil.copyfile(os.path.join(self.nodes[1].datadir, 'wallet.bak'), os.path.join(self.nodes[1].datadir, 'regtest', 'wallets', 'wallet.dat')) - shutil.copyfile(os.path.join(self.nodes[2].datadir, 'wallet.bak'), os.path.join(self.nodes[2].datadir, 'regtest', 'wallets', 'wallet.dat')) + shutil.copyfile(os.path.join(self.nodes[0].datadir, 'wallet.bak'), os.path.join(self.nodes[0].datadir, self.chain, 'wallets', 'wallet.dat')) + shutil.copyfile(os.path.join(self.nodes[1].datadir, 'wallet.bak'), os.path.join(self.nodes[1].datadir, self.chain, 'wallets', 'wallet.dat')) + shutil.copyfile(os.path.join(self.nodes[2].datadir, 'wallet.bak'), os.path.join(self.nodes[2].datadir, self.chain, 'wallets', 'wallet.dat')) self.log.info("Re-starting nodes") self.start_three() @@ -181,8 +181,8 @@ def run_test(self): self.erase_three() #start node2 with no chain - shutil.rmtree(os.path.join(self.nodes[2].datadir, 'regtest', 'blocks')) - shutil.rmtree(os.path.join(self.nodes[2].datadir, 'regtest', 'chainstate')) + shutil.rmtree(os.path.join(self.nodes[2].datadir, self.chain, 'blocks')) + shutil.rmtree(os.path.join(self.nodes[2].datadir, self.chain, 'chainstate')) self.start_three() @@ -202,10 +202,10 @@ def run_test(self): # Backup to source wallet file must fail sourcePaths = [ - os.path.join(self.nodes[0].datadir, 'regtest', 'wallets', 'wallet.dat'), - os.path.join(self.nodes[0].datadir, 'regtest', '.', 'wallets', 'wallet.dat'), - os.path.join(self.nodes[0].datadir, 'regtest', 'wallets', ''), - os.path.join(self.nodes[0].datadir, 'regtest', 'wallets')] + os.path.join(self.nodes[0].datadir, self.chain, 'wallets', 'wallet.dat'), + os.path.join(self.nodes[0].datadir, self.chain, '.', 'wallets', 'wallet.dat'), + os.path.join(self.nodes[0].datadir, self.chain, 'wallets', ''), + os.path.join(self.nodes[0].datadir, self.chain, 'wallets')] for sourcePath in sourcePaths: assert_raises_rpc_error(-4, "backup failed", self.nodes[0].backupwallet, sourcePath) diff --git a/test/functional/wallet_hd.py b/test/functional/wallet_hd.py index 97172d8b82d1d..423bd56913516 100755 --- a/test/functional/wallet_hd.py +++ b/test/functional/wallet_hd.py @@ -67,11 +67,11 @@ def run_test(self): self.log.info("Restore backup ...") self.stop_node(1) - # we need to delete the complete regtest directory + # we need to delete the complete chain directory # otherwise node1 would auto-recover all funds in flag the keypool keys as used - shutil.rmtree(os.path.join(self.nodes[1].datadir, "regtest", "blocks")) - shutil.rmtree(os.path.join(self.nodes[1].datadir, "regtest", "chainstate")) - shutil.copyfile(os.path.join(self.nodes[1].datadir, "hd.bak"), os.path.join(self.nodes[1].datadir, "regtest", "wallets", "wallet.dat")) + shutil.rmtree(os.path.join(self.nodes[1].datadir, self.chain, "blocks")) + shutil.rmtree(os.path.join(self.nodes[1].datadir, self.chain, "chainstate")) + shutil.copyfile(os.path.join(self.nodes[1].datadir, "hd.bak"), os.path.join(self.nodes[1].datadir, self.chain, "wallets", "wallet.dat")) self.start_node(1) # Assert that derivation is deterministic @@ -92,9 +92,9 @@ def run_test(self): # Try a RPC based rescan self.stop_node(1) - shutil.rmtree(os.path.join(self.nodes[1].datadir, "regtest", "blocks")) - shutil.rmtree(os.path.join(self.nodes[1].datadir, "regtest", "chainstate")) - shutil.copyfile(os.path.join(self.nodes[1].datadir, "hd.bak"), os.path.join(self.nodes[1].datadir, "regtest", "wallets", "wallet.dat")) + shutil.rmtree(os.path.join(self.nodes[1].datadir, self.chain, "blocks")) + shutil.rmtree(os.path.join(self.nodes[1].datadir, self.chain, "chainstate")) + shutil.copyfile(os.path.join(self.nodes[1].datadir, "hd.bak"), os.path.join(self.nodes[1].datadir, self.chain, "wallets", "wallet.dat")) self.start_node(1, extra_args=self.extra_args[1]) connect_nodes_bi(self.nodes, 0, 1) self.sync_all() diff --git a/test/functional/wallet_keypool_topup.py b/test/functional/wallet_keypool_topup.py index 0014555ade7af..1e3476d64c4a2 100755 --- a/test/functional/wallet_keypool_topup.py +++ b/test/functional/wallet_keypool_topup.py @@ -30,7 +30,7 @@ def skip_test_if_missing_module(self): self.skip_if_no_wallet() def run_test(self): - wallet_path = os.path.join(self.nodes[1].datadir, "regtest", "wallets", "wallet.dat") + wallet_path = os.path.join(self.nodes[1].datadir, self.chain, "wallets", "wallet.dat") wallet_backup_path = os.path.join(self.nodes[1].datadir, "wallet.bak") self.nodes[0].generate(101) diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py index 68bc45f9861d3..a089a1534ae7c 100755 --- a/test/functional/wallet_multiwallet.py +++ b/test/functional/wallet_multiwallet.py @@ -39,7 +39,7 @@ def add_options(self, parser): def run_test(self): node = self.nodes[0] - data_dir = lambda *p: os.path.join(node.datadir, 'regtest', *p) + data_dir = lambda *p: os.path.join(node.datadir, self.chain, *p) wallet_dir = lambda *p: data_dir('wallets', *p) wallet = lambda name: node.get_wallet_rpc(name) @@ -187,7 +187,7 @@ def wallet_file(name): assert_equal(w4.getbalance(), 3) batch = w1.batch([w1.getblockchaininfo.get_request(), w1.getwalletinfo.get_request()]) - assert_equal(batch[0]["result"]["chain"], "regtest") + assert_equal(batch[0]["result"]["chain"], self.chain) assert_equal(batch[1]["result"]["walletname"], "w1") self.log.info('Check for per-wallet settxfee call') diff --git a/test/functional/wallet_reorgsrestore.py b/test/functional/wallet_reorgsrestore.py index f48018e9fbe8f..497a5dd95e444 100755 --- a/test/functional/wallet_reorgsrestore.py +++ b/test/functional/wallet_reorgsrestore.py @@ -90,7 +90,7 @@ def run_test(self): # Node0 wallet file is loaded on longest sync'ed node1 self.stop_node(1) self.nodes[0].backupwallet(os.path.join(self.nodes[0].datadir, 'wallet.bak')) - shutil.copyfile(os.path.join(self.nodes[0].datadir, 'wallet.bak'), os.path.join(self.nodes[1].datadir, 'regtest', 'wallet.dat')) + shutil.copyfile(os.path.join(self.nodes[0].datadir, 'wallet.bak'), os.path.join(self.nodes[1].datadir, self.chain, 'wallet.dat')) self.start_node(1) tx_after_reorg = self.nodes[1].gettransaction(txid) # Check that normal confirmed tx is confirmed again but with different blockhash From e80f6cae1d39e44f2b2642e07e6482c119903d04 Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Mon, 7 Nov 2016 14:03:42 -0500 Subject: [PATCH 02/31] 9102: Really don't validate genesis block --- src/txdb.cpp | 8 +++++--- src/validation.cpp | 34 +++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index 18be07e6dbb02..18c12dd66281a 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -274,9 +274,11 @@ bool CBlockTreeDB::LoadBlockIndexGuts(const Consensus::Params& consensusParams, pindexNew->nStatus = diskindex.nStatus; pindexNew->nTx = diskindex.nTx; - if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits, consensusParams)) - return error("%s: CheckProofOfWork failed: %s", __func__, pindexNew->ToString()); - + const uint256 block_hash = pindexNew->GetBlockHash(); + if (!CheckProofOfWork(block_hash, pindexNew->nBits, consensusParams) && + block_hash != consensusParams.hashGenesisBlock) { + return error("%s: CheckProofOfWork: %s, %s", __func__, block_hash.ToString(), pindexNew->ToString()); + } pcursor->Next(); } else { return error("%s: failed to read value", __func__); diff --git a/src/validation.cpp b/src/validation.cpp index d470fd5b6ebbf..772e0fd67199a 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1009,8 +1009,11 @@ bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::P } // Check the header - if (!CheckProofOfWork(block.GetHash(), block.nBits, consensusParams)) + const uint256 block_hash = block.GetHash(); + if (!CheckProofOfWork(block_hash, block.nBits, consensusParams) && + block_hash != consensusParams.hashGenesisBlock) { return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString()); + } return true; } @@ -1752,6 +1755,18 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl assert(*pindex->phashBlock == block.GetHash()); int64_t nTimeStart = GetTimeMicros(); + // verify that the view's current state corresponds to the previous block + const uint256 hashPrevBlock = pindex->pprev == nullptr ? uint256() : pindex->pprev->GetBlockHash(); + assert(hashPrevBlock == view.GetBestBlock()); + + // Special case for the genesis block, skipping connection of its transactions + // (its coinbase is unspendable) + if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) { + if (!fJustCheck) + view.SetBestBlock(pindex->GetBlockHash()); + return true; + } + // Check it again in case a previous version let a bad block in // NOTE: We don't currently (re-)invoke ContextualCheckBlock() or // ContextualCheckBlockHeader() here. This means that if we add a new @@ -1775,18 +1790,6 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); } - // verify that the view's current state corresponds to the previous block - uint256 hashPrevBlock = pindex->pprev == nullptr ? uint256() : pindex->pprev->GetBlockHash(); - assert(hashPrevBlock == view.GetBestBlock()); - - // Special case for the genesis block, skipping connection of its transactions - // (its coinbase is unspendable) - if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) { - if (!fJustCheck) - view.SetBestBlock(pindex->GetBlockHash()); - return true; - } - nBlocksTotal++; bool fScriptChecks = true; @@ -3515,8 +3518,9 @@ bool CChainState::AcceptBlock(const std::shared_ptr& pblock, CVali if (pindex->nChainWork < nMinimumChainWork) return true; } - if (!CheckBlock(block, state, chainparams.GetConsensus()) || - !ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindex->pprev)) { + if (chainparams.GetConsensus().hashGenesisBlock != block.GetHash() && + (!CheckBlock(block, state, chainparams.GetConsensus()) || + !ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindex->pprev))) { assert(IsBlockReason(state.GetReason())); if (state.IsInvalid() && state.GetReason() != ValidationInvalidReason::BLOCK_MUTATED) { pindex->nStatus |= BLOCK_FAILED_VALID; From 628eddac688c4707d1fb3cb32abf6c8b9133edb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Thu, 20 Dec 2018 20:39:38 +0100 Subject: [PATCH 03/31] Config: Allow any chain/section name --- src/init.cpp | 5 ----- src/util/system.cpp | 15 --------------- src/util/system.h | 5 ----- test/functional/feature_config_args.py | 13 ------------- 4 files changed, 38 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index bb82130542dea..41183a13d7397 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -938,11 +938,6 @@ bool AppInitParameterInteraction() return InitError(strprintf(_("Config setting for %s only applied on %s network when in [%s] section.").translated, arg, network, network)); } - // Warn if unrecognized section name are present in the config file. - for (const auto& section : gArgs.GetUnrecognizedSections()) { - InitWarning(strprintf("%s:%i " + _("Section [%s] is not recognized.").translated, section.m_file, section.m_line, section.m_name)); - } - if (!fs::is_directory(GetBlocksDir())) { return InitError(strprintf(_("Specified blocks directory \"%s\" does not exist.").translated, gArgs.GetArg("-blocksdir", "").c_str())); } diff --git a/src/util/system.cpp b/src/util/system.cpp index 8098cde093830..00db76325eac6 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -352,21 +352,6 @@ const std::set ArgsManager::GetUnsuitableSectionOnlyArgs() const return unsuitables; } -const std::list ArgsManager::GetUnrecognizedSections() const -{ - // Section names to be recognized in the config file. - static const std::set available_sections{ - CBaseChainParams::REGTEST, - CBaseChainParams::TESTNET, - CBaseChainParams::MAIN - }; - - LOCK(cs_args); - std::list unrecognized = m_config_sections; - unrecognized.remove_if([](const SectionInfo& appeared){ return available_sections.find(appeared.m_name) != available_sections.end(); }); - return unrecognized; -} - void ArgsManager::SelectConfigNetwork(const std::string& network) { LOCK(cs_args); diff --git a/src/util/system.h b/src/util/system.h index 908a3c407d3a8..44efa2219b8ea 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -185,11 +185,6 @@ class ArgsManager */ const std::set GetUnsuitableSectionOnlyArgs() const; - /** - * Log warnings for unrecognized section names in the config file. - */ - const std::list GetUnrecognizedSections() const; - /** * Return a vector of strings of the given argument * diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py index 1b1ff14151e15..06a8d5b7eef9d 100755 --- a/test/functional/feature_config_args.py +++ b/test/functional/feature_config_args.py @@ -61,20 +61,7 @@ def test_config_file_parser(self): conf.write('server=1\nrpcuser=someuser\n[main]\nrpcpassword=some#pass') self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Error reading configuration file: parse error on line 4, using # in rpcpassword can be ambiguous and should be avoided') - inc_conf_file2_path = os.path.join(self.nodes[0].datadir, 'include2.conf') - with open(os.path.join(self.nodes[0].datadir, 'bitcoin.conf'), 'a', encoding='utf-8') as conf: - conf.write('includeconf={}\n'.format(inc_conf_file2_path)) - with open(inc_conf_file_path, 'w', encoding='utf-8') as conf: - conf.write('testnot.datadir=1\n') - with open(inc_conf_file2_path, 'w', encoding='utf-8') as conf: - conf.write('[testnet]\n') - self.restart_node(0) - self.nodes[0].stop_node(expected_stderr='Warning: ' + inc_conf_file_path + ':1 Section [testnot] is not recognized.' + os.linesep + 'Warning: ' + inc_conf_file2_path + ':1 Section [testnet] is not recognized.') - - with open(inc_conf_file_path, 'w', encoding='utf-8') as conf: - conf.write('') # clear - with open(inc_conf_file2_path, 'w', encoding='utf-8') as conf: conf.write('') # clear def test_log_buffer(self): From d5ec6ffbfd63e6c5d07bd532d0eea5ed81f12b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Fri, 21 Oct 2016 19:15:26 +0200 Subject: [PATCH 04/31] Testchains: Qt: Introduce custom chain whose constructor... ...reads params from regular arguments Qt: Add a default purple and title for unkown chains --- src/chainparams.cpp | 92 +++++++++++++++++++++++++++++++++++++++-- src/chainparamsbase.cpp | 40 +++++++++++++++--- src/qt/guiconstants.h | 1 + src/qt/networkstyle.cpp | 2 +- 4 files changed, 125 insertions(+), 10 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index ad766471dc133..de4ada8a280c5 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -17,13 +18,13 @@ #include #include -static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) +static CBlock CreateGenesisBlock(const CScript& coinbase_sig, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& 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 unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vin[0].scriptSig = coinbase_sig; txNew.vout[0].nValue = genesisReward; txNew.vout[0].scriptPubKey = genesisOutputScript; @@ -52,8 +53,16 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) { const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; + const CScript coinbase_sig = CScript() << 486604799 << CScriptNum(4) << std::vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + const CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; - return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward); + return CreateGenesisBlock(coinbase_sig, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward); +} + +static CBlock CreateGenesisBlockWithHash(const uint256& hash) +{ + CScript coinbase_sig = CScript() << std::vector(hash.begin(), hash.end()); + return CreateGenesisBlock(coinbase_sig, CScript(OP_RETURN), 1296688602, 2, 0x207fffff, 1, 50 * COIN); } /** @@ -376,6 +385,79 @@ void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args) } } +/** + * Custom params for testing. + */ +class CCustomParams : public CRegTestParams { + void UpdateFromArgs(ArgsManager& args) + { + UpdateActivationParametersFromArgs(args); + + consensus.nSubsidyHalvingInterval = args.GetArg("-con_nsubsidyhalvinginterval", consensus.nSubsidyHalvingInterval); + consensus.BIP16Exception = uint256S(args.GetArg("-con_bip16exception", "0x0")); + consensus.BIP34Height = args.GetArg("-con_bip34height", consensus.BIP34Height); + consensus.BIP34Hash = uint256S(args.GetArg("-con_bip34hash", "0x0")); + consensus.BIP65Height = args.GetArg("-con_bip65height", consensus.BIP65Height); + consensus.BIP66Height = args.GetArg("-con_bip66height", consensus.BIP66Height); + consensus.powLimit = uint256S(args.GetArg("-con_powlimit", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); + consensus.nPowTargetTimespan = args.GetArg("-con_npowtargettimespan", consensus.nPowTargetTimespan); + consensus.nPowTargetSpacing = args.GetArg("-con_npowtargetspacing", consensus.nPowTargetSpacing); + consensus.fPowAllowMinDifficultyBlocks = args.GetBoolArg("-con_fpowallowmindifficultyblocks", consensus.fPowAllowMinDifficultyBlocks); + consensus.fPowNoRetargeting = args.GetBoolArg("-con_fpownoretargeting", consensus.fPowNoRetargeting); + consensus.nRuleChangeActivationThreshold = (uint32_t)args.GetArg("-con_nrulechangeactivationthreshold", consensus.nRuleChangeActivationThreshold); + consensus.nMinerConfirmationWindow = (uint32_t)args.GetArg("-con_nminerconfirmationwindow", consensus.nMinerConfirmationWindow); + + consensus.nMinimumChainWork = uint256S(args.GetArg("-con_nminimumchainwork", "0x0")); + consensus.defaultAssumeValid = uint256S(args.GetArg("-con_defaultassumevalid", "0x00")); + + nDefaultPort = (uint64_t)args.GetArg("-ndefaultport", nDefaultPort); + nPruneAfterHeight = (uint64_t)args.GetArg("-npruneafterheight", nPruneAfterHeight); + m_assumed_blockchain_size = (uint64_t)args.GetArg("-assumed_blockchain_size", m_assumed_blockchain_size); + m_assumed_chain_state_size = (uint64_t)args.GetArg("-assumed_chain_state_size", m_assumed_chain_state_size); + fDefaultConsistencyChecks = args.GetBoolArg("-fdefaultconsistencychecks", fDefaultConsistencyChecks); + fRequireStandard = args.GetBoolArg("-frequirestandard", fRequireStandard); + m_is_test_chain = args.GetBoolArg("-is_test_chain", m_is_test_chain); + + bech32_hrp = args.GetArg("-bech32_hrp", bech32_hrp); + base58Prefixes[PUBKEY_ADDRESS] = std::vector(1, args.GetArg("-pubkeyprefix", 111)); + base58Prefixes[SCRIPT_ADDRESS] = std::vector(1, args.GetArg("-scriptprefix", 196)); + base58Prefixes[SECRET_KEY] = std::vector(1, args.GetArg("-secretprefix", 239)); + + const std::string extpubprefix = args.GetArg("-extpubkeyprefix", "043587CF"); + assert(IsHex(extpubprefix) && extpubprefix.size() == 8 && "-extpubkeyprefix must be hex string of length 8"); + base58Prefixes[EXT_PUBLIC_KEY] = ParseHex(extpubprefix); + + const std::string extprvprefix = args.GetArg("-extprvkeyprefix", "04358394"); + assert(IsHex(extprvprefix) && extprvprefix.size() == 8 && "-extprvkeyprefix must be hex string of length 8"); + base58Prefixes[EXT_SECRET_KEY] = ParseHex(extprvprefix); + + const std::string magic_str = args.GetArg("-pchmessagestart", "FABFB5DA"); + assert(IsHex(magic_str) && magic_str.size() == 8 && "-pchmessagestart must be hex string of length 8"); + const std::vector magic_byte = ParseHex(magic_str); + std::copy(begin(magic_byte), end(magic_byte), pchMessageStart); + + vSeeds.clear(); + if (gArgs.IsArgSet("-seednode")) { + const auto seednodes = gArgs.GetArgs("-seednode"); + if (seednodes.size() != 1 || seednodes[0] != "0") { + vSeeds = seednodes; + } + } + } + +public: + CCustomParams(const std::string& chain, ArgsManager& args) : CRegTestParams(args) + { + strNetworkID = chain; + UpdateFromArgs(args); + + CHashWriter h(SER_DISK, 0); + h << strNetworkID; + genesis = CreateGenesisBlockWithHash(h.GetHash()); + consensus.hashGenesisBlock = genesis.GetHash(); + } +}; + static std::unique_ptr globalChainParams; const CChainParams &Params() { @@ -385,13 +467,15 @@ const CChainParams &Params() { std::unique_ptr CreateChainParams(const std::string& chain) { + // Reserved names for non-custom chains if (chain == CBaseChainParams::MAIN) return std::unique_ptr(new CMainParams()); else if (chain == CBaseChainParams::TESTNET) return std::unique_ptr(new CTestNetParams()); else if (chain == CBaseChainParams::REGTEST) return std::unique_ptr(new CRegTestParams(gArgs)); - throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain)); + + return std::unique_ptr(new CCustomParams(chain, gArgs)); } void SelectParams(const std::string& network) diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index 4bb66c8d8b512..5bf0ed78a2cd2 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -17,12 +17,42 @@ const std::string CBaseChainParams::REGTEST = "regtest"; void SetupChainParamsBaseOptions() { - gArgs.AddArg("-chain=", "Use the chain (default: main). Allowed values: main, test, regtest", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-chain=", "Use the chain (default: main). Reserved values: main, test, regtest. With any other value, a custom chain is used.", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS); gArgs.AddArg("-regtest", "Enter regression test mode, which uses a special chain in which blocks can be solved instantly. " "This is intended for regression testing tools and app development. Equivalent to -chain=regtest.", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); - gArgs.AddArg("-segwitheight=", "Set the activation height of segwit. -1 to disable. (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); gArgs.AddArg("-testnet", "Use the test chain. Equivalent to -chain=test.", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS); - gArgs.AddArg("-vbparams=deployment:start:end", "Use given start/end times for specified version bits deployment (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-vbparams=deployment:start:end", "Use given start/end times for specified version bits deployment (regtest or custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-segwitheight=", "Set the activation height of segwit. -1 to disable. (regtest or custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); + gArgs.AddArg("-con_nsubsidyhalvinginterval", "Number of blocks between one subsidy adjustment and the next one. Default: 150 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-con_bip16exception", "A block hash not to validate BIP16 on. (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-con_bip34height", "Height from which BIP34 is enforced. Default: 500 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-con_bip34hash", "Hardcoded hash for BIP34 activation corresponding to the bip34height so that bip30 checks can be saved. (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-con_bip65height", "Height from which BIP65 is enforced. Default: 1351 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-con_bip66height", "Height from which BIP66 is enforced. Default: 1251 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-con_powlimit", "Maximum proof of work target. Default 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-con_npowtargettimespan", "Proof of work retargetting interval in seconds. Default: 2 weeks (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-con_npowtargetspacing", "Proof of work target for interval between blocks in seconds. Default: 600 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-con_fpowallowmindifficultyblocks", "Whether the chain allows minimum difficulty blocks or not. Default: 1 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-con_fpownoretargeting", "Whether the chain skips proof of work retargetting or not. Default: 1 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-con_nminerconfirmationwindow", "Interval for BIP9 deployment activation. Default: 144 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-con_nrulechangeactivationthreshold", "Minimum blocks to signal readiness for a chain for BIP9 activation. Default 108 (ie 75%). (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-con_nminimumchainwork", "The best chain should have at least this much work. Default: 0 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-con_defaultassumevalid", "By default assume that the signatures in ancestors of this block are valid. Consider using -assumevalid instead. (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-ndefaultport", "The port to listen for connections on by default. Consider using -port instead of changing the default. Default: 18444 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-npruneafterheight", "Only start prunning after this height. Default: 1000 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-assumed_blockchain_size", "Estimated current blockchain size (in GB) for UI purposes. Default 0 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-assumed_chain_state_size", "Estimated current chain state size (in GB) for UI purposes. Default 0 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-fdefaultconsistencychecks", "Whether -checkblockindex and -checkmempool are active by default or not. Consider using those options instead. Default: 1 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-frequirestandard", "Whether standard policy rules are applied in the local mempool by default. Consider using -acceptnonstdtxn=0 instead of changing the default. Default: 0 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-is_test_chain", "Whether it's allowed to set -acceptnonstdtxn=0 for this chain or not. It also affects the default for -fallbackfee=0. Consider using -fallbackfee=0 instead of changing the default. Default: 1 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-bech32_hrp", "Human readable part for bech32 addresses. See BIP173 for more info. Default: bcrt (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-pubkeyprefix", "Magic for base58 pubkeys. (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-scriptprefix", "Magic for base58 scripts. (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-secretprefix", "Magic for base58 secret keys. (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-extpubkeyprefix", "Magic for base58 external pubkeys. Default: 043587CF (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-extprvkeyprefix", "Magic for base58 external secret keys. Default: 04358394 (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-pchmessagestart", "Magic for p2p protocol. Default: FABFB5DA (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-seednode=", "Use specified node as seed node. This option can be specified multiple times to connect to multiple nodes. (custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); } static std::unique_ptr globalChainBaseParams; @@ -41,8 +71,8 @@ std::unique_ptr CreateBaseChainParams(const std::string& chain return MakeUnique("testnet3", 18332); else if (chain == CBaseChainParams::REGTEST) return MakeUnique("regtest", 18443); - else - throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain)); + + return MakeUnique(chain, 18553); } void SelectBaseParams(const std::string& chain) diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index dcdb2479770f8..fc27aef6617a7 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -47,6 +47,7 @@ static const int TOOLTIP_WRAP_THRESHOLD = 80; #define QAPP_APP_NAME_DEFAULT "Bitcoin-Qt" #define QAPP_APP_NAME_TESTNET "Bitcoin-Qt-testnet" #define QAPP_APP_NAME_REGTEST "Bitcoin-Qt-regtest" +#define QAPP_APP_NAME_CUSTOM "Bitcoin-Qt-custom-chain" /* One gigabyte (GB) in bytes */ static constexpr uint64_t GB_BYTES{1000000000}; diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index 5c039a939eee0..dcb405b5d9c82 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -91,5 +91,5 @@ const NetworkStyle* NetworkStyle::instantiate(const std::string& networkId) titleAddText.c_str()); } } - return nullptr; + return new NetworkStyle(strprintf("%s-%s", QAPP_APP_NAME_CUSTOM, networkId).c_str(), 250, 30, titleAddText.c_str()); } From 165ee55e0aef8c074c89f6ac9bd64644dd8c855f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Fri, 11 Nov 2016 00:06:44 +0100 Subject: [PATCH 05/31] QA: Adapt BitcoinTestFramework for chains other than "regtest" --- test/functional/feature_config_args.py | 4 ++-- test/functional/test_framework/util.py | 2 +- test/functional/tool_wallet.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py index 06a8d5b7eef9d..1ad7cdd026986 100755 --- a/test/functional/feature_config_args.py +++ b/test/functional/feature_config_args.py @@ -41,9 +41,9 @@ def test_config_file_parser(self): self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Config setting for -wallet only applied on %s network when in [%s] section.' % (self.chain, self.chain)) with open(inc_conf_file_path, 'w', encoding='utf-8') as conf: - conf.write('regtest=0\n') # mainnet + conf.write('is_test_chain=0\n') conf.write('acceptnonstdtxn=1\n') - self.nodes[0].assert_start_raises_init_error(expected_msg='Error: acceptnonstdtxn is not currently supported for main chain') + self.nodes[0].assert_start_raises_init_error(expected_msg='Error: acceptnonstdtxn is not currently supported for %s chain' % self.chain) with open(inc_conf_file_path, 'w', encoding='utf-8') as conf: conf.write('nono\n') diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py index 6d74447ada369..998cf207fe094 100644 --- a/test/functional/test_framework/util.py +++ b/test/functional/test_framework/util.py @@ -288,7 +288,7 @@ def initialize_datadir(dirname, n, chain): if not os.path.isdir(datadir): os.makedirs(datadir) with open(os.path.join(datadir, "bitcoin.conf"), 'w', encoding='utf8') as f: - f.write("{}=1\n".format(chain)) + f.write("chain={}\n".format(chain)) f.write("[{}]\n".format(chain)) f.write("port=" + str(p2p_port(n)) + "\n") f.write("rpcport=" + str(rpc_port(n)) + "\n") diff --git a/test/functional/tool_wallet.py b/test/functional/tool_wallet.py index f67279fcd2799..482590b9fe3e5 100755 --- a/test/functional/tool_wallet.py +++ b/test/functional/tool_wallet.py @@ -25,7 +25,7 @@ def skip_test_if_missing_module(self): def bitcoin_wallet_process(self, *args): binary = self.config["environment"]["BUILDDIR"] + '/src/bitcoin-wallet' + self.config["environment"]["EXEEXT"] - args = ['-datadir={}'.format(self.nodes[0].datadir), '-regtest'] + list(args) + args = ['-datadir={}'.format(self.nodes[0].datadir), '-chain=%s' % self.chain] + list(args) return subprocess.Popen([binary] + args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) def assert_raises_tool_error(self, error, *args): From da2d1de3b72bb51f0a1dd914d3f5a762bb6030a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Thu, 10 Nov 2016 19:51:54 +0100 Subject: [PATCH 06/31] QA: Use resgtest2 chain instead of regtest for rpc tests --- test/README.md | 2 +- test/functional/combine_logs.py | 2 +- test/functional/data/rpc_getblockstats.json | 214 +++++++++--------- .../test_framework/test_framework.py | 2 +- 4 files changed, 110 insertions(+), 110 deletions(-) diff --git a/test/README.md b/test/README.md index 8f08b7afe4fc6..557da6d19c174 100644 --- a/test/README.md +++ b/test/README.md @@ -193,7 +193,7 @@ For instance, to attach to `self.node[1]` during a run: use the directory path to get the pid from the pid file: ```bash -cat /tmp/user/1000/testo9vsdjo3/node1/regtest/bitcoind.pid +cat /tmp/user/1000/testo9vsdjo3/node1/regtest2/bitcoind.pid gdb /home/example/bitcoind ``` diff --git a/test/functional/combine_logs.py b/test/functional/combine_logs.py index 367d0f69165b6..0fe5d3015bec7 100755 --- a/test/functional/combine_logs.py +++ b/test/functional/combine_logs.py @@ -83,7 +83,7 @@ def read_logs(tmp_dir): chain = chain[0] # pick the first one if more than one chain was found (should never happen) chain = re.search(r'node0/(.+?)/debug\.log$', chain).group(1) # extract the chain name else: - chain = 'regtest' # fallback to regtest (should only happen when none exists) + chain = 'regtest2' # fallback to regtest2 (should only happen when none exists) files = [("test", "%s/test_framework.log" % tmp_dir)] for i in itertools.count(): diff --git a/test/functional/data/rpc_getblockstats.json b/test/functional/data/rpc_getblockstats.json index 16dbc5fe601b4..9910f9b243390 100644 --- a/test/functional/data/rpc_getblockstats.json +++ b/test/functional/data/rpc_getblockstats.json @@ -1,109 +1,109 @@ { "blocks": [ - "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f20020000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000", - "0000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f28394022bf44bff30d7399cb5a16e3b94fed67dc174c2e1d77df91bad5a51cb3194ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020e959d05cac787d7f82d1348326a4ca25ead09589befcd4b4513163e5acb5af6612d2f07672102dc6f099c4be308f598e4c4da1a7e0cb462ae14f0444525a13321a4ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03520101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000204401ebd07d42f8f18e80ede81795f728a9eb2a63073274ad92ccb9eda593ff3c5f17ca91704a014c6f68ca623ace6c542950f2e1d2d02ece08fbd440e33af53a1a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03530101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020eab1809c3e750647f588c027df5c9d5735bb8cb2a1a5f182d7b35524b0b8595f9d59f165de689fd9a4b6954b4394d40d7899eef078e6ddb9f7eb036b7b15af2b1b4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03540101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020bbe445e86bf69865a0c816690c0e470338bf9d692d388f8186613830afe2f54c07ae38ccc6fd49e7098d6e3149e459a234f30970c6c9a9894df992e3caf97ce31b4ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03550101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020f5b84b4e3b7e84720a83dae76aad6657c06ec6bbf85d9158c575de09c34631035b263b763b955c4c6d1a97b23e6b4bc5e6ee96d75910845557aaca233fe777fe1b4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03560101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002028d52759ccb342b81f2e8d574d8cf116178949f8a595d577098bae70e6969326119c83444b75d63bbe98d8b3a937f0de3a459bda5fdc0fd66c7acd752d19496d1b4ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03570101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020f461e9c8981911f5180e9a8e28be1d34146460ae4e7583935949f43f6252bb3cb287270caf2d4e735caf0d9888f998b8d7c79443e97933976930919e6dbc0b471c4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03580101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020d3328d99edb99583b478969aea57e378c2840bfc1df0341963fde16f75636e34a6c85df88c2800c54565eb2e6579b729def99fa9b8ca347ec649b8d4f8db78de1c4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03590101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000206b88980f5b713605233c1c8806639717f753c4aad93617d5e37872a43188af6c8dabd724a42288139a21186c855f23c4fe1d12337ec7b97f87c48389983239651c4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035a0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002030fd29b0e0e54a5eec463f93dac2fd9d73f383b7467d146a882bee4700f79832a343b1b1867b07ba30134ae555db5816ccd971232b78a9d596e2711d02251c521c4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035b0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000201845eacaca9b23798f32c22414015655035d4918be70e26f56b56e730e195e220bf32e9a8af59ce9264884b0690bb26709616ccf4bfb85812faf87144b2fb8131c4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035c0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020353ff17bd0d66a6ee1e784bfbb2497691f49e27c3822aced5125fda6ff09892fe72239d73e75b82916e8eef04a4963e6b500de80a7fdcd89952e23c6d249c5931c4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035d0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020c6c359d1b891b0a6afa7e0fb685b9c21afe41c8dddd80cd6331ecd856650af3803953a9bf6fc675eb2856718bac5362a12168e7b1baa7dc6b46a4eacd2e8baf61d4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035e0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020291a8a183e7ebb538030bc791b0f995a2ac0a766add84d83d3fa9f6fad50075a0857e76b64648e82fd4341931116efccaf147f0bc6e8c107cee68f400530c17d1d4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035f0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002081f804c3afb976efbaf9f62d50ca43402fd5a09571cfd93ddaf77d78952ebb3e3db790f598f68da5e0514b03902de787ff0d2457c05a59bfb22547d8ee6f7ed91d4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03600101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000204d559298cc1db4c70f422519822a850603ec250f4ab705f51423d67bb2d4a03abfdfd932c91a77b0065183cf1a575e73b9d1322804f869cc640747e7fa36c0531d4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401110101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020b49a26625c5d5210a3dbd1aeba62718b828a29dab035b6e028073c3679053c02ee7b702c74ece9d04af3aca5f745aad5d4142d6a15ae12d16157c1449b62b1b31d4ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401120101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020655a431b076a153aa7d9d3731b42b4213995f92299a56e6270860be4005d584d33b5d4b94367acd8ef20e10678a75de3c02e143a3f9bb0b0f0c31ed0396454c31d4ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401130101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020a96f9ad3e058c097d63488627158e074f759a73ae3292b8d8e3e979edcb4e33f0ccd7e3208e9cf08375f36a34f3d71da039e6a33cb8621a67bb484cedc5fb4f31e4ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401140101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000202ec3fddee36cdcfa564d29eafe073ba79120ecdf8740f62600293b0aad6039419047bdc522883061665549cacc029b05713ad4ae24281eeaf0a041cec3c7d0d31e4ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401150101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020d2985cee6e78b525c61ad111b0e9a6ad8c222ca793eff2121c23cf06462fd930bfe97d3f071f45d95467db4f5d31d8b7966c26789be3d5c1a5d53c903230abe61e4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401160101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020e799bf0166a1e3e7b94d6709fa0edd5feeadac19ddb271ce8e8a6144fd52c23b1699dad3820cb2ba528c13e37550cd32a900ca14f307db9b735daddb523b1d511e4ae75affff7f200a00000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401170101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020a6e38cccd5f39851e6f1aaab690b3591ce59ed225bc4815b66ed59f9e604da4beadf823c049567a4628d7b06090ac7f51f1a854c46817a8b6fb8f069a098f8941e4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401180101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002067dc38dccecab584fccbd21e1fdcaa8ce69155053eaffe082d51fedff22c26299e57f12478cab2077ac63eecad4a342082c9976addd08ea58896ab334ddf5e6d1e4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401190101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000200b71cba7f1d43034d1584c309e04bff61a7814896b3fd170f69d8757a81b114b4769be83a7993e5214c7cbb5053a142840cc180e23366cc1d52cd2ace2347a1b1f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011a0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002044d38910c5362c279ee6e183c56bb2379f0d053bceea9f2c00f99adaf1a70067de8615ddd58387b2847d215fde3633242c278ef9b18ab9c70963c9060b4a3f101f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011b0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020b063fc1b09b6f9cd8207b0f9ca9f1549ce2b1de07b7f937275d96461ecacb26a3abf0a5d24c68c0b3df1a58b6128039eca6452810a374a306ac0cb96bd462df61f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011c0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002023334826cbee5a6679259a50f8e112332db9663c97a1d08d54e64319dabac73331dbae7789d23e1da14d1ee39a9dea43581ddd9c09a199253ec0bd6c819514911f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011d0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020911e28670d744a0cb23495711db6ac20576273eec7ee442b0377ea2d7564402fcc7db46bd4aa8fdf1209e649b3866f5cb79fe3f2cfaf8aadd39a3d43eb084ce21f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011e0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002038d6d41fddd3c9278884c9141096360c538d2491ffb078be006222a88a10c854366b75e0a133e1d3f4db26e1b0e9b9820db50dbfb11988e8bb8739420ce1799c1f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011f0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000204e501ddc49c462c4ca52283614e99e6379b9c6570c947a822b832804e39aee00b037b85318c2f997bd9edda927e85dc2c83f8aa1952dc67556565d141a246186204ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401200101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002040cb0b50f15716374c2dc627d1fa6e3eaae67b1b4f1c90a30914e3c89a74de794a98fd86cc22c32f447477016e297c61a4e48135e658e5b5be84638f3a836ee3204ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401210101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020f51dd27d82fbb9296330e7f105a69ea307303799ca986abe900f00836f181e59a34210d60eb84f3fe493845aadfe404fb4096e599a26f63453c8120257cfc8c2204ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401220101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020b696bc517ca5d36092ca1106fd8d31047552e9453a9de51d92cf9226259a491618e806cd5aa13974beb89d41c5040a48242c24bffa8e65e9fdf3bc35e2a7c1b4204ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401230101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020358daeb9eef51c07f280abf17c5321023d8cf8bae26254abf25b9268d89a424fb67a604005cd713a7df2c45fbf5f761da51b9c6f21e86a3d8eb40827bbe2764b204ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401240101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000200170975c14ec6544367490c04b06294aa57fe978a1da6e5939ee6051d7602928e3676a94ad350f04f371edfe21281df51430055242082d9704030cf5317d0b81204ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401250101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002008d02d23a387a7263f5f3475bcd56b380fde9b742bbe83790dd9751701a7923038bfe35d91a9e4e5f8cc714713acfe2d1e96646e61b29b3dc072e5b182fdb45e214ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401260101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000206bd75eab3dabdee5a35c0a64de2aa90fb54f2d12b4f37ee60aa28541b51b493f0e5915bc2be5d87850016a330fc36b62f6e40ad7a6d38e0ed6a4f62056ba22a9214ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401270101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020a42645a785e5dd28047022b724c1af64d507d372b83f3f23899c82b317168262371693330fe6d94f33a962de50891b2f5811a066830c331a240996310b5c6280214ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401280101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020a6626233cfb7d9dd7c97f6db305ca20b6a7fc32d5e8ce9b07e35aeaaa7c0af3975cbe08a458c6fc4cd748a39427e29c2b29180293359623e30e2b5639d2d0417214ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401290101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000203a5a408e1a076fdc7bfa08460932fa40aedb0471fe808e268ee5768ce173520af5dc75a6bde31efc2ba81a4ea94fe91d3b1ab1ed99975fc5b1cc725f7f20817b214ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012a0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000204cc70837ef7c3804c04419260a2d65ce21515317991751117fb81596ef32c3161154931edf6dd92bb8a13231190f7c0b21bc527e188384770faa53b54aba04f8214ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012b0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002070b6275e92ff0b54df08933d70b7d933c3b534b779026630dfb2f96efb860436581cf56e07b7d7e2a377ba0e698f592e464d1ed84bf464b0dd67cb85cbf69f7a224ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012c0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020a330af8e1dc93fd74b7479c626b1a77c21dec2d240fe7b7d90249da127aaea50773fe8f12bdce2a65c375082dc3db0414e68aacea57f41504cf901a7858b8cf3224ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012d0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002052841b806090d1d40d221788025ba6ae3a9bb32f352cb12ce4b165be58846a12ee2ad08be6b3e693e3d53a90abe88a8426b342f19f3b271818e66eed4ed1892f224ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012e0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002095b86217b1ebf86fa345f2c605f4251b24d5a647710758cbe08340448250ef015f65e5752628c0a0131fc31fac03ed3a2ab0d2c1407414d4dfdc1680037a3b38224ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012f0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020757dfdbb6f52e389a0ed997dff15de8682d55f9e241d3b53b254f19fd96b926860d0c537aaa527616248c9e50fd776e801eb5dc5d9ef034251b846359da84bc1224ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401300101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000204c5ff56d6188016b722ba01c7d3b74bc530820b7dff447efbb8c5e756def2d25bdb8e2a27ead1a99e184a87195f06f858b810add552f6bf0127c0a36ec101a60224ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401310101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002064c6f9651c489cb014e8d5271e1f711b71d20d865ab7561b26bea5c85fe6957b6326b1ba78a33db0f148a07e1d49437ca70ae9d73544c183d2cfdf814fd7ff37234ae75affff7f200700000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401320101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020bc955dccd950bcd6051723e18c87ba5114103eb66c136d4bde1070b99678c12f6192856637c104e86194dc91e1550447d83b7124a230871020c37454f2ec82bf234ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401330101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000200f4e7a95470e9056dda68e82b62a61cae778e88b6e35a4714bdfa3bff8b6e846c45be9fa19a24d90a3180a562bdd8b8a5b71d4c2e0a9f84b6c55c439ebf2f22a234ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401340101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002044388dd29a4f16901222a7beeb49315884c0583a2c31a2f8865536931ff8ec4442553d33ba0273b54c52e589523cde509eb117046f5e63bd5e8a5a96f467c5f1234ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401350101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020438366e968619730e26031d71e8208d31ab6cb7c242acb65f3d1769157cb971210b6afd88e0ce95bb14554c6dad04012fa8ce0c88a5932ad71da4d04a15d44c3234ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401360101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020c38296d021842f437d04f8515079f943f0a1c8437d8f2c329499c32c0448ae1d961fb68ada366165b25199757ce8a527f11d0744bbcbaad402815e09623dae04234ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401370101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020101cd76ca645831e3a55898707454b2405151a06f8c8cee7822d148ca1251d12fd945975eb3855e5f0cd2afafd20b169a7763bdc73b64d1c2f096425d9c902eb244ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401380101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020f7735468f9b54bae6399754a1ba4b5ee620af1dc6a46261f4d8ab4d872818f35507916cc69e748edc3a9feadf7b79d1d19f16140e8f3260d7fbe9d1620e55f26244ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401390101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000200bc5d881eeab42717526d45d8475fefb1940bbf03c5726174e64379e5a23bf5cbc75b97dfb5771d55e7bd108bb109705ba34952511ab96646cd2db4539fc3b2b244ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013a0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002094a466199740a3c77035005e1fe5ae603df04ab18c429abfcc385b93681b75390e0d6b356161c1ccbe486a26b777ff01b1247cd6b4b9d4d5b0f958d2e887caab244ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013b0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020b5e8aad67d17f4f047da10404862703a89feab21624801f785cfe77af4a71d6b87994452ce4bfdc92a07f49ed16903e68d8d48191e31d9558dad4805718311d5244ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013c0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020b0ed4309ee1541c2dc5480b14092940b88870b9d4ca32ca448e7eaffc1d74978b9c5b6e8c1739811c932cdbecd192ae0bead4068782ca2e98805b8174d40f213244ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013d0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000205caa7f7a1817fcf6b454b156301f44edbb71cd19de098d9261305aa5731cf073faa4b4bcef4b3ed44ddf9b2b708397114484aa262a538c81b04103a02d8c033a254ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013e0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020c7ec1d68a2b4309b255ebc418cc4c8c1a57892bb3c6360a07d22b526ffba6a38436088fcdbf94cabbacefee23bb69b5ac30e3627f94500746630163249cc5029254ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013f0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002014c877261aa37fc58f703b64278f1d611b6faddd582e33cc7f1e7e63ad75df6cbd9d279982bfe391b013160a66675ed11debd83c32a9efa02351eee65ac96d09254ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401400101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000202b5cbee48cac714ff220fafa0cd4304f452e5c5b63dc5cd4f27072cc4ba7e9376f1f5aac2480c10e93e13f3be00b38523dc036eb6ae49b93f815140ee2b08a27254ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401410101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020aebd16a2c6cf18789e213338ee08bcca42d89e7c9f9220cf80e803cf9b67205eb58e2687eae141c7bc9656b434bc95900a6935f00db43dc23ac155e380af8e9e254ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401420101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020984d2d236668762da13fcb8f811401c1928a1df9a9896a4cc382912669b0b13642ad8e61dd8e6c702869587acb0d09b3355a1be27cb20ea909f51287f9e1b010254ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401430101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020d8ca9b5782f98937be5967d0c34aabdcdddc0201e17b70e4071e320bbb2c06418d020f678641ba278d49d70430385ede2f830c46aa49ff7a3febe99d2a9896a9264ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401440101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002017dad2d355421342e973abef035c18398d83dceccd6372269f6bbe6e844fcd52d9c4bce498d350184aae9af97f0aef0f366356d50b926c59bc1605ff6f41f144264ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401450101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020ab1775daac96add2d038b5046be91c90b597b8ed11038b2b9da32f47537d106556d820e14b52e6f4fd113554754f3a8d65b80e7dfab2c84c5e7bb41a30c39977264ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401460101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000204dd398d0716e12f3397c9de79cc644ae3d63c6b90c579f5872d76820dd79260fc5808f07c0d1a3e6a23c9e8dc84d58c12758cd61a2f0e8ec3694a1ac08a89bda264ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401470101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020ed9c915c725956194c078ed08ad2508ec34a6b868c21226d14213904bb3c4c50f385dbbdfd18fa6f8355a89c58370c50a71f59f44e2d2e505fb861960d155705264ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401480101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020b2f8525fa7a276f4a078bdad600074c49df4c237aae27cadb60ecf91eb7b8d42c21e035455f17270ff5e2a53c57c8c663f31cdb7a3a929de1499e3117358108f264ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401490101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020897b6cc09bd1b7cb5d42c648498199aba4008875614e021898b121e8e751f34cf0b8a1a4c993ffd133335d84b9aba6159bb8129384a253131d1998f28c3d371b274ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014a0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000206a9836bb25994ab592060389b119cb8f7a19a64acd27f9665eab93b235803170ec6385bd31ab432ed3a13f7a6cdf0a6c87fe50c614372a58a5a3716c34456e83274ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014b0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000208202cd4938b8eef65707e3b6cbd025780f7220fdfea8bc897e802da008026d29043cd5b1662309701440c7941d61cfb95d0c98e22ff8ff8b5994149e988ab179274ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014c0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002074eed60562b3fabf1cfbd4efd86acd62a470dc264b81b98c784dce4a57f56614d713809d3b1678f325563577d3b6dd9ae4f1e5b05b70c3b16abd67d7161d9002274ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014d0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002072677aab7f4bb3af82841c6a7100df3ac5e8b643d9e88bb271b2da39c575222aadfd5417618dde8d0ee9191c4b110d0c76dcb65eb8adfd3f8a32a35ccceee445274ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014e0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020508ed0a8978dd8a6a4e55bb5bc27dd8edae3838d4ddba461332da10f0fb901080c5a78ea3fb056e326e873cea75009c29c401fb77a415ee64ae4eca44bd617dd274ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014f0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000202004607f94d91d8eca99a860ed208c53a4fd53f38889c77dc35b31a676eef1625ee8e5c95cb2105d0b8268ed13eaac6236eb3405df3099fc52d62169d218fcdf284ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401500101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000204374d19a51a307de1344af36d893991965f58779adbc4b1c1045d5d8e14d6d0b034e10cf7e5158f62fe2674c89e8fc4ee94d2da62d81c0ffc8a237e8dfcb3e21284ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401510101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002037320af6c9cc617be33ba517458ae4607b1c0e3e007268669cf5c799e93ebe67f182660cef31f84c0c6b384f084b243a77e2c271be610ac958124076306d9170284ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401520101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000201ea13062078bd8f70060208d6973bd55789cbf2f221e8690f1a78254a597a1434a16aa13a90a872e0dd3046458114dc745e37d2928bd9ff306ce7adb2567efb3284ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401530101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002052fe4aa74774077ea9a1c27fea59dfa12b75f7ad46746f8458eb67acaeb9803921a47de6874e6c2359af86d72abdee12b27bcebe0f1ce48751055005813d3f42284ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401540101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000208ee41caa2f3076233035157fde7c5c2795a81b85d5e27ce7898e301679e91c4d2d38f595981a444c7d868166ae50e371d83b5f59802bebfed056b93aad1b971e284ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401550101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000201a0eea032f4abd74aa1bf1151e2966433175ecdf2d68b750b509305bc5663e3641f55e2175bc1d50b4d8a83f167091059a2a6e7d1a24d8223f50ca41313eef1b294ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401560101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000207403c2bca2c06351f16746d3360a1a7dceb5194d57879caee03a8316ec774a608a5d44cb75516291cdf62cd51a1a9c71fd3d4879737d88216c6c4c6bffb0784a294ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401570101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020f2be7a9ba2c914d5ee97c819cb096aa9d2c715d2f74e9dcf8a12cc83ac48475e4e332a45285f3fff16e8c5cf79107ee110dc2a2f84456205f43d8f4e237a10da294ae75affff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401580101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000205fc71ff65dd07485e26129b765937f514315487b27f0e431c5da7de97b397a4f1d984f86e81bd2c9db53c3515b6e3d6a28187b50adffb87df25608b738190bcf294ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401590101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020d7befb40f244eb69f02a3253bcc9b14f5c2697261e158288e7d0b48eab34f12eeac43d0751178d2574aa20506d1b91af13af688a8dfcdf1a48806f63e53b3245294ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015a0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000204a0082f8508319d99c86cc074cfedcf26fb98f2e6d0c27d602a9d6ed6d04db042163e10278a5cc75003c52739df112f1ea4fe0ed250ace8e544ecde713f47bfe294ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015b0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000203de23751fef24f5d30565808862dd364e209fc0f7bf83874ebcc8f155e65574acda81243c6a438daeb547e1b36c9a5441e6556bf16bb9bfb839628c39a3785162a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015c0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002045addce76c20d564ac3ff6b955e8ecf2185a5aa355a0d3ac7fd29448dcfb9c1ed184bdf283ba671c76c99173e4ec87e45dd97331c9000070edc81093bc4c7c872a4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015d0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020a7e8079eccbca3b4a4a0136ef27478b45352270f2f8947ab83eea09b06cc826ab29d7b37989b6570510e368a20f4fee2ca0142044f96a027830abdf438ddf7592a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015e0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000201f28203982fc7c2fc155361d00ef7e69ac9fa9c35ff3d10e8fd1a0004e9b10528488982a149b5ac96bef6be131e0b2f0ad9269ba66c9b4216901c0b81523123e2a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015f0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020435d68020c01c6088e4013cb4f349009e65c28ffa0630baf5dde1676df55481513a48742e06190847a40cabbda6d48f715802bdb3cbab7ad7a2e5c345d557b082a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401600101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020e525dd596c4b9ca78d964ef7997063d35af98665f62e9da62ed9c7fb38c9f57f5abfb8140edec21a383e1e3e31288ee0130a86564e5c3da9764594d8365134652a4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401610101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000203d4144c4bd71aa7f71af930a98087d3786e697335fc1eb11177bedcdae72a61549aa4519391183deb58058f99a6abb7638fe81f079b31c4e090d486c49e047ac2b4ae75affff7f200500000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401620101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "00000020f44e7a48b9f221af95f3295c8dcefc5358934a68dc79e2933dc0794b350cad0a90fad2cd50b41d4ef45e76c2a456b98c180632bb4b44e0cd18ce90679fe54e552b4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401630101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "0000002087454276cce83f4d19e0120f6e9728ac5905f7adaf6b27e3f5bbe43ab823f85db7d1f44666531483df3d67c15f2c231718ad93b63b851dce5ff4c4a67f524ffa2b4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401640101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000202cdc3e99f07a80252dd6097faa0eddf3f2dde5ae390610e0bca94ecc25931551d31fceb8fe0a682f6017ca3dbb582f3a2f06e5d99ec99c42c8a744dd4c9216b82b4ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401650101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", - "000000209b3ace9bd510918d20e87518c0cf5976cab3e28cc7af41259a89c6dd7668a32922808b8a082be71bcd6152cb8fd223650b5579a41344ba749e4d17b9bf211a9e2b4ae75affff7f200000000002020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401660101ffffffff026c03062a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9edb85d8f3c122c43a72f1e0dd122c8f7af040aa0b0a46001621110fb37818021510120000000000000000000000000000000000000000000000000000000000000000000000000020000000128394022bf44bff30d7399cb5a16e3b94fed67dc174c2e1d77df91bad5a51cb3000000006a47304402201c16d06a5c4353168b3881071aea7d1eb4d88eedfea53a9d6af9abb56da9060002205abf3ae535f1f1b5cfe8ba955535c2b20ac003e7d7720c5b7d2640ac2a04d19001210227d85ba011276cf25b51df6a188b75e604b38770a462b2d0e9fb2fc839ef5d3ffeffffff0294b89a3b000000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac00286bee0000000017a91452bab4f229415d0dc5c6d30b162f93a1a0cac5958765000000", - "000000200fa168b50a79ad24378a6b0f96e4c9f4ccb657a2663320d5fc1efd8ee7caa10ab42a31c444f2153387530a0979d4dc3dcc134b394c821227b8abff930c03c8412b4ae75affff7f200200000004020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401670101ffffffff02e015072a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ed20376d4bc90f9c689850eec3603cda658ba6295241730473ceb0e970b8d594150120000000000000000000000000000000000000000000000000000000000000000000000000020000000191e549a6cc852bbf1d3f11144b1a34079f64305e6971d2e685d2b40cd386e8a6000000006a47304402200bf62021c0a9a47ced8eba1e0998f5c71b2950763198d83ad284bd791241dbb00220446a05b7c35e7458924de88a8dcccab1ec6a106aa005345e55b482d8eb66337301210227d85ba011276cf25b51df6a188b75e604b38770a462b2d0e9fb2fc839ef5d3ffeffffff02acdbf405000000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac94d7a4350000000017a914dfa6f0b17d2c64962c94203e744a9d4179ed22c18766000000020000000112d2f07672102dc6f099c4be308f598e4c4da1a7e0cb462ae14f0444525a1332000000006a47304402200a6a2f544f3f9d299608a7c745e2326de176fb1cac03ae3e74943f4250b8896e02205023a5b4faff99865bf91f1263605a502c723628be9240c0b7bec81d2ed106f101210227d85ba011276cf25b51df6a188b75e604b38770a462b2d0e9fb2fc839ef5d3ffeffffff0200ca9a3b000000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac94166bee0000000017a914152cc82f7944f5c416de7dbffb052f7081765d7987660000000200000000010191e549a6cc852bbf1d3f11144b1a34079f64305e6971d2e685d2b40cd386e8a601000000171600147cc872ad7350c37fecab9c4c6d9f08aceb53bdb8feffffff02005ed0b20000000017a914aab1c8c53fe62e283a53efa28097709f4f2ed37b87e0bc9a3b000000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0247304402201b4476f238ed5d515bfcd6927d0d008a4993770763eca73e3ee66f69971831d902200f5215a6dfd90391dd63462cfdf69804fe31224c309ec9c38d33a04dce71c0ee0121028c9d2955a95301b699db62e97d54bf0a91feb44e5cd94bbf5b62f1df57fb643966000000" + "010000000000000000000000000000000000000000000000000000000000000000000000656577995de2a4f610fc7e48649fdee7533bbe7dae7fa602e32ce3a45d99fba0dae5494dffff7f20020000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff212040537e2c8ad0d5f6b10ff36c4aad4d5159ee92f0ec9e06878a4f4c789a502eecffffffff0100f2052a01000000016a00000000", + "00000020ec91918165afbc3a30cdebd4f556043e04f1b6b3db4cd38c7cc502374fad979328394022bf44bff30d7399cb5a16e3b94fed67dc174c2e1d77df91bad5a51cb3194ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000206b1b0fe07fd54fb5714c6244a86a28ea6b8c5cefd1a01c6d1c4e5554c3da5d5312d2f07672102dc6f099c4be308f598e4c4da1a7e0cb462ae14f0444525a13321a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03520101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020db134139e269e5c7792b196f934966353221077faf8603cd55f35c8840818c2a5f17ca91704a014c6f68ca623ace6c542950f2e1d2d02ece08fbd440e33af53a1a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03530101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002015f9a471bbfba2b0a9bf2bdc38680e7a527339b46d84e363bc58da54ec8b95339d59f165de689fd9a4b6954b4394d40d7899eef078e6ddb9f7eb036b7b15af2b1b4ae75affff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03540101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020dab95f7b30e60d040b0217f553252d8cf65b5f136d0561b62313e2770435fd7407ae38ccc6fd49e7098d6e3149e459a234f30970c6c9a9894df992e3caf97ce31b4ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03550101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020bf0e6a2114330be8935e3ed1bef2be4a2fd2333bb6d2eda73f5d3598f3772c7a5b263b763b955c4c6d1a97b23e6b4bc5e6ee96d75910845557aaca233fe777fe1b4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03560101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020707d247866067d6a3749fba9d850f1b035c399b3b3c34f8c30ce898ddc437f7c119c83444b75d63bbe98d8b3a937f0de3a459bda5fdc0fd66c7acd752d19496d1b4ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03570101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020a95b74ad20c6342a1e8834342dd39727605339599362d62d3018b407c1904b28b287270caf2d4e735caf0d9888f998b8d7c79443e97933976930919e6dbc0b471c4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03580101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020a2362668f89edcccb13312047d3a592a63822dcf24c0b79d98222a634454ff52a6c85df88c2800c54565eb2e6579b729def99fa9b8ca347ec649b8d4f8db78de1c4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03590101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020759523e651ba07425e1bf6912bd8a4d3cad4cab758af359be541a57e7091bd258dabd724a42288139a21186c855f23c4fe1d12337ec7b97f87c48389983239651c4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035a0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020389370e0fbee7eabd45e04c91cd7b7da58771c37cfea8008ca11df5519dbc860a343b1b1867b07ba30134ae555db5816ccd971232b78a9d596e2711d02251c521c4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035b0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000207360b5d69807ec4f448b38da1d3c69383d61eed5634be5913fad85e76c9863060bf32e9a8af59ce9264884b0690bb26709616ccf4bfb85812faf87144b2fb8131c4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035c0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000201212868cbaf8545242ad40021e7e5f298feb8656f8a6e1c3ad642a23e7accf58e72239d73e75b82916e8eef04a4963e6b500de80a7fdcd89952e23c6d249c5931c4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035d0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000200a5713f92693614deb5fe90dd2ee818cb7d6ad51dface5a1a1630bc542417f3503953a9bf6fc675eb2856718bac5362a12168e7b1baa7dc6b46a4eacd2e8baf61d4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035e0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020b1ce946ac2e1b4a97e03fd0ea44ac09fc17b5fc86092dfd3b54febd40ee709340857e76b64648e82fd4341931116efccaf147f0bc6e8c107cee68f400530c17d1d4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035f0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000202bf7907bbd95f16e986e7a1930c7fd837d1fe1cf9f6c1b034e1d3f6c888ba5303db790f598f68da5e0514b03902de787ff0d2457c05a59bfb22547d8ee6f7ed91d4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03600101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002001b52a636db868964b6d72eb281c3f88ad54c0e39c6fbe066db17a12109cfc58bfdfd932c91a77b0065183cf1a575e73b9d1322804f869cc640747e7fa36c0531d4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401110101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020d087fa61dc5f29cd1fec7793eb33cb75931d106702fe5db6e1e8f0b251699823ee7b702c74ece9d04af3aca5f745aad5d4142d6a15ae12d16157c1449b62b1b31d4ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401120101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000204e90a1f546516d846df6742c85eb69618477af870747c39fead5eb75956b4d0033b5d4b94367acd8ef20e10678a75de3c02e143a3f9bb0b0f0c31ed0396454c31d4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401130101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002086754095981c35cfab37527a34960b11a0b26149d59b5ca6749aad47b7cece1d0ccd7e3208e9cf08375f36a34f3d71da039e6a33cb8621a67bb484cedc5fb4f31e4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401140101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020fe5b85489c2dc22011fafa943a6478eacc818b0b1cab5f61765a8a859b2c90509047bdc522883061665549cacc029b05713ad4ae24281eeaf0a041cec3c7d0d31e4ae75affff7f200500000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401150101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002091696e57a2ee0f01c73be093ed524ee787403d65b0f21e89b84ae10eb3d4ab3dbfe97d3f071f45d95467db4f5d31d8b7966c26789be3d5c1a5d53c903230abe61e4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401160101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020e77d8b75a8dc978b93acf1ed5801a8cb390624d63fbae84ee6cf9d4112b609461699dad3820cb2ba528c13e37550cd32a900ca14f307db9b735daddb523b1d511e4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401170101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000201c69193a93523b2973bb1dd13370cc42583b6f0cc9db2d9a4e10d5ac356a9275eadf823c049567a4628d7b06090ac7f51f1a854c46817a8b6fb8f069a098f8941e4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401180101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020f54df2efeb31c6d5976fb71eb5c2bcd6ff7e1b5d22f6cf89dd1d9e2a4c97ca7f9e57f12478cab2077ac63eecad4a342082c9976addd08ea58896ab334ddf5e6d1e4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401190101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002054aae147a29982d18021def73806d4b07e6a9c0f9a18aa9e3eb77b89781b663e4769be83a7993e5214c7cbb5053a142840cc180e23366cc1d52cd2ace2347a1b1f4ae75affff7f200500000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011a0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020903f7e76e5be9444d974802e9f000498ce337e2d3e03020614f06a4efeb41e53de8615ddd58387b2847d215fde3633242c278ef9b18ab9c70963c9060b4a3f101f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011b0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000202ddf3b4659a266b18ea5c4b7c06a9f15e116627cb75a25c2a2cc1d43f885223a3abf0a5d24c68c0b3df1a58b6128039eca6452810a374a306ac0cb96bd462df61f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011c0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020ec7bf9fa3672f03f10e2874c43e58f1de9368862ff6bd47008705e5c5209a57631dbae7789d23e1da14d1ee39a9dea43581ddd9c09a199253ec0bd6c819514911f4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011d0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020fae0cd24c5b02a52e3b22fdb2cf2d5fd2cd3fbcbdedda80cb2be3d5391366845cc7db46bd4aa8fdf1209e649b3866f5cb79fe3f2cfaf8aadd39a3d43eb084ce21f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011e0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020ac27bf08acb508f81051a00535c00cec60f4259977e88e8f761e9b942336095e366b75e0a133e1d3f4db26e1b0e9b9820db50dbfb11988e8bb8739420ce1799c1f4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011f0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020dc5f47f41d917a5705d7507cb942877a54adb5c8d40ce5c94e053db63227f71db037b85318c2f997bd9edda927e85dc2c83f8aa1952dc67556565d141a246186204ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401200101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002083e73a406b0862d01ee4a594b783be3653ac838458212a7ff5ee436654121c514a98fd86cc22c32f447477016e297c61a4e48135e658e5b5be84638f3a836ee3204ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401210101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020386757a13068447500ba3cb02b25c6adf2636b36cc020ea659de3a22ecaacf75a34210d60eb84f3fe493845aadfe404fb4096e599a26f63453c8120257cfc8c2204ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401220101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020adbe06cb8475c4611c25a8946fd1c06990c2911769480515202367482166d44f18e806cd5aa13974beb89d41c5040a48242c24bffa8e65e9fdf3bc35e2a7c1b4204ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401230101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020ed216627b9cd9aa2faa01bbab1b13cf85842d39e7aad14e20795e0d56372f338b67a604005cd713a7df2c45fbf5f761da51b9c6f21e86a3d8eb40827bbe2764b204ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401240101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002028f7f5054f649378c942424d11fc05d114d67fa3dcba6de51bb9b7e0bdfa4c3be3676a94ad350f04f371edfe21281df51430055242082d9704030cf5317d0b81204ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401250101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020be9ae708adbedc150ed5578c1d8cf60c5008547c52b825a4c8de58c51c14574938bfe35d91a9e4e5f8cc714713acfe2d1e96646e61b29b3dc072e5b182fdb45e214ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401260101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020d37da543b469e1c90245b1492783d92d002e6cf0a7f251ed5ac06b379a23a10e0e5915bc2be5d87850016a330fc36b62f6e40ad7a6d38e0ed6a4f62056ba22a9214ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401270101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002012ecf5443162304a73d336db6baa43f902c10c4cd9a51e8869c673a2dba20d77371693330fe6d94f33a962de50891b2f5811a066830c331a240996310b5c6280214ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401280101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020a49c8c5b7e968b12b55bf96a2e9e721f618af8d9505b7ae264a535bbfb4c173b75cbe08a458c6fc4cd748a39427e29c2b29180293359623e30e2b5639d2d0417214ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401290101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000209f600c3f4634c66b384332120cee85d5cbe337a1b18a74b7d4c41077cb747726f5dc75a6bde31efc2ba81a4ea94fe91d3b1ab1ed99975fc5b1cc725f7f20817b214ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012a0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020993b090a92c41cf6167c5248ad9f4bc9b0f6b643b632f244a8ddd53d1862c44a1154931edf6dd92bb8a13231190f7c0b21bc527e188384770faa53b54aba04f8214ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012b0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000206d15e423ee5cf1501faaf0b7dd3a6f6d4c303105fa21c0fc2643ef2538721519581cf56e07b7d7e2a377ba0e698f592e464d1ed84bf464b0dd67cb85cbf69f7a224ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012c0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000201b0fb0b53c0e0feb0077c8c2b4a8776167c98ac02e52fc563015b974d6c6e55f773fe8f12bdce2a65c375082dc3db0414e68aacea57f41504cf901a7858b8cf3224ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012d0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000208aa1b4d529729aba82aa7407d694d083191cb566eb7d70a7945e41cfc0c1ea05ee2ad08be6b3e693e3d53a90abe88a8426b342f19f3b271818e66eed4ed1892f224ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012e0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000200253c918f3027a8fd02707caec3998c50475a84df17161b620515e90c57604175f65e5752628c0a0131fc31fac03ed3a2ab0d2c1407414d4dfdc1680037a3b38224ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012f0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002073e7eee63b7488f5dcea00a298eb935c02b8b673370cffe03a448a185cfb813160d0c537aaa527616248c9e50fd776e801eb5dc5d9ef034251b846359da84bc1224ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401300101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002052e04b9ae619e97adac11ecb84c4b32f19933174a03e0bc33fbe145dbca73726bdb8e2a27ead1a99e184a87195f06f858b810add552f6bf0127c0a36ec101a60224ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401310101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020707376182c249ef4323881e2021644f9658cac9f5687792f908770efcf852e236326b1ba78a33db0f148a07e1d49437ca70ae9d73544c183d2cfdf814fd7ff37234ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401320101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020f623d2a6bad65961718e848503ac2d2168ace52d5dd17e7ed379930996acd6406192856637c104e86194dc91e1550447d83b7124a230871020c37454f2ec82bf234ae75affff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401330101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000200c5e7830a82d67d308bd352461b5b9ec6385bf69adc7da55e4658c3b1752e423c45be9fa19a24d90a3180a562bdd8b8a5b71d4c2e0a9f84b6c55c439ebf2f22a234ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401340101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000204fe60343327adcaccb1781c88ff7869d2267d49ab5a5edc9a605d01354702d1c42553d33ba0273b54c52e589523cde509eb117046f5e63bd5e8a5a96f467c5f1234ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401350101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002080ccbc111d03cdf8d570d03ebc38c2b48651c6ce5ea2c6baaa11f90bda7e9a5e10b6afd88e0ce95bb14554c6dad04012fa8ce0c88a5932ad71da4d04a15d44c3234ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401360101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020f221abb685fc660057d2a1e1c60e3d39ec50c1c5d6f9696d2a5262092c55de03961fb68ada366165b25199757ce8a527f11d0744bbcbaad402815e09623dae04234ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401370101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000207b33c3208b567aa7a3c86ee1e7c1b6f9d80a58d0832c5d9974f4e616ee8c3657fd945975eb3855e5f0cd2afafd20b169a7763bdc73b64d1c2f096425d9c902eb244ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401380101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020f1be10ae2d05f116a355c237b763542784fa909e64116d3cabfd20717d26f924507916cc69e748edc3a9feadf7b79d1d19f16140e8f3260d7fbe9d1620e55f26244ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401390101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002089bf9d3aade2d9af33eb97a0d8213d815a9a0105eafc9d945ec22e019a566956bc75b97dfb5771d55e7bd108bb109705ba34952511ab96646cd2db4539fc3b2b244ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013a0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020ed8c5b87be2ab552137c997c4d84aafe9bce0b613e4390d2c958ed86e11df5060e0d6b356161c1ccbe486a26b777ff01b1247cd6b4b9d4d5b0f958d2e887caab244ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013b0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020a716b1bdf906c8accd99fd6da069b1325f0be434e1a62a3db4cf0046e5e1a55f87994452ce4bfdc92a07f49ed16903e68d8d48191e31d9558dad4805718311d5244ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013c0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020212647b93178e10ffc9b66c6d94df4a5ab20e90b02927f0da9eaf484a4e4ee23b9c5b6e8c1739811c932cdbecd192ae0bead4068782ca2e98805b8174d40f213244ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013d0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020f42c40f83aa763d523f8883a31429c107369b7d949b9b79d31d7b6b888d0b048faa4b4bcef4b3ed44ddf9b2b708397114484aa262a538c81b04103a02d8c033a254ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013e0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000202a1a1826cb6199be87d3916c6dfa1b48aebd5e886bd00e11e246c6c51f75c961436088fcdbf94cabbacefee23bb69b5ac30e3627f94500746630163249cc5029254ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013f0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020d211ddd5a8df8d9ef2758346e60595028496269e6c682cca2ad17c8c07533943bd9d279982bfe391b013160a66675ed11debd83c32a9efa02351eee65ac96d09254ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401400101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002065d4ca5f4c0832a0afb3da3e20df1d8eae6eddfcb6b5b9fb0b3e6c9946a05a296f1f5aac2480c10e93e13f3be00b38523dc036eb6ae49b93f815140ee2b08a27254ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401410101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020d3f8ff5dada7c4426e6d0e88e93373955666064c6ca405db38657769f4242f72b58e2687eae141c7bc9656b434bc95900a6935f00db43dc23ac155e380af8e9e254ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401420101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020c7d648289a24bec7554194de47e602a8872a02345122ad593df750ce9a7b882e42ad8e61dd8e6c702869587acb0d09b3355a1be27cb20ea909f51287f9e1b010254ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401430101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000201fd87fefb092863ee64d45fc97ce18c9b7496530e7ed7f0cb5b12a7d751b892c8d020f678641ba278d49d70430385ede2f830c46aa49ff7a3febe99d2a9896a9264ae75affff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401440101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020b88785c59608e75ba7d45dd8926e13ef4eb15d5e9d97b46a0b951db7ffa49648d9c4bce498d350184aae9af97f0aef0f366356d50b926c59bc1605ff6f41f144264ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401450101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020c1821fbfec02cf41ba87e84692f52db312592216af4f49921ac699e73842621a56d820e14b52e6f4fd113554754f3a8d65b80e7dfab2c84c5e7bb41a30c39977264ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401460101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000200f2fb0b626d66cd9e3f98076d65cad345d1cc3e6397d5ec67c232e47c0db4f5fc5808f07c0d1a3e6a23c9e8dc84d58c12758cd61a2f0e8ec3694a1ac08a89bda264ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401470101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002089d1eb345ef137d63ae0daf4de515629fd9e5cdb77acb9d7913d3c86c0266a04f385dbbdfd18fa6f8355a89c58370c50a71f59f44e2d2e505fb861960d155705264ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401480101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002040818bde028f677f06ecb1b193ad207694815456edc88f1aa9b8a2a93b61c944c21e035455f17270ff5e2a53c57c8c663f31cdb7a3a929de1499e3117358108f264ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401490101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020d1af87af32e8cf3c6205b0f0ae71179cef2daa6cdc2fe4ae7954531106e4125cf0b8a1a4c993ffd133335d84b9aba6159bb8129384a253131d1998f28c3d371b274ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014a0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020a4f1585d0a730294c0abfd956320eca370fc752ad7067f7db91a0ef67f16746fec6385bd31ab432ed3a13f7a6cdf0a6c87fe50c614372a58a5a3716c34456e83274ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014b0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000204ee7095bcea708bb45931557e5c20d77f6e4b3fbd2bc2fdb668b52ad27c8cb27043cd5b1662309701440c7941d61cfb95d0c98e22ff8ff8b5994149e988ab179274ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014c0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020b012e1b3e3143aa8e3e4d3cbc15bc0983fcfa62b3b94abb24d08208b1e97093ad713809d3b1678f325563577d3b6dd9ae4f1e5b05b70c3b16abd67d7161d9002274ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014d0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020b8acba68e4f66d328ba1fbc6749170c98614794a707adab49d9c39dc14e2af63adfd5417618dde8d0ee9191c4b110d0c76dcb65eb8adfd3f8a32a35ccceee445274ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014e0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002029e0881ae37eb32a5902fc32448031b71a86b5981c91127db557c8bd2762fe2c0c5a78ea3fb056e326e873cea75009c29c401fb77a415ee64ae4eca44bd617dd274ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014f0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002068e697d7ff9e7b9deb1ef1e62211ed8a6704c62d9fe2c34d12e31ecbe6cce4215ee8e5c95cb2105d0b8268ed13eaac6236eb3405df3099fc52d62169d218fcdf284ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401500101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002058153604c2e2d60acdf6ef5c7280f82bc964a111a763add4ec97dde452db636e034e10cf7e5158f62fe2674c89e8fc4ee94d2da62d81c0ffc8a237e8dfcb3e21284ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401510101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020ccc895a03f125b796254a8c4e6823f4d88a169ca9968c10ae1cf304720478511f182660cef31f84c0c6b384f084b243a77e2c271be610ac958124076306d9170284ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401520101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000201308762af23522f76d935ea4d713470ac9c71164608c8d21e5704a45f28a84314a16aa13a90a872e0dd3046458114dc745e37d2928bd9ff306ce7adb2567efb3284ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401530101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000205c26999ebc4f0c421d92c73efd003f1d31acba3b3325c979bb0eb5c4066e914f21a47de6874e6c2359af86d72abdee12b27bcebe0f1ce48751055005813d3f42284ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401540101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002002e491722884915c183a0c4875b4aa1c5015a68566dd940b7f5a139cbd1bee132d38f595981a444c7d868166ae50e371d83b5f59802bebfed056b93aad1b971e284ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401550101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000207f4f64f81d83467cadb46d0dc57fff43a1a3dae83b383fcefdd5cd6ccf28c60341f55e2175bc1d50b4d8a83f167091059a2a6e7d1a24d8223f50ca41313eef1b294ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401560101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002041fc3a8302ef83780b2239a633040f7c48f6aaba02b8ec2769a9d33a7e21fd278a5d44cb75516291cdf62cd51a1a9c71fd3d4879737d88216c6c4c6bffb0784a294ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401570101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002057509697de70999f71d48f79f41f89aa198e078c99c3a6ad51575234cc945d4a4e332a45285f3fff16e8c5cf79107ee110dc2a2f84456205f43d8f4e237a10da294ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401580101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020d420c4f3d25f59091da8b2f9282a5744620531912876d4f650b11cb70d8f7d781d984f86e81bd2c9db53c3515b6e3d6a28187b50adffb87df25608b738190bcf294ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401590101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020a2774594fdb16bce7f81fa28f6a52f5c1b17f0490b40f0054639d7c143693e63eac43d0751178d2574aa20506d1b91af13af688a8dfcdf1a48806f63e53b3245294ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015a0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000203f788c201ffaefadf4e088d314beec56dc5637251e2a40829dbebd5f14ae3e032163e10278a5cc75003c52739df112f1ea4fe0ed250ace8e544ecde713f47bfe294ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015b0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000202ffeb56a81ecd73d63a0d0af50248fb9bbc6fa7e8d36319759350cc40cfba742cda81243c6a438daeb547e1b36c9a5441e6556bf16bb9bfb839628c39a3785162a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015c0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020ff8b1de950c84c927333b035ca57b5bd45dc665defd48db70e842920f05bf761d184bdf283ba671c76c99173e4ec87e45dd97331c9000070edc81093bc4c7c872a4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015d0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000201dc138f0418892f79dd4e50e00a335540758d1fab773711848cc165c7615cc1cb29d7b37989b6570510e368a20f4fee2ca0142044f96a027830abdf438ddf7592a4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015e0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000202789894c1f3c280b8977092f55c3fd74ced22efa4f21d2ee295f2ac78bba02748488982a149b5ac96bef6be131e0b2f0ad9269ba66c9b4216901c0b81523123e2a4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015f0101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "0000002086ea7fe01933055512578393daeea43f5e7403c60fb9c841d8771c78b1faea4213a48742e06190847a40cabbda6d48f715802bdb3cbab7ad7a2e5c345d557b082a4ae75affff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401600101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000208a2b516ecc28433867697c0e55e4990333193eda69a436d23e9c5215dbbcb5755abfb8140edec21a383e1e3e31288ee0130a86564e5c3da9764594d8365134652a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401610101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000200a95e3f7f4cd783e34700d894e47693a3705969ff28c6fa84efa53456eb54a2d49aa4519391183deb58058f99a6abb7638fe81f079b31c4e090d486c49e047ac2b4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401620101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000201b512cae4c5a8902f07d327b483dcc5d27c15ad28f6e4cd11e00f6394c7fe50f90fad2cd50b41d4ef45e76c2a456b98c180632bb4b44e0cd18ce90679fe54e552b4ae75affff7f200500000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401630101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020df8ea83bf52082065acd5d3452bfdb299a8c7c2f63a20c151491da1405304a60b7d1f44666531483df3d67c15f2c231718ad93b63b851dce5ff4c4a67f524ffa2b4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401640101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "00000020ad23c2a6baabbb8daf4aeb52432c563e100af5e9e05f5987d9fd36cd81dbd450d31fceb8fe0a682f6017ca3dbb582f3a2f06e5d99ec99c42c8a744dd4c9216b82b4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401650101ffffffff0200f2052a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000", + "000000206eb707a145192df4f1ef48cf74cd5576863d5df91a7aa616519f1f6409b23d037395edfd4c06c106ee0139d5f59ac61d349967085afabffe44b950e6382850a52b4ae75affff7f200200000002020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401660101ffffffff026c03062a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ed2c4121db32ea6e2bb403b3e6839bf1765cbba486b1d3507c4d2688d9c6eb75130120000000000000000000000000000000000000000000000000000000000000000000000000020000000128394022bf44bff30d7399cb5a16e3b94fed67dc174c2e1d77df91bad5a51cb3000000006a473044022022ad106efc06e56991dcacb73099e24904663af05f80464b528648084a6ed1aa02200a3281be027912a86f6ee5cfa494d941f3955b01adef77e2819398f4d1440be601210227d85ba011276cf25b51df6a188b75e604b38770a462b2d0e9fb2fc839ef5d3ffeffffff0200286bee0000000017a9143e9be6834f3e98b3872cd23cb8b0919a0092ba258794b89a3b000000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac65000000", + "0000002071142c94092f81b3d886e458f1493b6566e8ddc26c17fc0af8e812fc0ffd133cdbe1647b7728f567704f166c78eaee0c86701ea5e5d2544aa531ce6f99f3fae82b4ae75affff7f200100000004020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401670101ffffffff02e015072a010000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9edd2eeeba6a67778105328e6b0f3d675de2d65af47baf5832dc824091cf1cbbc1c01200000000000000000000000000000000000000000000000000000000000000000000000000200000001b4249e0227e3add5ead776ce6d5ff2e97b270dc6efe2d3edb630a0ced11bf98b010000006a47304402206f734bd90a80608f169f8640ace087e3062a6fde4c48686984b96f57b11cc04402204f3ed7cc5615938d3bd4d36cfbb1e9e9b159b674796c7d88e039ca47bae7d56501210227d85ba011276cf25b51df6a188b75e604b38770a462b2d0e9fb2fc839ef5d3ffeffffff0294d7a4350000000017a914e790b54f82863c5e9ce37d488584720cb021eb5b87acdbf405000000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac6600000002000000000101b4249e0227e3add5ead776ce6d5ff2e97b270dc6efe2d3edb630a0ced11bf98b0000000017160014509ab3d9ad4b38230aabd1d240c8546e848f3400feffffff02005ed0b20000000017a9144e3d5db2eacf8f98bff3f46fde272c2a85e41f6187e0bc9a3b000000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac02473044022040c45b0b84b1218ca9a95842b9cd8b3fa8263dc5d11bbd2a31593a4f986d915e02204c239cb34cfbba26388dc0842d32e4b671023aac3a5f36538913b1dc7088733b012103476b9de917463589bf76f169f93bc9f05677afee492e0916545c58b6b3014ab366000000020000000112d2f07672102dc6f099c4be308f598e4c4da1a7e0cb462ae14f0444525a1332000000006a47304402206ec6d7f188ef042d1750647d3196de9d080324bd546fc90c93d247f980e1a33e02206ae45e0d2fad231d02463419c87cc3b9ba80d3b145e43f490a90ad6fdbea80a201210227d85ba011276cf25b51df6a188b75e604b38770a462b2d0e9fb2fc839ef5d3ffeffffff0294166bee0000000017a914ca2e18a77e4479f56faa1deb0bbc8f28427f29928700ca9a3b000000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac66000000" ], "mocktime": 1525107225, "stats": [ @@ -111,7 +111,7 @@ "avgfee": 0, "avgfeerate": 0, "avgtxsize": 0, - "blockhash": "29a36876ddc6899a2541afc78ce2b3ca7659cfc01875e8208d9110d59bce3a9b", + "blockhash": "033db209641f9f5116a67a1af95d3d867655cd74cf48eff1f42d1945a107b76e", "feerate_percentiles": [ 0, 0, @@ -148,7 +148,7 @@ "avgfee": 4460, "avgfeerate": 20, "avgtxsize": 223, - "blockhash": "0aa1cae78efd1efcd5203366a257b6ccf4c9e4960f6b8a3724ad790ab568a10f", + "blockhash": "3c13fd0ffc12e8f80afc176cc2dde866653b49f158e486d8b3812f09942c1471", "feerate_percentiles": [ 20, 20, @@ -185,7 +185,7 @@ "avgfee": 24906, "avgfeerate": 121, "avgtxsize": 231, - "blockhash": "53e416e2538bc783c42a7aea566e884321afed893e9e58cf356d6429759dfa46", + "blockhash": "21bcade91ede54671826448840b2fa3a488ab56444aee71d4cd79c8357651244", "feerate_percentiles": [ 20, 20, diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index 9aff08fdc7dae..e21afc3d19ed1 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -91,7 +91,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): def __init__(self): """Sets test framework defaults. Do not override this method. Instead, override the set_test_params() method""" - self.chain = 'regtest' + self.chain = 'regtest2' self.setup_clean_chain = False self.nodes = [] self.network_thread = None From 40436e67921dec474015f621c2db35e1cfbcfb54 Mon Sep 17 00:00:00 2001 From: Karl-Johan Alm Date: Wed, 17 Jul 2019 17:33:25 +0900 Subject: [PATCH 07/31] add witness commitment section support to primitive/block This also moves GetWitnessCommitmentIndex out of validation.cpp into CBlock, with 3 lines affected (GetWitnessCommitmentIndex(block) -> block.GetWitnessCommitmentIndex()). --- src/primitives/block.cpp | 62 ++++++++++++++++++++++++++++++++++++++++ src/primitives/block.h | 44 ++++++++++++++++++++++++++++ src/validation.cpp | 21 ++------------ 3 files changed, 109 insertions(+), 18 deletions(-) diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 60c7c2d16083e..b41b90612d9dc 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -29,3 +29,65 @@ std::string CBlock::ToString() const } return s.str(); } + +bool CBlock::GetWitnessCommitmentSection(const uint8_t header[4], std::vector& result) const +{ + int cidx = GetWitnessCommitmentIndex(); + if (cidx == -1) return false; + auto script = vtx.at(0)->vout.at(cidx).scriptPubKey; + opcodetype opcode; + CScript::const_iterator pc = script.begin(); + ++pc; // move beyond initial OP_RETURN + while (script.GetOp(pc, opcode, result)) { + if (result.size() > 3 && !memcmp(result.data(), header, 4)) { + result.erase(result.begin(), result.begin() + 4); + return true; + } + } + result.clear(); + return false; +} + +bool CBlock::SetWitnessCommitmentSection(CMutableTransaction& mtx, const uint8_t header[4], const std::vector data) +{ + int cidx = GetWitnessCommitmentIndex(mtx); + if (cidx == -1) return false; + + CScript result; + std::vector pushdata; + auto script = mtx.vout[cidx].scriptPubKey; + opcodetype opcode; + CScript::const_iterator pc = script.begin(); + result.push_back(*pc++); + bool found = false; + while (script.GetOp(pc, opcode, pushdata)) { + if (pushdata.size() > 0) { + if (pushdata.size() > 3 && !memcmp(pushdata.data(), header, 4)) { + // replace pushdata + found = true; + pushdata.erase(pushdata.begin() + 4, pushdata.end()); + pushdata.insert(pushdata.end(), data.begin(), data.end()); + } + result << pushdata; + } else { + result << opcode; + } + } + if (!found) { + // append section as it did not exist + pushdata.clear(); + pushdata.insert(pushdata.end(), header, header + 4); + pushdata.insert(pushdata.end(), data.begin(), data.end()); + result << pushdata; + } + mtx.vout[cidx].scriptPubKey = result; + return true; +} + +bool CBlock::SetWitnessCommitmentSection(const uint8_t header[4], const std::vector data) +{ + auto mtx = CMutableTransaction(*vtx[0]); + if (!SetWitnessCommitmentSection(mtx, header, data)) return false; + vtx[0] = std::make_shared(mtx); + return true; +} diff --git a/src/primitives/block.h b/src/primitives/block.h index 750d42efbc236..db6c9be4185c3 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -116,6 +116,50 @@ class CBlock : public CBlockHeader return block; } + /** + * Get the vout index of the segwit commitment in the coinbase transaction of this block. + * + * Returns -1 if no witness commitment was found. + */ + inline int GetWitnessCommitmentIndex() const + { + return vtx.empty() ? -1 : GetWitnessCommitmentIndex(*vtx.at(0)); + } + + /** + * Get the vout index of the segwit commitment in the given coinbase transaction. + * + * Returns -1 if no witness commitment was found. + */ + template static inline int GetWitnessCommitmentIndex(const T& coinbase) { + for (int64_t o = coinbase.vout.size() - 1; o > -1; --o) { + auto vospk = coinbase.vout[o].scriptPubKey; + if (vospk.size() >= 38 && vospk[0] == OP_RETURN && vospk[1] == 0x24 && vospk[2] == 0xaa && vospk[3] == 0x21 && vospk[4] == 0xa9 && vospk[5] == 0xed) { + return o; + } + } + return -1; + } + + /** + * Attempt to get the data for the section with the given header in the witness commitment of this block. + * + * Returns false if header was not found. The data (excluding the 4 byte header) is written into result if found. + */ + bool GetWitnessCommitmentSection(const uint8_t header[4], std::vector& result) const; + + /** + * Attempt to add or update the data for the section with the given header in the witness commitment of this block. + * + * This operation may fail and return false, if no witness commitment exists upon call time. Returns true on success. + */ + bool SetWitnessCommitmentSection(const uint8_t header[4], const std::vector data); + + /** + * The tx based equivalent of the above. + */ + static bool SetWitnessCommitmentSection(CMutableTransaction& tx, const uint8_t header[4], const std::vector data); + std::string ToString() const; }; diff --git a/src/validation.cpp b/src/validation.cpp index 772e0fd67199a..dac197c812693 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3135,24 +3135,9 @@ bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& pa return (height >= params.SegwitHeight); } -// Compute at which vout of the block's coinbase transaction the witness -// commitment occurs, or -1 if not found. -static int GetWitnessCommitmentIndex(const CBlock& block) -{ - int commitpos = -1; - if (!block.vtx.empty()) { - for (size_t o = 0; o < block.vtx[0]->vout.size(); o++) { - if (block.vtx[0]->vout[o].scriptPubKey.size() >= 38 && block.vtx[0]->vout[o].scriptPubKey[0] == OP_RETURN && block.vtx[0]->vout[o].scriptPubKey[1] == 0x24 && block.vtx[0]->vout[o].scriptPubKey[2] == 0xaa && block.vtx[0]->vout[o].scriptPubKey[3] == 0x21 && block.vtx[0]->vout[o].scriptPubKey[4] == 0xa9 && block.vtx[0]->vout[o].scriptPubKey[5] == 0xed) { - commitpos = o; - } - } - } - return commitpos; -} - void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams) { - int commitpos = GetWitnessCommitmentIndex(block); + int commitpos = block.GetWitnessCommitmentIndex(); static const std::vector nonce(32, 0x00); if (commitpos != -1 && IsWitnessEnabled(pindexPrev, consensusParams) && !block.vtx[0]->HasWitness()) { CMutableTransaction tx(*block.vtx[0]); @@ -3165,7 +3150,7 @@ void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPr std::vector GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams) { std::vector commitment; - int commitpos = GetWitnessCommitmentIndex(block); + int commitpos = block.GetWitnessCommitmentIndex(); std::vector ret(32, 0x00); if (consensusParams.SegwitHeight != std::numeric_limits::max()) { if (commitpos == -1) { @@ -3303,7 +3288,7 @@ static bool ContextualCheckBlock(const CBlock& block, CValidationState& state, c // multiple, the last one is used. bool fHaveWitness = false; if (nHeight >= consensusParams.SegwitHeight) { - int commitpos = GetWitnessCommitmentIndex(block); + int commitpos = block.GetWitnessCommitmentIndex(); if (commitpos != -1) { bool malleated = false; uint256 hashWitness = BlockWitnessMerkleRoot(block, &malleated); From 0431724a6f0e34627998b2c41a37f40295e5e2b8 Mon Sep 17 00:00:00 2001 From: Karl-Johan Alm Date: Wed, 17 Jul 2019 17:38:43 +0900 Subject: [PATCH 08/31] add simple signature support (checker/creator) The simple signature takes a sighash as argument and verifies a signature and pubkey against it. It is used in signet for verifying blocks, but can be used for practically anything. --- src/script/interpreter.cpp | 14 ++++++++++++++ src/script/interpreter.h | 12 ++++++++++++ src/script/sign.cpp | 9 +++++++++ src/script/sign.h | 11 +++++++++++ 4 files changed, 46 insertions(+) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index f8701b6d01a6d..d7af9841d8c45 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1416,6 +1416,20 @@ bool GenericTransactionSignatureChecker::CheckSequence(const CScriptNum& nSeq template class GenericTransactionSignatureChecker; template class GenericTransactionSignatureChecker; +bool SimpleSignatureChecker::CheckSig(const std::vector& vchSigIn, const std::vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const +{ + CPubKey pubkey(vchPubKey); + if (!pubkey.IsValid()) return false; + + // Hash type is one byte tacked on to the end of the signature + std::vector vchSig(vchSigIn); + if (vchSig.empty()) return false; + // int nHashType = vchSig.back(); + vchSig.pop_back(); + + return pubkey.Verify(hash, vchSig); +} + static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion, const std::vector& program, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) { std::vector > stack; diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 276ff9a58a870..d49c955d50f87 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -162,6 +162,18 @@ class BaseSignatureChecker virtual ~BaseSignatureChecker() {} }; +/** A general purpose signature checker. */ +class SimpleSignatureChecker : public BaseSignatureChecker +{ +private: + uint256 hash; + +public: + const uint256& GetHash() const { return hash; } + explicit SimpleSignatureChecker(const uint256& hash_in) : hash(hash_in) {} + bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override; +}; + template class GenericTransactionSignatureChecker : public BaseSignatureChecker { diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 13481af9c5063..a356c13908a39 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -33,6 +33,15 @@ bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provid return true; } +bool SimpleSignatureCreator::CreateSig(const SigningProvider& provider, std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const +{ + CKey key; + if (!provider.GetKey(keyid, key)) return false; + if (!key.Sign(checker.GetHash(), vchSig)) return false; + vchSig.push_back((unsigned char)SIGHASH_ALL); + return true; +} + static bool GetCScript(const SigningProvider& provider, const SignatureData& sigdata, const CScriptID& scriptid, CScript& script) { if (provider.GetCScript(scriptid, script)) { diff --git a/src/script/sign.h b/src/script/sign.h index 0e751afd3ba5e..6de734a8c2047 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -32,6 +32,17 @@ class BaseSignatureCreator { virtual bool CreateSig(const SigningProvider& provider, std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const =0; }; +/** A general purpose signature creator. */ +class SimpleSignatureCreator : public BaseSignatureCreator +{ + SimpleSignatureChecker checker; + +public: + explicit SimpleSignatureCreator(const uint256& hashIn) : BaseSignatureCreator(), checker(hashIn) {}; + const BaseSignatureChecker& Checker() const override { return checker; } + bool CreateSig(const SigningProvider& provider, std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override; +}; + /** A signature creator for transactions. */ class MutableTransactionSignatureCreator : public BaseSignatureCreator { const CMutableTransaction* txTo; From 56f407b7f3c0301d3631c9042bfa85d2195d63ed Mon Sep 17 00:00:00 2001 From: Karl-Johan Alm Date: Wed, 17 Jul 2019 17:41:32 +0900 Subject: [PATCH 09/31] add signet basic support (signet.cpp) --- src/Makefile.am | 2 ++ src/consensus/params.h | 6 +++++ src/signet.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++ src/signet.h | 43 +++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 src/signet.cpp create mode 100644 src/signet.h diff --git a/src/Makefile.am b/src/Makefile.am index 8fc7f61d4b78e..0175b93e03626 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -189,6 +189,7 @@ BITCOIN_CORE_H = \ script/signingprovider.h \ script/standard.h \ shutdown.h \ + signet.h \ streams.h \ support/allocators/secure.h \ support/allocators/zeroafterfree.h \ @@ -471,6 +472,7 @@ libbitcoin_common_a_SOURCES = \ script/sign.cpp \ script/signingprovider.cpp \ script/standard.cpp \ + signet.cpp \ versionbitsinfo.cpp \ warnings.cpp \ $(BITCOIN_CORE_H) diff --git a/src/consensus/params.h b/src/consensus/params.h index 8263b0fef4a89..a9da0bba133be 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -79,6 +79,12 @@ struct Params { int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; } uint256 nMinimumChainWork; uint256 defaultAssumeValid; + + /** + * If true, witness commitments contain a payload equal to a Bitcoin Script solution + * to a signet challenge as defined in the chain params. + */ + bool signet_blocks{false}; }; } // namespace Consensus diff --git a/src/signet.cpp b/src/signet.cpp new file mode 100644 index 0000000000000..e6b8d32186cde --- /dev/null +++ b/src/signet.cpp @@ -0,0 +1,57 @@ +// Copyright (c) 2019 The Bitcoin Core 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