def _do_config_list(args): """Lists the current on-chain configuration values. """ rest_client = RestClient(args.url) state = rest_client.list_state(subtree=SETTINGS_NAMESPACE) prefix = args.filter head = state['head'] state_values = state['data'] printable_settings = [] proposals_address = _key_to_address('sawtooth.settings.vote.proposals') for state_value in state_values: if state_value['address'] == proposals_address: # This is completely internal setting and we won't list it here continue decoded = b64decode(state_value['data']) setting = Setting() setting.ParseFromString(decoded) for entry in setting.entries: if entry.key.startswith(prefix): printable_settings.append(entry) printable_settings.sort(key=lambda s: s.key) if args.format == 'default': tty_width = tty.width() for setting in printable_settings: # Set value width to the available terminal space, or the min width width = tty_width - len(setting.key) - 3 width = width if width > _MIN_PRINT_WIDTH else _MIN_PRINT_WIDTH value = (setting.value[:width] + '...' if len(setting.value) > width else setting.value) print('{}: {}'.format(setting.key, value)) elif args.format == 'csv': try: writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL) writer.writerow(['KEY', 'VALUE']) for setting in printable_settings: writer.writerow([setting.key, setting.value]) except csv.Error: raise CliException('Error writing CSV') elif args.format == 'json' or args.format == 'yaml': settings_snapshot = { 'head': head, 'settings': {setting.key: setting.value for setting in printable_settings} } if args.format == 'json': print(json.dumps(settings_snapshot, indent=2, sort_keys=True)) else: print(yaml.dump(settings_snapshot, default_flow_style=False)[0:-1]) else: raise AssertionError('Unknown format {}'.format(args.format))
def _get_proposals(rest_client): state_leaf = rest_client.get_leaf( _key_to_address('sawtooth.config.vote.proposals')) config_candidates = ConfigCandidates() if state_leaf is not None: setting_bytes = b64decode(state_leaf['data']) setting = Setting() setting.ParseFromString(setting_bytes) candidates_bytes = None for entry in setting.entries: if entry.key == 'sawtooth.config.vote.proposals': candidates_bytes = entry.value if candidates_bytes is not None: decoded = b64decode(candidates_bytes) config_candidates.ParseFromString(decoded) return config_candidates
def _do_config_proposal_list(args): """Executes the 'proposal list' subcommand. Given a url, optional filters on prefix and public key, this command lists the current pending proposals for settings changes. """ rest_client = RestClient(args.url) state_leaf = rest_client.get_leaf( _key_to_address('sawtooth.config.vote.proposals')) def _accept(candidate, public_key, prefix): # Check to see if the first public key matches the given public key # (if it is not None). This public key belongs to the user that # created it. has_pub_key = (not public_key or candidate.votes[0].public_key == public_key) has_prefix = candidate.proposal.setting.startswith(prefix) return has_prefix and has_pub_key if state_leaf is not None: setting_bytes = b64decode(state_leaf['data']) setting = Setting() setting.ParseFromString(setting_bytes) candidates_bytes = None for entry in setting.entries: if entry.key == 'sawtooth.config.vote.proposals': candidates_bytes = entry.value decoded = b64decode(candidates_bytes) candidates_payload = ConfigCandidates() candidates_payload.ParseFromString(decoded) candidates = [ c for c in candidates_payload.candidates if _accept(c, args.public_key, args.filter) ] else: candidates = [] if args.format == 'default': for candidate in candidates: print('{}: {} => {}'.format(candidate.proposal_id, candidate.proposal.setting, candidate.proposal.value)) elif args.format == 'csv': writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL) writer.writerow(['PROPOSAL_ID', 'KEY', 'VALUE']) for candidate in candidates: writer.writerow([ candidate.proposal_id, candidate.proposal.setting, candidate.proposal.value ]) elif args.format == 'json' or args.format == 'yaml': candidates_snapshot = \ {c.proposal_id: {c.proposal.setting: c.proposal.value} for c in candidates} if args.format == 'json': print(json.dumps(candidates_snapshot, indent=2, sort_keys=True)) else: print( yaml.dump(candidates_snapshot, default_flow_style=False)[0:-1]) else: raise AssertionError('Unknown format {}'.format(args.format))