def _run_single(self, hosts, rate, bench_parameters, node_parameters, debug=False): Print.info('Booting testbed...') # Kill any potentially unfinished run and delete logs. self.kill(hosts=hosts, delete_logs=True) Print.info('Killed previous instances') sleep(10) # Run the clients (they will wait for the nodes to be ready). # Filter all faulty nodes from the client addresses (or they will wait # for the faulty nodes to be online). committee = Committee.load(PathMaker.committee_file()) addresses = [f'{x}:{self.settings.front_port}' for x in hosts] rate_share = ceil(rate / committee.size()) # Take faults into account. timeout = node_parameters.timeout_delay client_logs = [PathMaker.client_log_file(i) for i in range(len(hosts))] for host, addr, log_file in zip(hosts, addresses, client_logs): cmd = CommandMaker.run_client(addr, bench_parameters.tx_size, rate_share, timeout, nodes=addresses) self._background_run(host, cmd, log_file) Print.info('Clients boosted...') sleep(10) # Run the nodes. key_files = [PathMaker.key_file(i) for i in range(len(hosts))] dbs = [PathMaker.db_path(i) for i in range(len(hosts))] node_logs = [PathMaker.node_log_file(i) for i in range(len(hosts))] threshold_key_files = [ PathMaker.threshold_key_file(i) for i in range(len(hosts)) ] for host, key_file, threshold_key_file, db, log_file in zip( hosts, key_files, threshold_key_files, dbs, node_logs): cmd = CommandMaker.run_node(key_file, threshold_key_file, PathMaker.committee_file(), db, PathMaker.parameters_file(), debug=debug) self._background_run(host, cmd, log_file) # Wait for the nodes to synchronize Print.info('Waiting for the nodes to synchronize...') sleep(node_parameters.timeout_delay / 1000) # Wait for all transactions to be processed. duration = bench_parameters.duration for _ in progress_bar(range(100), prefix=f'Running benchmark ({duration} sec):'): sleep(ceil(duration / 100)) self.kill(hosts=hosts, delete_logs=False)
def _config(self, hosts, node_parameters): Print.info('Generating configuration files...') # Cleanup all local configuration files. cmd = CommandMaker.cleanup() subprocess.run([cmd], shell=True, stderr=subprocess.DEVNULL) # Recompile the latest code. cmd = CommandMaker.compile().split() subprocess.run(cmd, check=True, cwd=PathMaker.node_crate_path()) # Create alias for the client and nodes binary. cmd = CommandMaker.alias_binaries(PathMaker.binary_path()) subprocess.run([cmd], shell=True) # Generate configuration files. keys = [] key_files = [PathMaker.key_file(i) for i in range(len(hosts))] for filename in key_files: cmd = CommandMaker.generate_key(filename).split() subprocess.run(cmd, check=True) keys += [Key.from_file(filename)] # Generate threshold signature files. nodes = len(hosts) cmd = './node threshold_keys' for i in range(nodes): cmd += ' --filename ' + PathMaker.threshold_key_file(i) cmd = cmd.split() subprocess.run(cmd, capture_output=True, check=True) names = [x.name for x in keys] consensus_addr = [f'{x}:{self.settings.consensus_port}' for x in hosts] front_addr = [f'{x}:{self.settings.front_port}' for x in hosts] tss_keys = [] for i in range(nodes): tss_keys += [TSSKey.from_file(PathMaker.threshold_key_file(i))] ids = [x.id for x in tss_keys] mempool_addr = [f'{x}:{self.settings.mempool_port}' for x in hosts] committee = Committee(names, ids, consensus_addr, front_addr, mempool_addr) committee.print(PathMaker.committee_file()) node_parameters.print(PathMaker.parameters_file()) # Cleanup all nodes. cmd = f'{CommandMaker.cleanup()} || true' g = Group(*hosts, user='******', connect_kwargs=self.connect) g.run(cmd, hide=True) # Upload configuration files. progress = progress_bar(hosts, prefix='Uploading config files:') for i, host in enumerate(progress): c = Connection(host, user='******', connect_kwargs=self.connect) c.put(PathMaker.committee_file(), '.') c.put(PathMaker.key_file(i), '.') c.put(PathMaker.threshold_key_file(i), '.') c.put(PathMaker.parameters_file(), '.') return committee
def create_instances(self, instances): assert isinstance(instances, int) and instances > 0 # Create the security group in every region. for client in self.clients.values(): try: self._create_security_group(client) except ClientError as e: error = AWSError(e) if error.code != 'InvalidGroup.Duplicate': raise BenchError('Failed to create security group', error) try: # Create all instances. size = instances * len(self.clients) progress = progress_bar( self.clients.values(), prefix=f'Creating {size} instances' ) for client in progress: client.run_instances( ImageId=self._get_ami(client), InstanceType=self.settings.instance_type, KeyName=self.settings.key_name, MaxCount=instances, MinCount=instances, SecurityGroups=[self.SECURITY_GROUP_NAME], TagSpecifications=[{ 'ResourceType': 'instance', 'Tags': [{ 'Key': 'Name', 'Value': self.INSTANCE_NAME }] }], EbsOptimized=True, BlockDeviceMappings=[{ 'DeviceName': '/dev/sda1', 'Ebs': { 'VolumeType': 'gp2', 'VolumeSize': 200, 'DeleteOnTermination': True } }], ) # Wait for the instances to boot. Print.info('Waiting for all instances to boot...') self._wait(['pending']) Print.heading(f'Successfully created {size} new instances') except ClientError as e: raise BenchError('Failed to create AWS instances', AWSError(e))
def _run_single(self, hosts, rate, bench_parameters, node_parameters, debug=False): Print.info('Booting testbed...') # Kill any potentially unfinished run and delete logs. self.kill(hosts=hosts, delete_logs=True) # Run the clients (they will wait for the nodes to be ready). committee = Committee.load(PathMaker.committee_file()) addresses = committee.front_addresses() rate_share = ceil(rate / committee.size()) timeout = node_parameters.timeout_delay client_logs = [PathMaker.client_log_file(i) for i in range(len(hosts))] for host, addr, log_file in zip(hosts, addresses, client_logs): cmd = CommandMaker.run_client(addr, bench_parameters.tx_size, rate_share, timeout, nodes=addresses) self._background_run(host, cmd, log_file) # Run the nodes. key_files = [PathMaker.key_file(i) for i in range(len(hosts))] dbs = [PathMaker.db_path(i) for i in range(len(hosts))] node_logs = [PathMaker.node_log_file(i) for i in range(len(hosts))] for host, key_file, db, log_file in zip(hosts, key_files, dbs, node_logs): cmd = CommandMaker.run_node(key_file, PathMaker.committee_file(), db, PathMaker.parameters_file(), debug=debug) self._background_run(host, cmd, log_file) # Wait for the nodes to synchronize Print.info('Waiting for the nodes to synchronize...') sleep(2 * node_parameters.timeout_delay / 1000) # Wait for all transactions to be processed. duration = bench_parameters.duration for _ in progress_bar(range(20), prefix=f'Running benchmark ({duration} sec):'): sleep(ceil(duration / 20)) self.kill(hosts=hosts, delete_logs=False)
def _logs(self, hosts): # Delete local logs (if any). cmd = CommandMaker.clean_logs() subprocess.run([cmd], shell=True, stderr=subprocess.DEVNULL) # Download log files. progress = progress_bar(hosts, prefix='Downloading logs:') for i, host in enumerate(progress): c = Connection(host, user='******', connect_kwargs=self.connect) c.get(PathMaker.node_log_file(i), local=PathMaker.node_log_file(i)) c.get(PathMaker.client_log_file(i), local=PathMaker.client_log_file(i)) # Parse logs and return the parser. Print.info('Parsing logs and computing performance...') return LogParser.process(PathMaker.logs_path())