diff --git a/ots-git-gpg-wrapper b/ots-git-gpg-wrapper index 31df0eb..07f1f46 100755 --- a/ots-git-gpg-wrapper +++ b/ots-git-gpg-wrapper @@ -39,9 +39,13 @@ parser = otsclient.args.make_common_options_arg_parser() parser.add_argument("-g", "--gpg-program", action="store", default="/usr/bin/gpg", help="Path to the GnuPG binary (default %(default)s)") -parser.add_argument('-c','--calendar', metavar='URL', dest='calendar_urls', action='append', type=str, - default=["https://a.pool.opentimestamps.org", "https://b.pool.opentimestamps.org", "https://a.pool.eternitywall.com"], - help='Create timestamp with the aid of a remote calendar. May be specified multiple times. Default: %(default)r') +parser.add_argument('-a', '--aggregator', metavar='URL', dest='aggregators', action='append', type=str, + default=[], + help='Add an aggregator') +parser.add_argument('--no-default-aggregators', action='store_true', default=False, + help='Do not use the default list of aggregators; ' + 'use only aggregators manually added with --aggregator') + parser.add_argument('-b','--btc-wallet', dest='use_btc_wallet', action='store_true', help='Create timestamp locally with the local Bitcoin wallet.') parser.add_argument('--rehash-trees', action='store_true', @@ -50,14 +54,12 @@ parser.add_argument("gpgargs", nargs=argparse.REMAINDER, help='Arguments passed to GnuPG binary') parser.add_argument("--timeout", type=int, default=5, - help="Timeout before giving up on a calendar. " + help="Timeout before giving up on an aggregator. " "Default: %(default)d") -parser.add_argument("-m", type=int, default="2", - help="Commitments are sent to remote calendars," - "in the event of timeout the timestamp is considered " - "done if at least M calendars replied. " - "Default: %(default)s") +parser.add_argument("-m", type=int, metavar='M', default=2, + help="Require at least M of the aggregators to respond for the " + "timestamp to be considered complete. Default: %(default)d") args = otsclient.args.handle_common_options(parser.parse_args(), parser) @@ -134,7 +136,7 @@ if gpgargs.bsau: final_timestamp = signed_commit_timestamp.ops.add(OpAppend(tree_stamper.timestamp.msg)).ops.add(OpSHA256()) minor_version = 1 - otsclient.cmds.create_timestamp(final_timestamp, args.calendar_urls, args) + otsclient.cmds.create_timestamp(final_timestamp, args) if args.wait: # Interpreted as override by the upgrade command diff --git a/otsclient/args.py b/otsclient/args.py index 81fbf8d..15f9320 100644 --- a/otsclient/args.py +++ b/otsclient/args.py @@ -160,9 +160,13 @@ def parse_ots_args(raw_args): parser_stamp = subparsers.add_parser('stamp', aliases=['s'], help='Timestamp files') - parser_stamp.add_argument('-c', '--calendar', metavar='URL', dest='calendar_urls', action='append', type=str, + parser_stamp.add_argument('-a', '--aggregator', metavar='URL', dest='aggregators', action='append', type=str, default=[], - help='Create timestamp with the aid of a remote calendar. May be specified multiple times.') + help='Add an aggregator') + + parser_stamp.add_argument('--no-default-aggregators', action='store_true', default=False, + help='Do not use the default list of aggregators; ' + 'use only aggregators manually added with --aggregator') parser_stamp.add_argument('-b', '--btc-wallet', dest='use_btc_wallet', action='store_true', help='Create timestamp locally with the local Bitcoin wallet.') @@ -172,14 +176,12 @@ def parse_ots_args(raw_args): help='Filename') parser_stamp.add_argument("--timeout", type=int, default=5, - help="Timeout before giving up on a calendar. " + help="Timeout (in seconds) before giving up on an aggregator. " "Default: %(default)d") - parser_stamp.add_argument("-m", type=int, default="2", - help="Commitments are sent to remote calendars," - "in the event of timeout the timestamp is considered " - "done if at least M calendars replied. " - "Default: %(default)s") + parser_stamp.add_argument("-m", type=int, metavar='M', default=2, + help="Require at least M of the aggregators to respond for the " + "timestamp to be considered complete. Default: %(default)d") # ----- upgrade ----- parser_upgrade = subparsers.add_parser('upgrade', aliases=['u'], diff --git a/otsclient/cmds.py b/otsclient/cmds.py index 1fb7dfe..cf54096 100644 --- a/otsclient/cmds.py +++ b/otsclient/cmds.py @@ -45,13 +45,8 @@ def remote_calendar(calendar_uri): user_agent="OpenTimestamps-Client/%s" % otsclient.__version__) -def create_timestamp(timestamp, calendar_urls, args): - """Create a timestamp - - calendar_urls - List of calendar's to use - setup_bitcoin - False if Bitcoin timestamp not desired; set to - args.setup_bitcoin() otherwise. - """ +def create_timestamp(timestamp, args): + """Create a timestamp""" setup_bitcoin = args.setup_bitcoin if args.use_btc_wallet else False if setup_bitcoin: @@ -92,17 +87,23 @@ def create_timestamp(timestamp, calendar_urls, args): assert block_timestamp is not None timestamp.merge(block_timestamp) + aggregator_urls = [] if args.no_default_aggregators else list(opentimestamps.calendar.DEFAULT_AGGREGATORS) + aggregator_urls.extend(args.aggregators) + m = args.m - n = len(calendar_urls) - if m > n or m <= 0: - logging.error("m (%d) cannot be greater than available calendar%s (%d) neither less or equal 0" % (m, "" if n == 1 else "s", n)) + n = len(aggregator_urls) + if m > n: + logging.error("m (%d) cannot be greater than number of available aggregators", m) + sys.exit(1) + elif m <= 0: + logging.error("m must greater than zero") sys.exit(1) logging.debug("Doing %d-of-%d request, timeout is %d second%s" % (m, n, args.timeout, "" if n == 1 else "s")) q = Queue() - for calendar_url in calendar_urls: - submit_async(calendar_url, timestamp.msg, q, args.timeout) + for aggregator_url in aggregator_urls: + submit_async(aggregator_url, timestamp.msg, q, args.timeout) start = time.time() merged = 0 @@ -123,23 +124,27 @@ def create_timestamp(timestamp, calendar_urls, args): # Timeout continue + # FIXME: we should change this to have a concept of trusted calendars, and + # actually check that the aggregators return pending attestations with + # enough redundancy + if merged < m: - logging.error("Failed to create timestamp: need at least %d attestation%s but received %s within timeout" % (m, "" if m == 1 else "s", merged)) + logging.error("Failed to create timestamp: need at least %d attestation%s but received only %s within timeout" % (m, "" if m == 1 else "s", merged)) sys.exit(1) logging.debug("%.2f seconds elapsed" % (time.time()-start)) -def submit_async(calendar_url, msg, q, timeout): +def submit_async(aggregator_url, msg, q, timeout): def submit_async_thread(remote, msg, q, timeout): try: - calendar_timestamp = remote.submit(msg, timeout=timeout) - q.put(calendar_timestamp) + aggregator_timestamp = remote.submit(msg, timeout=timeout) + q.put(aggregator_timestamp) except Exception as exc: q.put(exc) - logging.info('Submitting to remote calendar %s' % calendar_url) - remote = remote_calendar(calendar_url) + logging.info('Submitting to aggregator %s' % aggregator_url) + remote = remote_calendar(aggregator_url) t = threading.Thread(target=submit_async_thread, args=(remote, msg, q, timeout)) t.start() @@ -181,13 +186,7 @@ def stamp_command(args): merkle_tip = make_merkle_tree(merkle_roots) - if not args.calendar_urls: - # Neither calendar nor wallet specified; add defaults - args.calendar_urls.append('https://a.pool.opentimestamps.org') - args.calendar_urls.append('https://b.pool.opentimestamps.org') - args.calendar_urls.append('https://a.pool.eternitywall.com') - - create_timestamp(merkle_tip, args.calendar_urls, args) + create_timestamp(merkle_tip, args) if args.wait: upgrade_timestamp(merkle_tip, args) diff --git a/release-notes.md b/release-notes.md index 3b89e28..07e8a7c 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,13 +1,31 @@ # OpenTimestamps Client Release Notes -## v0.5.0 +## v0.5.0-PENDING -Breaking change: The remote calendar whitelist options have been reworked. The +### Breaking Change: Calendar Whitelists + +The remote calendar whitelist options have been reworked. The new behavior is that the `--whitelist` option adds additional remote calendars to the default whitelist. If you don't want to use the default whitelist, it can be disabled with the `--no-default-whitelist` option, replacing the prior `--no-remote-calendars` option, which no longer exists. +Previously the default whitelist was only loaded if `--whitelist` wasn't used +at all, making it the client inconvenient to use if you wanted to be able to +verify timestamps using both standard and non-standard calendars at the same +time. + + +### Breaking Change: Aggregators + +Previously commands that created timestamps incorrectly used the term +"calendar" when they should have used the term "aggregator" in both +documentation and command line options. This version fixes that oversight by +renaming the `--calendar` options of the `stamp` subcommand and +`ots-git-gpg-wrapper` to `--aggregator`. As with the new calendar whitelist +options, there's a default list of aggregators that can be disabled with the +`--no-default-aggregators` option. + ## v0.4.0