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. """ setup_bitcoin = args.setup_bitcoin if args.use_btc_wallet else False if setup_bitcoin: proxy = setup_bitcoin() unfunded_tx = CTransaction( [], [CTxOut(0, CScript([OP_RETURN, timestamp.msg]))]) r = proxy.fundrawtransaction(unfunded_tx) # FIXME: handle errors funded_tx = r['tx'] r = proxy.signrawtransaction(funded_tx) assert r['complete'] signed_tx = r['tx'] txid = proxy.sendrawtransaction(signed_tx) logging.info('Sent timestamp tx') blockhash = None while blockhash is None: logging.info('Waiting for timestamp tx %s to confirm...' % b2lx(txid)) time.sleep(1) r = proxy.gettransaction(txid) if 'blockhash' in r: # FIXME: this will break when python-bitcoinlib adds RPC # support for gettransaction, due to formatting differences blockhash = lx(r['blockhash']) logging.info('Confirmed by block %s' % b2lx(blockhash)) block = proxy.getblock(blockhash) r = proxy.getblockheader(blockhash, True) blockheight = r['height'] # We have a block hash! We can now generate the attestation from the block. block_timestamp = make_timestamp_from_block(timestamp.msg, block, blockheight) assert block_timestamp is not None timestamp.merge(block_timestamp) 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)) 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) start = time.time() merged = 0 for i in range(n): try: remaining = max(0, args.timeout - (time.time() - start)) result = q.get(block=True, timeout=remaining) try: if isinstance(result, Timestamp): timestamp.merge(result) merged += 1 else: logging.debug(str(result)) except Exception as error: logging.debug(str(error)) except Empty: # Timeout continue 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)) sys.exit(1) logging.debug("%.2f seconds elapsed" % (time.time() - start))
def native(self): ins = [input.native() for input in self.inputs] outs = [output.native() for output in self.outputs] return CTransaction(ins, outs)
def __init__(self, protover=PROTO_VERSION): super(msg_tx, self).__init__(protover) self.tx = CTransaction()