def extend_genesis_util(self, overrides): print vnm = None try: vnm = get_default_vnm(2, overrides=overrides) # Test genesis util cfg = vnm.get_configuration(0) ledger_type = cfg['LedgerType'] gblock_file = genesis_info_file_name(cfg['DataDirectory']) self.assertFalse(os.path.exists(gblock_file)) vnm.do_genesis() self.assertTrue(os.path.exists(gblock_file)) genesis_dat = None with open(gblock_file, 'r') as f: genesis_dat = json.load(f) self.assertTrue('GenesisId' in genesis_dat.keys()) head = genesis_dat['GenesisId'] # Verify genesis tool efficacy on a minimal network vnm.launch() # ...verify validator is extending tgt_block to = TimeOut(64) blk_lists = None prog_str = 'testing root extension (expect root: %s)' % head with Progress(prog_str) as p: print while not to.is_timed_out() and blk_lists is None: try: blk_lists = get_blocklists(['http://localhost:8800']) print 'block_lists: %s' % blk_lists if len(blk_lists) < 1 or len(blk_lists[0]) < 2: blk_lists = None except MessageException as e: pass time.sleep(2) p.step() self.assertIsNotNone(blk_lists) root = blk_lists[0][0] self.assertEqual(head, root) # ...verify general convergence to = TimeOut(32) with Progress('testing root convergence') as p: print while (is_convergent(vnm.urls(), tolerance=1, standard=1) is False and not to.is_timed_out()): time.sleep(2) p.step() # ...verify convergence on the genesis block blk_lists = get_blocklists(['http://localhost:8800']) root = blk_lists[0][0] self.assertEqual(head, root) print 'network converged on root: %s' % root finally: if vnm is not None: archive_name = 'Test%sGenesisResults' % ledger_type.upper() vnm.shutdown(archive_name=archive_name)
def do_genesis(self, do_genesis_validator_idx=0, **kwargs): assert self._initialized cfg = self.get_configuration(do_genesis_validator_idx) overrides = { "InitialConnectivity": 0, "DevModePublisher": True, } cfg.update(overrides) self.set_configuration(do_genesis_validator_idx, cfg) config_file = self.write_configuration(do_genesis_validator_idx) cfg = self.get_configuration(do_genesis_validator_idx) ledger_type = cfg.get('LedgerType', 'poet0') # validate user input to Popen assert ledger_type in ['dev_mode', 'poet0', 'poet1'] assert os.path.isfile(config_file) alg_name = ledger_type if ledger_type == 'dev_mode': alg_name = 'dev-mode' cli_args = 'admin %s-genesis --config %s' % (alg_name, config_file) try: executable = find_executable('sawtooth') except ExitError: path = os.path.dirname(self.node_controller.txnvalidator) executable = os.path.join(path, 'sawtooth') assert os.path.isfile(executable) cmd = '%s %s %s' % (sys.executable, executable, cli_args) proc = subprocess.Popen(cmd.split()) proc.wait() if proc.returncode != 0: return # Get genesis block id gblock_file = genesis_info_file_name(cfg['DataDirectory']) assert os.path.exists(gblock_file) is True genesis_dat = None with open(gblock_file, 'r') as f: genesis_dat = json.load(f) assert 'GenesisId' in genesis_dat.keys() head = genesis_dat['GenesisId'] print('created genesis block: %s' % head)
def do_genesis(self, do_genesis_validator_idx=0, **kwargs): assert self._initialized cfg = self.get_configuration(do_genesis_validator_idx) overrides = { "InitialConnectivity": 0, "DevModePublisher": True, } cfg.update(overrides) self.set_configuration(do_genesis_validator_idx, cfg) config_file = self.write_configuration(do_genesis_validator_idx) cfg = self.get_configuration(do_genesis_validator_idx) ledger_type = cfg.get('LedgerType', 'poet1') # validate user input to Popen assert ledger_type in ['dev_mode', 'poet1'] assert os.path.isfile(config_file) alg_name = ledger_type if ledger_type == 'dev_mode': alg_name = 'dev-mode' cli_args = 'admin %s-genesis --config %s' % (alg_name, config_file) try: executable = find_executable('sawtooth') except ExitError: path = os.path.dirname(self.node_controller.txnvalidator) executable = os.path.join(path, 'sawtooth') assert os.path.isfile(executable) cmd = '%s %s %s' % (sys.executable, executable, cli_args) proc = subprocess.Popen(cmd.split()) proc.wait() if proc.returncode != 0: return # Get genesis block id gblock_file = genesis_info_file_name(cfg['DataDirectory']) assert os.path.exists(gblock_file) is True genesis_dat = None with open(gblock_file, 'r') as f: genesis_dat = json.load(f) assert 'GenesisId' in genesis_dat.keys() head = genesis_dat['GenesisId'] print('created genesis block: %s' % head)
def do_poet0_genesis(args): # Get ledger config: # ...set the default value of config because argparse 'default' in # ...combination with action='append' does the wrong thing. if args.config is None: args.config = ['txnvalidator.js'] # ...convert any comma-delimited argument strings to list elements for arglist in [args.config]: if arglist is not None: for arg in arglist: if ',' in arg: loc = arglist.index(arg) arglist.pop(loc) for element in reversed(arg.split(',')): arglist.insert(loc, element) options_config = ArgparseOptionsConfig([('conf_dir', 'ConfigDirectory'), ('data_dir', 'DataDirectory'), ('type', 'LedgerType'), ('log_config', 'LogConfigFile'), ('keyfile', 'KeyFile'), ('node', 'NodeName'), ('verbose', 'Verbose'), ('family', 'TransactionFamilies')], args) cfg = get_validator_configuration(args.config, options_config) # Obtain Journal object: # ...set WaitTimer globals target_wait_time = cfg.get("TargetWaitTime") initial_wait_time = cfg.get("InitialWaitTime") certificate_sample_length = cfg.get('CertificateSampleLength') fixed_duration_blocks = cfg.get("FixedDurationBlocks") from journal.consensus.poet0.wait_timer import set_wait_timer_globals set_wait_timer_globals( target_wait_time, initial_wait_time, certificate_sample_length, fixed_duration_blocks, ) # ...build Gossip dependency (nd, _) = parse_networking_info(cfg) minimum_retries = cfg.get("MinimumRetries") retry_interval = cfg.get("RetryInterval") gossiper = Gossip(nd, minimum_retries, retry_interval) # ...build Journal min_txn_per_block = cfg.get("MinimumTransactionsPerBlock") max_txn_per_block = cfg.get("MaxTransactionsPerBlock") max_txn_age = cfg.get("MaxTxnAge") genesis_ledger = cfg.get("GenesisLedger") data_directory = cfg.get("DataDirectory") store_type = cfg.get("StoreType") stat_domains = {} from journal.consensus.poet0.poet_consensus import PoetConsensus consensus_obj = PoetConsensus(cfg) journal = Journal( gossiper.LocalNode, gossiper, gossiper.dispatcher, consensus_obj, stat_domains, minimum_transactions_per_block=min_txn_per_block, max_transactions_per_block=max_txn_per_block, max_txn_age=max_txn_age, genesis_ledger=genesis_ledger, data_directory=data_directory, store_type=store_type, ) # ...add 'built in' txn families default_transaction_families = [endpoint_registry] for txn_family in default_transaction_families: txn_family.register_transaction_types(journal) # ...add auxiliary transaction families for txn_family_module_name in cfg.get("TransactionFamilies", []): txn_family = importlib.import_module(txn_family_module_name) txn_family.register_transaction_types(journal) # Make genesis block: # ...make sure there is no current chain here, or fail # ...create block g_block g_block = journal.build_block(genesis=True) journal.claim_block(g_block) # ...simulate receiving the genesis block msg from reactor to force commit g_block_msg = gossiper.IncomingMessageQueue.pop() journal.dispatcher.dispatch(g_block_msg) journal.initialization_complete() head = journal.most_recent_committed_block_id chain_len = len(journal.committed_block_ids()) # Run shutdown: # ...persist new state journal.shutdown() # ...release gossip obj's UDP port gossiper.Listener.loseConnection() gossiper.Listener.connectionLost(reason=None) # Log genesis data, then write it out to ease dissemination genesis_data = { 'GenesisId': head, 'ChainLength': chain_len, } gblock_fname = genesis_info_file_name(cfg['DataDirectory']) LOGGER.info('genesis data: %s', genesis_data) LOGGER.info('writing genesis data to %s', gblock_fname) with open(gblock_fname, 'w') as f: f.write(json.dumps(genesis_data))
def extend_genesis_util(self, ledger_type, pre_overrides, post_overrides): print top = None try: # Get configs and resources for a ValidatorManager compliant nodes top = get_default_sim_controller(2, ledger_type=ledger_type) # Set up validator-0 cfg = top.get_configuration(0) cfg.update(pre_overrides) top.set_configuration(0, cfg) config_file = top.write_configuration(0) # Test genesis tool print 'testing genesis util...' gblock_file = genesis_info_file_name(cfg['DataDirectory']) self.assertFalse(os.path.exists(gblock_file)) cli_args = 'admin %s-genesis --config %s' % (ledger_type, config_file) sawtooth_cli_intercept(cli_args) # Get genesis block id self.assertTrue(os.path.exists(gblock_file)) genesis_dat = None with open(gblock_file, 'r') as f: genesis_dat = json.load(f) self.assertTrue('GenesisId' in genesis_dat.keys()) head = genesis_dat['GenesisId'] # Verify genesis tool efficacy on a minimal network print 'testing efficacy...' # ...apply validator-related overrides to validator-0 cfg = top.get_configuration(0) cfg.update(post_overrides) top.set_configuration(0, cfg) # ...launch entire network top.launch(probe_seconds=0, reg_seconds=0) # ...verify validator is extending tgt_block to = TimeOut(64) blk_lists = None prog_str = 'testing root extension (expect root: %s)' % head with Progress(prog_str) as p: print while not to.is_timed_out() and blk_lists is None: try: blk_lists = get_blocklists(['http://localhost:8800']) print 'block_lists: %s' % blk_lists if len(blk_lists) < 1 or len(blk_lists[0]) < 2: blk_lists = None except MessageException as e: pass time.sleep(2) p.step() self.assertIsNotNone(blk_lists) root = blk_lists[0][0] self.assertEqual(head, root) # ...verify general convergence to = TimeOut(32) with Progress('testing root convergence') as p: print while (is_convergent(top.urls(), tolerance=1, standard=1) is False and not to.is_timed_out()): time.sleep(2) p.step() # ...verify convergence on the genesis block blk_lists = get_blocklists(['http://localhost:8800']) root = blk_lists[0][0] self.assertEqual(head, root) print 'network converged on root: %s' % root finally: if top is not None: archive_name = 'Test%sGenesisResults' % ledger_type.upper() top.shutdown(archive_name=archive_name)
def do_poet1_genesis(args): # Get journal config: cfg = mirror_validator_parsing(args) # Check for existing block store node_name = cfg.get("NodeName") data_directory = cfg.get("DataDirectory") store_type = cfg.get("StoreType") check_for_chain(data_directory, node_name, store_type) # Obtain Journal object: # ...set WaitTimer globals target_wait_time = cfg.get("TargetWaitTime") initial_wait_time = cfg.get("InitialWaitTime") certificate_sample_length = cfg.get('CertificateSampleLength') fixed_duration_blocks = cfg.get("FixedDurationBlocks") set_wait_timer_globals( target_wait_time, initial_wait_time, certificate_sample_length, fixed_duration_blocks, ) # ...build Gossip dependency (nd, _) = parse_networking_info(cfg) minimum_retries = cfg.get("MinimumRetries") retry_interval = cfg.get("RetryInterval") gossiper = Gossip(nd, minimum_retries, retry_interval) # ...build Journal min_txn_per_block = cfg.get("MinimumTransactionsPerBlock") max_txn_per_block = cfg.get("MaxTransactionsPerBlock") max_txn_age = cfg.get("MaxTxnAge") stat_domains = {} consensus_obj = PoetConsensus(cfg) journal = Journal( gossiper.LocalNode, gossiper, gossiper.dispatcher, consensus_obj, stat_domains, minimum_transactions_per_block=min_txn_per_block, max_transactions_per_block=max_txn_per_block, max_txn_age=max_txn_age, data_directory=data_directory, store_type=store_type, ) # ...add 'built in' txn families default_transaction_families = [ endpoint_registry, validator_registry, ] for txn_family in default_transaction_families: txn_family.register_transaction_types(journal) # ...add auxiliary transaction families for txn_family_module_name in cfg.get("TransactionFamilies", []): txn_family = importlib.import_module(txn_family_module_name) txn_family.register_transaction_types(journal) # Make genesis block: # ...make sure there is no current chain here, or fail # ...pop VR seed (we'll presently defer resolving VR seed issues) vr_seed = gossiper.IncomingMessageQueue.pop() journal.initial_transactions.append(vr_seed.Transaction) # ...create block g_block (including VR seed txn just popped) journal.on_genesis_block.fire(journal) journal.initializing = False for txn in journal.initial_transactions: journal.add_pending_transaction(txn, build_block=False) g_block = journal.build_block(genesis=True) # seed later... journal.claim_block(g_block) # ...simulate receiving the genesis block msg from reactor to force commit g_block_msg = gossiper.IncomingMessageQueue.pop() poet_public_key = g_block.poet_public_key journal.dispatcher.dispatch(g_block_msg) journal.initialization_complete() head = journal.most_recent_committed_block_id chain_len = len(journal.committed_block_ids()) # Run shutdown: # ...persist new state journal.shutdown() # ...release gossip obj's UDP port gossiper.Listener.loseConnection() gossiper.Listener.connectionLost(reason=None) # Log genesis data, then write it out to ease dissemination genesis_data = { 'GenesisId': head, 'ChainLength': chain_len, 'PoetPublicKey': poet_public_key, } gblock_fname = genesis_info_file_name(cfg['DataDirectory']) LOGGER.info('genesis data: %s', genesis_data) LOGGER.info('writing genesis data to %s', gblock_fname) with open(gblock_fname, 'w') as f: f.write(json.dumps(genesis_data, indent=4))
def do_dev_mode_genesis(args): # Get journal config: cfg = mirror_validator_parsing(args) # Check for existing block store node_name = cfg.get("NodeName") data_directory = cfg.get("DataDirectory") store_type = cfg.get("StoreType") check_for_chain(data_directory, node_name, store_type) # Obtain Journal object: # ...build Gossip dependency (nd, _) = parse_networking_info(cfg) minimum_retries = cfg.get("MinimumRetries") retry_interval = cfg.get("RetryInterval") gossiper = Gossip(nd, minimum_retries, retry_interval) # ...build Journal min_txn_per_block = cfg.get("MinimumTransactionsPerBlock") max_txn_per_block = cfg.get("MaxTransactionsPerBlock") max_txn_age = cfg.get("MaxTxnAge") stat_domains = {} consensus_obj = DevModeConsensus(block_publisher=True, block_wait_time=cfg.get('BlockWaitTime')) journal = Journal(gossiper.LocalNode, gossiper, gossiper.dispatcher, consensus_obj, stat_domains, minimum_transactions_per_block=min_txn_per_block, max_transactions_per_block=max_txn_per_block, max_txn_age=max_txn_age, data_directory=data_directory, store_type=store_type, ) # ...add 'built in' txn families default_transaction_families = [ endpoint_registry ] for txn_family in default_transaction_families: txn_family.register_transaction_types(journal) # ...add auxiliary transaction families for txn_family_module_name in cfg.get("TransactionFamilies", []): txn_family = importlib.import_module(txn_family_module_name) txn_family.register_transaction_types(journal) # Make genesis block: # ...make sure there is no current chain here, or fail # ...create block g_block journal.on_genesis_block.fire(journal) journal.initializing = False for txn in journal.initial_transactions: journal.add_pending_transaction(txn, build_block=False) g_block = journal.build_block(genesis=True) journal.claim_block(g_block) # ...simulate receiving the genesis block msg from reactor to force commit g_block_msg = gossiper.IncomingMessageQueue.pop() journal.dispatcher.dispatch(g_block_msg) journal.initialization_complete() head = journal.most_recent_committed_block_id chain_len = len(journal.committed_block_ids()) # Run shutdown: # ...persist new state journal.shutdown() # ...release gossip obj's UDP port gossiper.Listener.loseConnection() gossiper.Listener.connectionLost(reason=None) # Log genesis data, then write it out to ease dissemination genesis_data = { 'GenesisId': head, 'ChainLength': chain_len, } gblock_fname = genesis_info_file_name(cfg['DataDirectory']) LOGGER.info('genesis data: %s', genesis_data) LOGGER.info('writing genesis data to %s', gblock_fname) with open(gblock_fname, 'w') as f: f.write(json.dumps(genesis_data))
def do_poet1_genesis(args): # Get journal config: cfg = mirror_validator_parsing(args) # Check for existing block store node_name = cfg.get("NodeName") data_directory = cfg.get("DataDirectory") store_type = cfg.get("StoreType") check_for_chain(data_directory, node_name, store_type) # Obtain Journal object: # ...set WaitTimer globals target_wait_time = cfg.get("TargetWaitTime") initial_wait_time = cfg.get("InitialWaitTime") certificate_sample_length = cfg.get('CertificateSampleLength') fixed_duration_blocks = cfg.get("FixedDurationBlocks") set_wait_timer_globals(target_wait_time, initial_wait_time, certificate_sample_length, fixed_duration_blocks, ) # ...build Gossip dependency (nd, _) = parse_networking_info(cfg) minimum_retries = cfg.get("MinimumRetries") retry_interval = cfg.get("RetryInterval") gossiper = Gossip(nd, minimum_retries, retry_interval) # ...build Journal min_txn_per_block = cfg.get("MinimumTransactionsPerBlock") max_txn_per_block = cfg.get("MaxTransactionsPerBlock") max_txn_age = cfg.get("MaxTxnAge") stat_domains = {} consensus_obj = PoetConsensus(cfg) journal = Journal(gossiper.LocalNode, gossiper, gossiper.dispatcher, consensus_obj, stat_domains, minimum_transactions_per_block=min_txn_per_block, max_transactions_per_block=max_txn_per_block, max_txn_age=max_txn_age, data_directory=data_directory, store_type=store_type, ) # ...add 'built in' txn families default_transaction_families = [ endpoint_registry, validator_registry, ] for txn_family in default_transaction_families: txn_family.register_transaction_types(journal) # ...add auxiliary transaction families for txn_family_module_name in cfg.get("TransactionFamilies", []): txn_family = importlib.import_module(txn_family_module_name) txn_family.register_transaction_types(journal) # Make genesis block: consensus_obj.register_signup_information(journal=journal) # ...make sure there is no current chain here, or fail # ...pop VR seed (we'll presently defer resolving VR seed issues) vr_seed = gossiper.IncomingMessageQueue.pop() journal.initial_transactions.append(vr_seed.Transaction) # ...create block g_block (including VR seed txn just popped) journal.on_genesis_block.fire(journal) journal.initializing = False for txn in journal.initial_transactions: journal.add_pending_transaction(txn, build_block=False) g_block = journal.build_block(genesis=True) # seed later... journal.claim_block(g_block) # ...simulate receiving the genesis block msg from reactor to force commit g_block_msg = gossiper.IncomingMessageQueue.pop() poet_public_key = g_block.poet_public_key journal.dispatcher.dispatch(g_block_msg) journal.initialization_complete() head = journal.most_recent_committed_block_id chain_len = len(journal.committed_block_ids()) # Run shutdown: # ...persist new state journal.shutdown() # ...release gossip obj's UDP port gossiper.Listener.loseConnection() gossiper.Listener.connectionLost(reason=None) # Log genesis data, then write it out to ease dissemination genesis_data = { 'GenesisId': head, 'ChainLength': chain_len, 'PoetPublicKey': poet_public_key, } gblock_fname = genesis_info_file_name(cfg['DataDirectory']) LOGGER.info('genesis data: %s', genesis_data) LOGGER.info('writing genesis data to %s', gblock_fname) with open(gblock_fname, 'w') as f: f.write(json.dumps(genesis_data, indent=4))
def extend_genesis_util(self, overrides): print() vnm = None try: self._node_ctrl = None print('creating', str(self.__class__.__name__)) # set up our nodes (suite-internal interface) self._node_ctrl = WrappedNodeController(SubprocessNodeController()) cfg = overrides temp_dir = self._node_ctrl.get_data_dir() file_name = os.path.join(temp_dir, "config.js") with open(file_name, 'w') as config: config.write(json.dumps(cfg)) data_dir = os.path.join(temp_dir, "data") gblock_file = genesis_info_file_name(data_dir) self._nodes = [ NodeArguments('v%s' % i, 8800 + i, 9000 + i, config_files=[file_name], ledger_type=overrides["LedgerType"]) for i in range(2)] # set up our urls (external interface) self.urls = [ 'http://localhost:%s' % x.http_port for x in self._nodes] # Make genesis block print('creating genesis block...') self.assertFalse(os.path.exists(gblock_file)) self._nodes[0].genesis = True self._node_ctrl.create_genesis_block(self._nodes[0]) # Test genesis util self.assertTrue(os.path.exists(gblock_file)) genesis_dat = None with open(gblock_file, 'r') as f: genesis_dat = json.load(f) self.assertTrue('GenesisId' in genesis_dat.keys()) head = genesis_dat['GenesisId'] # Verify genesis tool efficacy on a minimal network # Launch network (node zero will trigger bootstrapping) print('launching network...') for x in self._nodes: self._node_ctrl.start(x) # ...verify validator is extending tgt_block to = TimeOut(64) blk_lists = None prog_str = 'testing root extension (expect root: %s)' % head with Progress(prog_str) as p: print() while not to.is_timed_out() and blk_lists is None: try: blk_lists = get_blocklists(['http://localhost:8800']) print('block_lists: %s' % blk_lists) if len(blk_lists) < 1 or len(blk_lists[0]) < 2: blk_lists = None except MessageException as e: pass time.sleep(2) p.step() self.assertIsNotNone(blk_lists) root = blk_lists[0][0] self.assertEqual(head, root) # ...verify general convergence to = TimeOut(32) with Progress('testing root convergence') as p: print() while (is_convergent(self.urls, tolerance=1, standard=1) is False and not to.is_timed_out()): time.sleep(2) p.step() # ...verify convergence on the genesis block blk_lists = get_blocklists(['http://localhost:8800']) root = blk_lists[0][0] self.assertEqual(head, root) print('network converged on root: %s' % root) finally: print('destroying', str(self.__class__.__name__)) if hasattr(self, '_node_ctrl') and self._node_ctrl is not None: # Shut down the network with Progress("terminating network") as p: for node_name in self._node_ctrl.get_node_names(): self._node_ctrl.stop(node_name) to = TimeOut(16) while len(self._node_ctrl.get_node_names()) > 0: if to.is_timed_out(): break time.sleep(1) p.step() # force kill anything left over for node_name in self._node_ctrl.get_node_names(): try: print("%s still 'up'; sending kill..." % node_name) self._node_ctrl.kill(node_name) except Exception as e: print(e.message) self._node_ctrl.archive(self.__class__.__name__) self._node_ctrl.clean()
def do_poet0_genesis(args): # Get ledger config: # ...set the default value of config because argparse 'default' in # ...combination with action='append' does the wrong thing. if args.config is None: args.config = ['txnvalidator.js'] # ...convert any comma-delimited argument strings to list elements for arglist in [args.config]: if arglist is not None: for arg in arglist: if ',' in arg: loc = arglist.index(arg) arglist.pop(loc) for element in reversed(arg.split(',')): arglist.insert(loc, element) options_config = ArgparseOptionsConfig( [ ('conf_dir', 'ConfigDirectory'), ('data_dir', 'DataDirectory'), ('type', 'LedgerType'), ('log_config', 'LogConfigFile'), ('keyfile', 'KeyFile'), ('node', 'NodeName'), ('verbose', 'Verbose'), ('family', 'TransactionFamilies') ], args) cfg = get_validator_configuration(args.config, options_config) # Obtain Journal object: # ...set WaitTimer globals target_wait_time = cfg.get("TargetWaitTime") initial_wait_time = cfg.get("InitialWaitTime") certificate_sample_length = cfg.get('CertificateSampleLength') fixed_duration_blocks = cfg.get("FixedDurationBlocks") from journal.consensus.poet0.wait_timer import set_wait_timer_globals set_wait_timer_globals(target_wait_time, initial_wait_time, certificate_sample_length, fixed_duration_blocks, ) # ...build Gossip dependency (nd, _) = parse_networking_info(cfg) minimum_retries = cfg.get("MinimumRetries") retry_interval = cfg.get("RetryInterval") gossiper = Gossip(nd, minimum_retries, retry_interval) # ...build Journal min_txn_per_block = cfg.get("MinimumTransactionsPerBlock") max_txn_per_block = cfg.get("MaxTransactionsPerBlock") max_txn_age = cfg.get("MaxTxnAge") genesis_ledger = cfg.get("GenesisLedger") data_directory = cfg.get("DataDirectory") store_type = cfg.get("StoreType") stat_domains = {} from journal.consensus.poet0.poet_consensus import PoetConsensus consensus_obj = PoetConsensus(cfg) journal = Journal(gossiper.LocalNode, gossiper, gossiper.dispatcher, consensus_obj, stat_domains, minimum_transactions_per_block=min_txn_per_block, max_transactions_per_block=max_txn_per_block, max_txn_age=max_txn_age, genesis_ledger=genesis_ledger, data_directory=data_directory, store_type=store_type, ) # ...add 'built in' txn families default_transaction_families = [ endpoint_registry ] for txn_family in default_transaction_families: txn_family.register_transaction_types(journal) # ...add auxiliary transaction families for txn_family_module_name in cfg.get("TransactionFamilies", []): txn_family = importlib.import_module(txn_family_module_name) txn_family.register_transaction_types(journal) # Make genesis block: # ...make sure there is no current chain here, or fail # ...create block g_block g_block = journal.build_block(genesis=True) journal.claim_block(g_block) # ...simulate receiving the genesis block msg from reactor to force commit g_block_msg = gossiper.IncomingMessageQueue.pop() journal.dispatcher.dispatch(g_block_msg) journal.initialization_complete() head = journal.most_recent_committed_block_id chain_len = len(journal.committed_block_ids()) # Run shutdown: # ...persist new state journal.shutdown() # ...release gossip obj's UDP port gossiper.Listener.loseConnection() gossiper.Listener.connectionLost(reason=None) # Log genesis data, then write it out to ease dissemination genesis_data = { 'GenesisId': head, 'ChainLength': chain_len, } gblock_fname = genesis_info_file_name(cfg['DataDirectory']) LOGGER.info('genesis data: %s', genesis_data) LOGGER.info('writing genesis data to %s', gblock_fname) with open(gblock_fname, 'w') as f: f.write(json.dumps(genesis_data))
def extend_genesis_util(self, ledger_type, pre_overrides, post_overrides): print top = None try: # Get configs and resources for a ValidatorManager compliant nodes top = get_default_sim_controller(2, ledger_type=ledger_type) # Set up validator-0 cfg = top.get_configuration(0) cfg.update(pre_overrides) top.set_configuration(0, cfg) config_file = top.write_configuration(0) # Test genesis tool print 'testing genesis util...' gblock_file = genesis_info_file_name(cfg['DataDirectory']) self.assertFalse(os.path.exists(gblock_file)) cli_args = 'admin %s-genesis --config %s' % (ledger_type, config_file) sawtooth_cli_intercept(cli_args) # Get genesis block id self.assertTrue(os.path.exists(gblock_file)) genesis_dat = None with open(gblock_file, 'r') as f: genesis_dat = json.load(f) self.assertTrue('GenesisId' in genesis_dat.keys()) head = genesis_dat['GenesisId'] # Verify genesis tool efficacy on a minimal network print 'testing efficacy...' # ...apply validator-related overrides to validator-0 cfg = top.get_configuration(0) cfg.update(post_overrides) top.set_configuration(0, cfg) # ...launch entire network top.launch(probe_seconds=0, reg_seconds=0) # ...verify validator is extending tgt_block to = TimeOut(64) blk_lists = None prog_str = 'testing root extension (expect root: %s)' % head with Progress(prog_str) as p: print while not to.is_timed_out() and blk_lists is None: try: blk_lists = get_blocklists(['http://localhost:8800']) print 'block_lists: %s' % blk_lists if len(blk_lists) < 1 or len(blk_lists[0]) < 2: blk_lists = None except MessageException as e: pass time.sleep(2) p.step() self.assertIsNotNone(blk_lists) root = blk_lists[0][0] self.assertEqual(head, root) # ...verify general convergence to = TimeOut(32) with Progress('testing root convergence') as p: print while (is_convergent(top.urls(), tolerance=1, standard=1) is False and not to.is_timed_out()): time.sleep(2) p.step() # ...verify convergence on the genesis block blk_lists = get_blocklists(['http://localhost:8800']) root = blk_lists[0][0] self.assertEqual(head, root) print 'network converged on root: %s' % root finally: if top is not None: archive_name = 'Test%sGenesisResults' % ledger_type.upper() top.shutdown(archive_name=archive_name)
def extend_genesis_util(self, overrides): print() vnm = None try: self._node_ctrl = None print('creating', str(self.__class__.__name__)) # set up our nodes (suite-internal interface) self._node_ctrl = WrappedNodeController( SubprocessLegacyNodeController()) cfg = overrides temp_dir = self._node_ctrl.get_data_dir() file_name = os.path.join(temp_dir, "config.js") with open(file_name, 'w') as config: config.write(json.dumps(cfg)) data_dir = os.path.join(temp_dir, "data") gblock_file = genesis_info_file_name(data_dir) self._nodes = [ NodeArguments('v%s' % i, 8800 + i, 9000 + i, config_files=[file_name], ledger_type=overrides["LedgerType"]) for i in range(2)] # set up our urls (external interface) self.urls = [ 'http://localhost:%s' % x.http_port for x in self._nodes] # Make genesis block print('creating genesis block...') self.assertFalse(os.path.exists(gblock_file)) self._nodes[0].genesis = True self._node_ctrl.create_genesis_block(self._nodes[0]) # Test genesis util self.assertTrue(os.path.exists(gblock_file)) genesis_dat = None with open(gblock_file, 'r') as f: genesis_dat = json.load(f) self.assertTrue('GenesisId' in genesis_dat.keys()) head = genesis_dat['GenesisId'] # Verify genesis tool efficacy on a minimal network # Launch network (node zero will trigger bootstrapping) print('launching network...') for x in self._nodes: self._node_ctrl.start(x) # ...verify validator is extending tgt_block to = TimeOut(64) blk_lists = None prog_str = 'testing root extension (expect root: %s)' % head with Progress(prog_str) as p: print() while not to.is_timed_out() and blk_lists is None: try: blk_lists = get_blocklists(['http://localhost:8800']) print('block_lists: %s' % blk_lists) if len(blk_lists) < 1 or len(blk_lists[0]) < 2: blk_lists = None except MessageException as e: pass time.sleep(2) p.step() self.assertIsNotNone(blk_lists) root = blk_lists[0][0] self.assertEqual(head, root) # ...verify general convergence to = TimeOut(32) with Progress('testing root convergence') as p: print() while (is_convergent(self.urls, tolerance=1, standard=1) is False and not to.is_timed_out()): time.sleep(2) p.step() # ...verify convergence on the genesis block blk_lists = get_blocklists(['http://localhost:8800']) root = blk_lists[0][0] self.assertEqual(head, root) print('network converged on root: %s' % root) finally: print('destroying', str(self.__class__.__name__)) if hasattr(self, '_node_ctrl') and self._node_ctrl is not None: # Shut down the network with Progress("terminating network") as p: for node_name in self._node_ctrl.get_node_names(): self._node_ctrl.stop(node_name) to = TimeOut(16) while len(self._node_ctrl.get_node_names()) > 0: if to.is_timed_out(): break time.sleep(1) p.step() # force kill anything left over for node_name in self._node_ctrl.get_node_names(): try: print("%s still 'up'; sending kill..." % node_name) self._node_ctrl.kill(node_name) except Exception as e: print(e.message) self._node_ctrl.archive(self.__class__.__name__) self._node_ctrl.clean()