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)
Example #4
0
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))
Example #5
0
 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)
Example #6
0
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))
Example #9
0
    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()