def do_store(args): subcommands = ['list', 'show'] if args.subcommand not in subcommands: print('Unknown sub-command, expecting one of {0}'.format( subcommands)) return if args.url is not None: url = args.url else: url = 'http://localhost:8800' web_client = SawtoothClient(url) try: if args.subcommand == 'list': transaction_type_name = web_client.get_store_list() print(pretty_print_dict(transaction_type_name)) return elif args.subcommand == 'show': store_info = \ web_client.get_store_by_name( txn_type_or_name=args.transactionTypeName, key=args.key, block_id=args.blockID, delta=args.incremental) print(pretty_print_dict(store_info)) return except MessageException as e: raise CliException(e)
def do_store(args): subcommands = ['list', 'show'] if args.subcommand not in subcommands: print('Unknown sub-command, expecting one of {0}'.format(subcommands)) return if args.url is not None: url = args.url else: url = 'http://localhost:8800' web_client = SawtoothClient(url) try: if args.subcommand == 'list': transaction_type_name = web_client.get_store_list() print(pretty_print_dict(transaction_type_name)) return elif args.subcommand == 'show': store_info = \ web_client.get_store_by_name( txn_type_or_name=args.transactionTypeName, key=args.key, block_id=args.blockID, delta=args.incremental) print(pretty_print_dict(store_info)) return except MessageException as e: raise CliException(e)
class ClientController(cmd.Cmd): _TxnVerbMap = {'=': 'set', '+=': 'inc', '-=': 'dec'} pformat = 'client> ' def __init__(self, baseurl, keystring=None): cmd.Cmd.__init__(self) self.prompt = 'client> ' self._current_state = {} self._client = SawtoothClient(baseurl) signingkey = generate_signing_key( wifstr=keystring) if keystring else generate_signing_key() identifier = generate_identifier(signingkey) self._local_node = Node(identifier=identifier, signingkey=signingkey, name="txnclient") def postcmd(self, flag, line): return flag def sign_and_post(self, msg): msg.SenderID = self._local_node.Identifier msg.sign_from_node(self._local_node) try: result = self._client.forward_message(msg) if result: pretty_print_dict(result) except MessageException as me: print me # ================================================================= # COMMANDS # ================================================================= def do_set(self, args): """ set -- Command to set properties of the interpreter set url --url <url> set nodeid --name <name> --keyfile <file> """ pargs = args.split() if len(pargs) == 0: print 'missing subcommand url|nodeid' return try: if pargs[0] == 'url': parser = argparse.ArgumentParser() parser.add_argument('--url', help='url used to connect to a validator', required=True) options = parser.parse_args(pargs) self.BaseURL = options.url print "server URL set to {0}".format(self.BaseURL) return elif pargs[0] == 'nodeid': pargs = args.split() parser = argparse.ArgumentParser() parser.add_argument('--name', help='name to use for the client', default='txnclient') parser.add_argument('--keyfile', help='name of the file that contains ' 'the wif format private key') options = parser.parse_args(pargs[1:]) addr = (socket.gethostbyname("localhost"), 0) name = options.name if options.keyfile: signingkey = generate_signing_key( wifstr=read_key_file(options.keyfile)) else: signingkey = generate_signing_key() identifier = generate_identifier(signingkey) self._local_node = Node(address=addr, identifier=identifier, signingkey=signingkey, name=name) print "local id set to {0}".format(self._local_node) return else: print "unknown subcommand; {0}".format(pargs[0]) return except Exception as e: print 'an error occured processing {0}: {1}'.format(args, str(e)) return def do_state(self, args): """ state -- Command to manipulate the current ledger state state fetch --store <store> state keys state value --path <path> """ pargs = args.split() if len(pargs) == 0: print 'missing subcommand: fetch|keys|value' return try: if pargs[0] == 'fetch': parser = argparse.ArgumentParser() parser.add_argument('--store', choices=TransactionTypes.keys(), default='endpoint') options = parser.parse_args(pargs[1:]) self._current_state = \ self._client.get_store_by_name( txn_type_or_name=TransactionTypes.get(options.store), key='*') elif pargs[0] == 'keys': try: print self._current_state.keys() except: print '[]' elif pargs[0] == 'value': parser = argparse.ArgumentParser() parser.add_argument('--path', required=True) options = parser.parse_args(pargs[1:]) pathargs = options.path.split('.') value = self._current_state while pathargs: value = value.get(pathargs.pop(0)) print value except Exception as e: print 'an error occured processing {0}: {1}'.format(args, str(e)) return def do_txn(self, args): """ txn -- Command to create IntegerKey transactions txn <expr> [ && <expr> ]* """ txn = integer_key.IntegerKeyTransaction() # pylint: disable=line-too-long pattern = re.compile( r"^\s*(?P<name>[a-zA-Z0-9]+)\s*(?P<verb>[+-]?=)\s*(?P<value>[0-9]+)\s*$" ) # noqa expressions = args.split('&&') for expression in expressions: match = pattern.match(expression) if not match: print 'unable to parse the transaction; {0}'.format(expression) return update = integer_key.Update() update.Verb = self._TxnVerbMap[match.group('verb')] update.Name = match.group('name') update.Value = long(match.group('value')) txn.Updates.append(update) txn.sign_from_node(self._local_node) msg = integer_key.IntegerKeyTransactionMessage() msg.Transaction = txn self.sign_and_post(msg) def do_nodestats(self, args): """ nodestats -- Command to send nodestats messages to validator pool nodestats reset --metrics [<metric>]+ nodestats dump --metrics [<metric>]+ --domains [<domain>]+ """ pargs = args.split() if len(pargs) == 0: print 'missing subcommand: reset|dump' return try: if pargs[0] == 'reset': parser = argparse.ArgumentParser() parser.add_argument('--metrics', default=[], nargs='+') options = parser.parse_args(pargs[1:]) self.sign_and_post( gossip_debug.ResetStatsMessage( {'MetricList': options.metrics})) return elif pargs[0] == 'dump': parser = argparse.ArgumentParser() parser.add_argument('--metrics', default=[], nargs='+') parser.add_argument('--domains', default=[], nargs='+') options = parser.parse_args(pargs[1:]) self.sign_and_post( gossip_debug.DumpNodeStatsMessage({ 'MetricList': options.metrics, 'DomainList': options.domains })) return except Exception as e: print 'an error occured processing {0}: {1}'.format(args, str(e)) return print 'unknown nodestats command {0}'.format(args) def do_peerstats(self, args): """ peerstats -- Command to send peerstats messages to validator pool peerstats reset --metrics [<metric>]+ peerstats dump --metrics [<metric>]+ --peers [<nodeid>]+ """ pargs = args.split() if len(pargs) == 0: print 'missing subcommand: reset|dump' return try: if pargs[0] == 'reset': parser = argparse.ArgumentParser() parser.add_argument('--metrics', default=[], nargs='+') options = parser.parse_args(pargs[1:]) self.sign_and_post( gossip_debug.ResetPeerStatsMessage( {'MetricList': options.metrics})) return elif pargs[0] == 'dump': parser = argparse.ArgumentParser() parser.add_argument('--metrics', default=[], nargs='+') parser.add_argument('--peers', default=[], nargs='+') options = parser.parse_args(pargs[1:]) self.sign_and_post( gossip_debug.DumpPeerStatsMessage({ 'MetricList': options.metrics, 'PeerIDList': options.peers })) return except Exception as e: print 'an error occured processing {0}: {1}'.format(args, str(e)) return print 'unknown peerstats command {0}'.format(args) def do_ping(self, args): """ ping -- Command to send a ping message to validator pool """ self.sign_and_post(gossip_debug.PingMessage({})) def do_sping(self, args): """ sping -- Command to send a special ping message to validator pool """ parser = argparse.ArgumentParser() parser.add_argument('--address', default=self._local_node.Identifier) parser.add_argument('--count', default=2, type=int) options = parser.parse_args(args.split()) msg = SpecialPingMessage() msg.Address = options.address msg.Count = options.count self.sign_and_post(msg) def do_dumpquorum(self, args): """ dumpquorum -- Command to request quorum consensus node to dump quorum list """ self.sign_and_post(quorum_debug.DumpQuorumMessage({})) def do_dumpcnxs(self, args): """ dumpcnxs -- Command to send to the validator pool a request to dump current connection information """ self.sign_and_post(gossip_debug.DumpConnectionsMessage({})) def do_dumpblks(self, args): """ dumpblks -- Command to send dump blocks request to the validator pool dumpblks --blocks <count> """ parser = argparse.ArgumentParser() parser.add_argument('--blocks', default=0, type=int) options = parser.parse_args(args.split()) self.sign_and_post( gossip_debug.DumpJournalBlocksMessage({'Count': options.blocks})) def do_val(self, args): """ val -- Command to send a dump value request to the validator pool val <name> [--type <transaction type>] """ pargs = args.split() parser = argparse.ArgumentParser() parser.add_argument('--type', help='Transaction family', default='/IntegerKeyTransaction') options = parser.parse_args(pargs[1:]) tinfo = {'Name': pargs[0], 'TransactionType': options.type} self.sign_and_post(journal_debug.DumpJournalValueMessage(tinfo)) def do_shutdown(self, args): """ shutdown -- Command to send a shutdown message to the validator pool """ self.sign_and_post(shutdown_message.ShutdownMessage({})) return True def do_exit(self, args): """exit Shutdown the simulator and exit the command loop """ return True def do_eof(self, args): return True
class ClientController(cmd.Cmd): _TxnVerbMap = {'=': 'set', '+=': 'inc', '-=': 'dec'} pformat = 'client> ' def __init__(self, baseurl, keystring=None): cmd.Cmd.__init__(self) self.prompt = 'client> ' self._current_state = {} self._client = SawtoothClient(baseurl) signingkey = generate_signing_key( wifstr=keystring) if keystring else generate_signing_key() identifier = generate_identifier(signingkey) self._local_node = Node(identifier=identifier, signingkey=signingkey, name="txnclient") def postcmd(self, flag, line): return flag def sign_and_post(self, msg): msg.SenderID = self._local_node.Identifier msg.sign_from_node(self._local_node) try: result = self._client.forward_message(msg) if result: pretty_print_dict(result) except MessageException as me: print me # ================================================================= # COMMANDS # ================================================================= def do_set(self, args): """ set -- Command to set properties of the interpreter set url --url <url> set nodeid --name <name> --keyfile <file> """ pargs = args.split() if len(pargs) == 0: print 'missing subcommand url|nodeid' return try: if pargs[0] == 'url': parser = argparse.ArgumentParser() parser.add_argument('--url', help='url used to connect to a validator', required=True) options = parser.parse_args(pargs) self.BaseURL = options.url print "server URL set to {0}".format(self.BaseURL) return elif pargs[0] == 'nodeid': pargs = args.split() parser = argparse.ArgumentParser() parser.add_argument('--name', help='name to use for the client', default='txnclient') parser.add_argument('--keyfile', help='name of the file that contains ' 'the wif format private key') options = parser.parse_args(pargs[1:]) addr = (socket.gethostbyname("localhost"), 0) name = options.name if options.keyfile: signingkey = generate_signing_key( wifstr=read_key_file(options.keyfile)) else: signingkey = generate_signing_key() identifier = generate_identifier(signingkey) self._local_node = Node(address=addr, identifier=identifier, signingkey=signingkey, name=name) print "local id set to {0}".format(self._local_node) return else: print "unknown subcommand; {0}".format(pargs[0]) return except Exception as e: print 'an error occured processing {0}: {1}'.format(args, str(e)) return def do_state(self, args): """ state -- Command to manipulate the current ledger state state fetch --store <store> state keys state value --path <path> """ pargs = args.split() if len(pargs) == 0: print 'missing subcommand: fetch|keys|value' return try: if pargs[0] == 'fetch': parser = argparse.ArgumentParser() parser.add_argument('--store', choices=TransactionTypes.keys(), default='endpoint') options = parser.parse_args(pargs[1:]) self._current_state = \ self._client.get_store_by_name( txn_type_or_name=TransactionTypes.get(options.store), key='*') elif pargs[0] == 'keys': try: print self._current_state.keys() except: print '[]' elif pargs[0] == 'value': parser = argparse.ArgumentParser() parser.add_argument('--path', required=True) options = parser.parse_args(pargs[1:]) pathargs = options.path.split('.') value = self._current_state while pathargs: value = value.get(pathargs.pop(0)) print value except Exception as e: print 'an error occured processing {0}: {1}'.format(args, str(e)) return def do_txn(self, args): """ txn -- Command to create IntegerKey transactions txn <expr> [ && <expr> ]* """ txn = integer_key.IntegerKeyTransaction() # pylint: disable=line-too-long pattern = re.compile(r"^\s*(?P<name>[a-zA-Z0-9]+)\s*(?P<verb>[+-]?=)\s*(?P<value>[0-9]+)\s*$") # noqa expressions = args.split('&&') for expression in expressions: match = pattern.match(expression) if not match: print 'unable to parse the transaction; {0}'.format(expression) return update = integer_key.Update() update.Verb = self._TxnVerbMap[match.group('verb')] update.Name = match.group('name') update.Value = long(match.group('value')) txn.Updates.append(update) txn.sign_from_node(self._local_node) msg = integer_key.IntegerKeyTransactionMessage() msg.Transaction = txn self.sign_and_post(msg) def do_nodestats(self, args): """ nodestats -- Command to send nodestats messages to validator pool nodestats reset --metrics [<metric>]+ nodestats dump --metrics [<metric>]+ --domains [<domain>]+ """ pargs = args.split() if len(pargs) == 0: print 'missing subcommand: reset|dump' return try: if pargs[0] == 'reset': parser = argparse.ArgumentParser() parser.add_argument('--metrics', default=[], nargs='+') options = parser.parse_args(pargs[1:]) self.sign_and_post(gossip_debug.ResetStatsMessage( {'MetricList': options.metrics})) return elif pargs[0] == 'dump': parser = argparse.ArgumentParser() parser.add_argument('--metrics', default=[], nargs='+') parser.add_argument('--domains', default=[], nargs='+') options = parser.parse_args(pargs[1:]) self.sign_and_post(gossip_debug.DumpNodeStatsMessage( {'MetricList': options.metrics, 'DomainList': options.domains})) return except Exception as e: print 'an error occured processing {0}: {1}'.format(args, str(e)) return print 'unknown nodestats command {0}'.format(args) def do_peerstats(self, args): """ peerstats -- Command to send peerstats messages to validator pool peerstats reset --metrics [<metric>]+ peerstats dump --metrics [<metric>]+ --peers [<nodeid>]+ """ pargs = args.split() if len(pargs) == 0: print 'missing subcommand: reset|dump' return try: if pargs[0] == 'reset': parser = argparse.ArgumentParser() parser.add_argument('--metrics', default=[], nargs='+') options = parser.parse_args(pargs[1:]) self.sign_and_post(gossip_debug.ResetPeerStatsMessage( {'MetricList': options.metrics})) return elif pargs[0] == 'dump': parser = argparse.ArgumentParser() parser.add_argument('--metrics', default=[], nargs='+') parser.add_argument('--peers', default=[], nargs='+') options = parser.parse_args(pargs[1:]) self.sign_and_post(gossip_debug.DumpPeerStatsMessage( {'MetricList': options.metrics, 'PeerIDList': options.peers})) return except Exception as e: print 'an error occured processing {0}: {1}'.format(args, str(e)) return print 'unknown peerstats command {0}'.format(args) def do_ping(self, args): """ ping -- Command to send a ping message to validator pool """ self.sign_and_post(gossip_debug.PingMessage({})) def do_sping(self, args): """ sping -- Command to send a special ping message to validator pool """ parser = argparse.ArgumentParser() parser.add_argument( '--address', default=self._local_node.Identifier) parser.add_argument('--count', default=2, type=int) options = parser.parse_args(args.split()) msg = SpecialPingMessage() msg.Address = options.address msg.Count = options.count self.sign_and_post(msg) def do_dumpquorum(self, args): """ dumpquorum -- Command to request quorum consensus node to dump quorum list """ self.sign_and_post(quorum_debug.DumpQuorumMessage({})) def do_dumpcnxs(self, args): """ dumpcnxs -- Command to send to the validator pool a request to dump current connection information """ self.sign_and_post(gossip_debug.DumpConnectionsMessage({})) def do_dumpblks(self, args): """ dumpblks -- Command to send dump blocks request to the validator pool dumpblks --blocks <count> """ parser = argparse.ArgumentParser() parser.add_argument('--blocks', default=0, type=int) options = parser.parse_args(args.split()) self.sign_and_post(gossip_debug.DumpJournalBlocksMessage( {'Count': options.blocks})) def do_val(self, args): """ val -- Command to send a dump value request to the validator pool val <name> [--type <transaction type>] """ pargs = args.split() parser = argparse.ArgumentParser() parser.add_argument('--type', help='Transaction family', default='/IntegerKeyTransaction') options = parser.parse_args(pargs[1:]) tinfo = {'Name': pargs[0], 'TransactionType': options.type} self.sign_and_post(journal_debug.DumpJournalValueMessage(tinfo)) def do_shutdown(self, args): """ shutdown -- Command to send a shutdown message to the validator pool """ self.sign_and_post(shutdown_message.ShutdownMessage({})) return True def do_exit(self, args): """exit Shutdown the simulator and exit the command loop """ return True def do_eof(self, args): return True