Ejemplo n.º 1
0
    def refund_tx(self, payer_sig, serial_tx, redeem_script):
        '''
            Sends a transaction refunding the funder of
            the P2SH address.
        '''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        txin = tx.vin[0]

        # Set script sig
        txin.scriptSig = CScript([payer_sig + '\x01', OP_FALSE, redeem_script])

        # Verify script
        redeem_script = CScript(redeem_script)
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])

        serial_tx = tx.serialize()
        if not self.test:
            # txid = self.self.proxy.sendrawtransaction(tx)
            txid = b2lx(Hash(serial_tx))
        else:
            txid = b2lx(Hash(serial_tx))

        self.logger.info("refund_tx: TXID is %s", txid)
        self.logger.info("refund_tx: RAW TX is %s", b2x(serial_tx))

        return serial_tx
Ejemplo n.º 2
0
    def process_header(self, header, block_origin):
        hash_ = header.GetHash()
        logging.info('process Block(hash={}) from {}'.format(core.b2lx(hash_), block_origin))

        fork_before = chainutil.get_private_public_fork(self.tips)
        logging.info('fork before {}'.format(fork_before))

        self.try_to_insert_header(header, block_origin)

        fork_after = chainutil.get_private_public_fork(self.tips)
        logging.info('fork after {}'.format(fork_after))

        if self.initializing:
            if hash_ == self.start_hash or header.hashPrevBlock == self.start_hash:
                self.initializing = False
                logging.info('Initializing over; now starting selfish mining')
            else:
                logging.info('chain is initializing - no action needs to be taken')
        else:
            if fork_before != fork_after:
                logging.debug('fork tip_private={}'.format(core.b2lx(fork_after.private_tip.hash())))
                logging.debug('fork tip_public={}'.format(core.b2lx(fork_after.public_tip.hash())))
                try:
                    action = self.strategy.find_action(fork_after.private_height, fork_after.public_height, block_origin)
                    logging.info('found action={}'.format(action))

                    self.executor.execute(action, fork_after.private_tip, fork_after.public_tip)
                except ActionException as exception:
                    logging.warn(exception.message)
            else:
                logging.debug('the two forks are the same - no action needs to be taken')
Ejemplo n.º 3
0
    def parse_vin(self, tx, txid, tx_data, vin, idx, batch=None):
        if tx.is_coinbase() and idx == 0:
            tx_data["vin"] = []
            tx_data["addresses_in"][None] = 0
            return
        if batch:
            # TODO: remove old utxo db
            preaddress, prevalue = self.poputxo(batch, b2lx(vin.prevout.hash), vin.prevout.n)
            self.spend_txout(b2lx(vin.prevout.hash), vin.prevout.n, batch)
        else:
            preaddress, prevalue = self.getutxo(b2lx(vin.prevout.hash), vin.prevout.n)
#        tx_data["vin"].append({"address": preaddress, "value": prevalue})
        tx_data["vin"].append({"txid": b2lx(vin.prevout.hash), "vout": vin.prevout.n, "value": prevalue})
        tx_data["input_value"] += prevalue

        # Add to the value of address vin
        if preaddress in tx_data["addresses_in"]:
            tx_data["addresses_in"][preaddress] += prevalue
        else:
            tx_data["addresses_in"][preaddress] = prevalue

        # Update address tracking only when non-mempool (batch is not none)
        if batch:
            self.log.debug("Updating address %s with value %s" % (preaddress, -prevalue))
            if preaddress in self.address_changes:
                self.address_changes[preaddress]['balance'] -= prevalue
                self.address_changes[preaddress]['sent'] += prevalue
            else:
                self.address_changes[preaddress] = {
                    'balance': -prevalue,
                    'sent': prevalue,
                    'received': 0,
                }
Ejemplo n.º 4
0
    def spend_escrow(self, payer_sig, redeemer_sig, serial_tx, redeem_script):
        '''
            Sends a transaction fulfilling the redeem script of escrow tx
        '''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        txin = tx.vin[0]

        # Set script sig
        txin.scriptSig = CScript([
            OP_FALSE, payer_sig + '\x01', redeemer_sig + '\x01', OP_TRUE,
            redeem_script
        ])

        # Verify script
        redeem_script = CScript(redeem_script)
        serial_tx = tx.serialize()
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])

        serial_tx = tx.serialize()
        if not self.test:
            # txid = self.proxy.sendrawtransaction(tx)
            txid = b2lx(Hash(serial_tx))
        else:
            txid = b2lx(Hash(serial_tx))

        self.logger.info("spend_escrow: TXID is %s", txid)
        self.logger.info("spend_escrow: RAW TX is %s", b2x(serial_tx))

        return serial_tx
Ejemplo n.º 5
0
 def handle_tx(self, message_obj):
     '''
     From BIP 37:
     Because a merkleblock message contains only a list of transaction hashes, 
     transactions matching the filter should also be sent in separate tx messages 
     after the merkleblock is sent. This avoids a slow roundtrip that would otherwise 
     be required.
     '''
     tx_hash = b2lx(message_obj.tx.GetHash())
     tx_id = b2lx(message_obj.tx.GetTxid())
     # Check if there are some false positive
     if tx_hash not in self.filtered_transation_hashes:
         return
     tx_is_mine = False
     for vin in message_obj.tx.vin:
         if b2x(vin.scriptSig) in self.my_scripts:
             tx_is_mine = True
             print("Transaction ID {}".format(tx_id))
             print(
                 "You spent the bitcoin earned from transaction with ID\n{} (vout index {})"
                 .format(b2lx(vin.prevout.hash), vin.prevout.n))
             print("-" * 100)
     for vout in message_obj.tx.vout:
         if b2x(vout.scriptPubKey) in self.my_scripts:
             tx_is_mine = True
             print("Transaction ID {}".format(tx_id))
             print("You earned {} bitcoin".format(vout.nValue))
             print("-" * 100)
     if tx_is_mine:
         # You can store the transition data in order to create your own wallet
         pass
Ejemplo n.º 6
0
    def test_block_get_header(self):
        block = Block.deserialize(self.raw_block)
        header = block.get_header()

        self.assertEqual(1, header.version)
        self.assertEqual(
            '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f',
            b2lx(header.prev_block))
        self.assertEqual(
            '0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098',
            b2lx(header.merkle_root))
        self.assertEqual(
            '0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098',
            b2lx(header.stake_root))
        self.assertEqual(0, header.vote_bits)
        self.assertEqual('000000000000', b2x(header.final_state))
        self.assertEqual(0, header.voters)
        self.assertEqual(0, header.fresh_stake)
        self.assertEqual(0, header.revocations)
        self.assertEqual(0, header.pool_size)
        self.assertEqual(486604799, header.bits)
        self.assertEqual(0, header.sbits)
        self.assertEqual(1, header.height)
        self.assertEqual(1, header.size)
        self.assertEqual(1231469665, header.timestamp)
        self.assertEqual(2573394689, header.nonce)
        self.assertEqual(
            '000000000000000000000000000000000000000000000000000000000000000000000000',
            b2x(header.extra_data))
Ejemplo n.º 7
0
    def getdata_message(self, connection, message):
        self.sync.lock.acquire()
        try:
            for inv in message.inv:
                try:
                    if net.CInv.typemap[inv.type] == 'Block':
                        hash_ = inv.hash
                        if hash_ in self.chain.blocks:
                            if self.chain.blocks[hash_].cblock:
                                self.send_block(connection, self.chain.blocks[hash_].cblock)
                            else:
                                if hash_ in self.deferred_block_requests:
                                    self.deferred_block_requests[hash_].append(connection.host[0])
                                else:
                                    self.deferred_block_requests[hash_] = [connection.host[0]]
                                logging.info(
                                    'Added Block(hash={}) requested from {} to deferred block requests'
                                    .format(core.b2lx(hash_), self.repr_connection(connection)))
                        else:
                            logging.warn(
                                'Never seen Block(hash={}) requested from {}'
                                .format(core.b2lx(hash_), self.repr_connection(connection)))
                    else:
                        pass
                except KeyError:
                    logging.warn("unknown inv type={}")

        finally:
            self.sync.lock.release()
Ejemplo n.º 8
0
def collect_transactions():
    blockchain = Blockchain()

    count = blockchain.get_block_count()
    start = Info.objects.get(id=1)
    logger.info('Blockchain count: %d' % count)
    logger.info('Fetching blocks from %d' % (start.height + 1))

    for height in range(start.height + 1, count + 1):
        block = blockchain.get_block_by_height(height)
        for tx in block.vtx:
            txid = b2lx(tx.GetTxid())
            txsrlzr = BaseTransactionSerializer(data={
                'id': txid,
                'vin': [],
                'vout': []
            })
            if txsrlzr.is_valid():
                newtx = txsrlzr.save()
            else:
                newtx = Transaction.objects.get(id=txid)

            for v in tx.vin:
                newtx.vin = []
                if not v.prevout.is_null():
                    t = Transaction.objects.get(id=b2lx(v.prevout.hash))
                    coin_id = t.vout[v.prevout.n]
                    newtx.vin.append(coin_id)
                    coin = Coin.objects.get(id=coin_id)
                    coin.spendable = False
                    coin.frozen = False
                    coin.save()

            for i, v in enumerate(tx.vout):
                newtx.vout = []
                if v.nValue > 0:
                    data = {
                        'txid': txid,
                        'vout': i,
                        'owner': str(CBitcoinAddress.from_scriptPubKey(v.scriptPubKey)),
                        'value': v.nValue,
                        'height': height,
                        'spendable': True,
                        'frozen': False,
                    }
                    serializer = BaseCoinSerializer(data=data)
                    if serializer.is_valid():
                        coin = serializer.save()
                    else:
                        coin = Coin.objects.get(txid=data['txid'], vout=i)
                    newtx.vout.append(coin.id)
                # else:
                #     print(blockchain.get_data_from_vout(v))
            newtx.save()

    start.height = count
    start.save()

    logger.info('Successfully loaded all transactions.')
Ejemplo n.º 9
0
    def sweep_btc_account(self, SENDER_ADDRESS='', email=''):
        addrs = []
        addrs.append(SENDER_ADDRESS)

        transactions = []
        transactions_with_key = []
        sum = 0.0

        utxo = rpc.listunspent(minconf=6, addrs=addrs)
        # Return if there are no transactions
        if len(utxo) == 0: return

        for txo in utxo:
            sum += float(txo['amount']) / COIN
            transaction = {}
            transaction['txid'] = b2lx(txo['outpoint'].hash)
            transaction['vout'] = txo['outpoint'].n
            transactions.append(transaction)
            transaction['scriptPubKey'] = hexlify(txo['scriptPubKey'])
            transactions_with_key.append(transaction)

        # Need to calculate transaction fee
        transaction_fee = 0.0001

        addresses = {}
        addresses[EXCHANGE_BITCOIN_ADDRESS] = sum - transaction_fee

        # Pickup the private key from the database, hardcoded for now
        PRIVATE_KEY = manager_c.get('bitcoin_keypairs',
                                    SENDER_ADDRESS)['priv_key']
        private_keys = []
        private_keys.append(PRIVATE_KEY)

        try:
            raw_tx = rpc.createrawtransaction(transactions, addresses)
            signed_transaction = rpc.signrawtransaction(
                raw_tx, transactions_with_key, private_keys)
        except:
            raise
            return

        if not signed_transaction['complete'] or not signed_transaction:
            raise 'Transaction signing unsuccessful'
            return
        else:
            txid = rpc.sendrawtransaction(signed_transaction['tx'])
            print 'Sent %s from %s to %s' % (
                addresses[EXCHANGE_BITCOIN_ADDRESS], SENDER_ADDRESS,
                PRIVATE_KEY)
            lxtxid = b2lx(txid)
            print lxtxid
            # Update the the users space in hyperdex, add 'sum' bitcoin to the
            # user's balance keyed on email-id.
            x = webserver_c.begin_transaction()
            #x.put('users', email, {'Bitcoin': x.get('users', email)['Bitcoin'] + addresses[EXCHANGE_BITCOIN_ADDRESS]})
            x.atomic_add('users', email,
                         {'Bitcoin': addresses[EXCHANGE_BITCOIN_ADDRESS]})
            x.commit()
Ejemplo n.º 10
0
    def sweep_btc_account(self, SENDER_ADDRESS='', email=''):
        addrs = []
        addrs.append(SENDER_ADDRESS)

        transactions = []
        transactions_with_key = []
        sum = 0.0

        utxo = rpc.listunspent(minconf=6, addrs=addrs)
        # Return if there are no transactions
        if len(utxo) == 0: return

        for txo in utxo:
            sum += float(txo['amount'])/COIN
            transaction = {}
            transaction['txid'] = b2lx(txo['outpoint'].hash)
            transaction['vout'] = txo['outpoint'].n
            transactions.append(transaction)
            transaction['scriptPubKey'] = hexlify(txo['scriptPubKey'])
            transactions_with_key.append(transaction)

        # Need to calculate transaction fee
        transaction_fee = 0.0001

        addresses = {}
        addresses[EXCHANGE_BITCOIN_ADDRESS] = sum - transaction_fee

        # Pickup the private key from the database, hardcoded for now
        PRIVATE_KEY = manager_c.get('bitcoin_keypairs', SENDER_ADDRESS)['priv_key']
        private_keys = []
        private_keys.append(PRIVATE_KEY)

        try:
            raw_tx = rpc.createrawtransaction(
                transactions, 
                addresses)
            signed_transaction = rpc.signrawtransaction(
                raw_tx, 
                transactions_with_key, 
                private_keys)
        except:
            raise
            return

        if not signed_transaction['complete'] or not signed_transaction:
            raise 'Transaction signing unsuccessful'
            return
        else:
            txid = rpc.sendrawtransaction(signed_transaction['tx'])
            print 'Sent %s from %s to %s' % (addresses[EXCHANGE_BITCOIN_ADDRESS], SENDER_ADDRESS, PRIVATE_KEY)
            lxtxid = b2lx(txid)
            print lxtxid
            # Update the the users space in hyperdex, add 'sum' bitcoin to the 
            # user's balance keyed on email-id.
            x = webserver_c.begin_transaction()
            #x.put('users', email, {'Bitcoin': x.get('users', email)['Bitcoin'] + addresses[EXCHANGE_BITCOIN_ADDRESS]})
            x.atomic_add('users', email, {'Bitcoin': addresses[EXCHANGE_BITCOIN_ADDRESS]})
            x.commit()
Ejemplo n.º 11
0
    def connect_block(self, ser_hash, block, blkmeta):

        # update database pointers for best chain
        with self.db.write_batch(transaction=True) as wb:
            wb.put(b'misc:total_work', int_to_bytes(blkmeta.work))
            wb.put(b'misc:height', struct.pack('i', blkmeta.height))
            wb.put(b'misc:tophash', lx(ser_hash))

            self.log.info("ChainDb: height %d, block %s" % (blkmeta.height, b2lx(block.GetHash())))

            bHash = b2lx(block.GetHash())
            dt = datetime.utcfromtimestamp(block.nTime)
            # self.db_sync()
            if dt > datetime.utcnow() - timedelta(minutes=10) and self.initial_sync:
                self.log.info('Chain has caught up')
                self.initial_sync = False
                self.db_sync()

            height = blkmeta.height
            timestamp = dt.timestamp()
            wb.put(('pg_block:%s' % bHash).encode(), json.dumps({
                'merkle_root': b2lx(block.hashMerkleRoot), # save merkle root as hex string
                'difficulty': block.calc_difficulty(block.nBits), # save difficulty as both calculated and nBits
                'timestamp': timestamp,
                'version': block.nVersion, # we can do binary operation if saved as binary
                'height': height,
                'bits': block.nBits,
                'nonce': block.nNonce,
                'size': len(block.serialize()),
                'hash': bHash,
                'coinbase': base64.encodebytes(block.vtx[0].vin[0].scriptSig).decode(),
                'tx_count': len(block.vtx),
                'tx': list(map(lambda tx : b2lx(tx.GetTxid()), block.vtx))
            }).encode())

            self.parse_vtx(block.vtx, wb, timestamp, block.GetHash(), height)

            self._update_address_index()

            self.checktransactions()

            self.checkaddresses()

            self.checkblocks(height)
            
            self.checkutxos()

            h = block.GetHash()
            # wb.put(b'tip', h)
            # wb.put(b'height', struct.pack('i', height))

            for key, value in self.utxo_cache.items():
                wb.put(key, value)
            self.utxo_cache = {}
            
            # self.log.info("UpdateTip: %s height %s" % (b2lx(h), height))
            return dt
Ejemplo n.º 12
0
def verify_timestamp(timestamp, args):
    args.calendar_urls = []
    upgrade_timestamp(timestamp, args)

    def attestation_key(item):
        (msg, attestation) = item
        if attestation.__class__ == BitcoinBlockHeaderAttestation:
            return attestation.height
        else:
            return 2**32-1

    good = False
    for msg, attestation in sorted(timestamp.all_attestations(), key=attestation_key):
        if attestation.__class__ == PendingAttestation:
            # Handled by the upgrade_timestamp() call above.
            pass

        elif attestation.__class__ == BitcoinBlockHeaderAttestation:
            if not args.use_bitcoin:
                logging.warning("Not checking Bitcoin attestation; Bitcoin disabled")
                logging.info("To verify manually, check that Bitcoin block %d has merkleroot %s" %
                                (attestation.height, b2lx(msg)))
                continue

            proxy = args.setup_bitcoin()

            try:
                block_count = proxy.getblockcount()
                blockhash = proxy.getblockhash(attestation.height)
            except IndexError:
                logging.error("Bitcoin block height %d not found; %d is highest known block" % (attestation.height, block_count))
                continue
            except ConnectionError as exp:
                logging.error("Could not connect to local Bitcoin node: %s" % exp)
                continue

            block_header = proxy.getblockheader(blockhash)

            logging.debug("Attestation block hash: %s" % b2lx(blockhash))

            try:
                attested_time = attestation.verify_against_blockheader(msg, block_header)
            except VerificationError as err:
                logging.error("Bitcoin verification failed: %s" % str(err))
                continue

            logging.info("Success! Bitcoin block %d attests existence as of %s" %
                            (attestation.height,
                             time.strftime('%Y-%m-%d %Z',
                                          time.localtime(attested_time))))
            good = True

            # One Bitcoin attestation is enough
            break

    return good
Ejemplo n.º 13
0
 def __repr__(self):
     return "%s(%i, lx(%s), lx(%s), %s, 0x%08x, 0x%08x, %s)" % (
         self.__class__.__name__,
         self.nVersion,
         b2lx(self.hashPrevBlock),
         b2lx(self.hashMerkleRoot),
         self.nTime,
         self.nBits,
         self.nNonce,
         self.auxpow,
     )
Ejemplo n.º 14
0
def printInfo(blockheight):
    #see https://blockchain.info/block-height/381410
    bitcoinLayer = bitcoin.rpc.Proxy()
    h = bitcoinLayer.getblockhash(blockheight)
    block = bitcoinLayer.getblock(h)

    print (block.nTime)
    print (block.get_header())
    print (b2lx(block.hashMerkleRoot))
    print (b2lx(block.hashPrevBlock))
    print (len(block.vMerkleTree))
    print (len(block.vtx))
Ejemplo n.º 15
0
    def parse_vtx(self, vtx, wb, timestamp, bHash, bHeight):
        neverseen = 0
        for tx in vtx:
            txid = b2lx(tx.GetTxid())

            if not self.mempool_remove(txid):
                neverseen += 1
            txidx = TxIdx(b2lx(bHash))
            if not self.puttxidx(txid, txidx, batch=wb):
                self.log.warn("TxIndex failed %s" % (txid,))
                return False
            self.parse_tx(timestamp, b2lx(bHash), bHeight, tx, wb)
Ejemplo n.º 16
0
 def convert_block(self, index, block):
     """
     Return list of triples representing Bitcoin block according to the
     model specified in model.ttl.
     """
     # Curry few heavily used methods to make intents clearer.
     m, d, v, add = self.model_uri, self.data_uri, self.literal, self._add
     # Extract and normalize raw block data.
     blk_node = 'block{}'.format(index)
     blk_hash = b2lx(block.GetHash())
     blk_version = block.nVersion
     blk_time = block.nTime
     # Add block header data.
     add((d(blk_node), RDF.TYPE, m('Block')),
         (d(blk_node), m('height'), v(index, XSD.INT)),
         (d(blk_node), m('hash'), v(blk_hash, XSD.STRING)),
         (d(blk_node), m('version'), v(blk_version, XSD.INT)),
         (d(blk_node), m('time'), v(blk_time, XSD.INT)))
     # Add previous block links.
     if index > 0:
         blk_prev_blk_node = d('block{}'.format(index - 1))
         add((d(blk_node), m('prevBlock'), blk_prev_blk_node))
     # Add transaction data.
     for tx_i, tx in enumerate(block.vtx):
         tx_node = b2lx(tx.GetHash())
         tx_locktime = tx.nLockTime
         add((d(tx_node), RDF.TYPE, m('Transaction')),
             (d(tx_node), m('index'), v(tx_i, XSD.INT)),
             (d(tx_node), m('txid'), v(tx_node, XSD.STRING)),
             (d(tx_node), m('lockTime'), v(tx_locktime, XSD.LONG)),
             (d(blk_node), m('transaction'), d(tx_node)))
         # Add txin data.
         for in_i, txin in enumerate(tx.vin):
             txin_node = self._connection.createBNode()
             output_hash = b2lx(txin.prevout.hash)
             output_n = txin.prevout.n
             script = self.decode_script(txin.scriptSig)
             add((txin_node, RDF.TYPE, m('TxInput')),
                 (txin_node, m('index'), v(in_i, XSD.INT)),
                 (txin_node, m('outputHash'), v(output_hash, XSD.STRING)),
                 (txin_node, m('outputIndex'), v(output_n, XSD.STRING)),
                 (txin_node, m('unlockScript'), v(script, XSD.STRING)),
                 (d(tx_node), m('input'), txin_node))
         # Add txout data.
         for out_i, txout in enumerate(tx.vout):
             txout_node = self._connection.createBNode()
             amount = txout.nValue
             script = self.decode_script(txout.scriptPubKey)
             add((txout_node, RDF.TYPE, m('TxOutput')),
                 (txout_node, m('index'), v(out_i, XSD.INT)),
                 (txout_node, m('amount'), v(amount, XSD.LONG)),
                 (txout_node, m('lockScript'), v(script, XSD.STRING)),
                 (d(tx_node), m('output'), txout_node))
Ejemplo n.º 17
0
def create_timestamp(timestamp, calendar_urls, setup_bitcoin=False):
    """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.
    """

    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)

    for calendar_url in calendar_urls:
        remote = remote_calendar(calendar_url)

        logging.info('Submitting to remote calendar %s' % calendar_url)
        calendar_timestamp = remote.submit(timestamp.msg)
        timestamp.merge(calendar_timestamp)
Ejemplo n.º 18
0
 def mempool_add(self, tx):
     # Do not add if not fully synced
     if self.initial_sync:
         return
     # TODO: Transaction can get stuck in mempool if double-spent or RBF
     # TODO: Add expiry from mempool? e.g. x blocks, either indicates not accepted by the network or stuck in mempool due to another issue
     self.mempool.add(tx)
     timestamp = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')
     tx_parsed = self.parse_tx(timestamp, None, None, tx)
     Transaction.insert_many([tx_parsed]).execute(None)
     txid = b2lx(tx.GetTxid())
     for idx, vin in enumerate(tx.vin):
         Utxo.update(spent=True).where((Utxo.txid == b2lx(vin.prevout.hash)) & (Utxo.vout == vin.prevout.n)).execute()
     external_sio.emit('tx', tx_parsed, room='inv')
Ejemplo n.º 19
0
 def create_signature(self, privkey, reedem_script):
     """
     Exports a raw signature suitable for use in a multisig transaction
     """
     seckey = CBitcoinSecret.from_secret_bytes(x(bitcointools.encode_privkey(privkey, "hex")))
     signatures = []
     for i in range(len(self.tx.vin)):
         sighash = SignatureHash(CScript(x(reedem_script)), self.tx, i, SIGHASH_ALL)
         signatures.append({
             "index": i,
             "signature": (seckey.sign(sighash) + struct.pack('<B', SIGHASH_ALL)).encode("hex"),
             "outpoint": b2lx(self.tx.vin[i].prevout.hash) + b2lx(struct.pack(b"<I", self.tx.vin[i].prevout.n))
         })
     return signatures
Ejemplo n.º 20
0
 def recv_votes(self, msg):
     """ vote (transaction lock) collation """
     txid = b2lx(msg.txlvote.hash)
     vin = b2lx(msg.txlvote.vin.prevout.hash) + "-" + str(msg.txlvote.vin.prevout.n)
     if txid not in self.mempool:
         self.mempool[txid] = {}
     if "recv_time" not in self.mempool[txid]:
         self.mempool[txid]["recv_time"] = int(time.time())
     if "locks" not in self.mempool[txid]:
         self.mempool[txid]["locks"] = set()
     self.mempool[txid]["locks"].add(vin)
     # only print locks for target addresses
     if "processed" in self.mempool[txid]:
         info("    LOCK: %s from %s" % (txid, vin))
     self._check_ix_threshold(txid)
Ejemplo n.º 21
0
 def set_block_header(self, block):
     self.clear()
     if not isinstance(block, CBlockHeader):
         return
     items = map(lambda x: QStandardItem(x), [
             str(block.nVersion),
             b2lx(block.hashPrevBlock),
             b2lx(block.hashMerkleRoot),
             str(block.nTime),
             str(block.nBits),
             str(block.nNonce)
     ])
     rows = range(6)
     for row, item in zip(rows, items):
         self.model.setItem(row, 0, item)
Ejemplo n.º 22
0
    def parse_vtx(self, vtx, wb, timestamp, bHash, bHeight):
        neverseen = 0
        for tx in vtx:
            txid = b2lx(tx.GetTxid())

            if not self.mempool_remove(txid):
                neverseen += 1
            txidx = TxIdx(b2lx(bHash))
            if not self.puttxidx(txid, txidx, batch=wb):
                self.log.warn("TxIndex failed %s" % (txid,))
                return False
            tx_parsed = self.parse_tx(timestamp, b2lx(bHash), bHeight, tx, wb)
            # Emit coinbase transactions
            if not self.initial_sync and tx.is_coinbase():
                external_sio.emit('tx', tx_parsed, room='inv')
Ejemplo n.º 23
0
 def process_block(self, block):
     """
     A block (or header) passed into this function will be added into the database only if it passes all
     validity checks.
     """
     try:
         header = block if isinstance(block, CBlockHeader) else block.get_header()
         CheckBlockHeader(header, True)
         # self._check_timestamp(header.nTime) # not working on testnet?
         target = self._check_difficulty_target(header)
         h = self._get_parent_height(header)
         if h is not None:
             self._commit_block(h + 1, b2lx(header.GetHash()), b2lx(header.hashPrevBlock), header.nBits, header.nTime, target)
     except CheckBlockHeaderError, e:
         print e.message
Ejemplo n.º 24
0
 def set_block_header(self, block):
     self.clear()
     if not isinstance(block, CBlockHeader):
         return
     items = map(lambda x: QStandardItem(x), [
         str(block.nVersion),
         b2lx(block.hashPrevBlock),
         b2lx(block.hashMerkleRoot),
         str(block.nTime),
         str(block.nBits),
         str(block.nNonce)
     ])
     rows = range(6)
     for row, item in zip(rows, items):
         self.model.setItem(row, 0, item)
Ejemplo n.º 25
0
 def cashout_doge(self):
     ''' For every incomplete cashout 'transaction', create add the address,
     amount pair to the payments dictionary and then call the sendmany() rpc
     from the 'exchange' account. Then update all the 'transactions' you 
     just completed with the BTC transactionID, i.e. lxtxid.
     '''
     webserver_x = webserver_c.begin_transaction()
     payments = {}
     serviced_txns = []
     lxtxid = ''
     for order in webserver_c.search('dogecoin_txns', {'txid': ''}): 
         try:
             amount = order['amount'] - 0.0002
             addr = order['pub_key']
             if addr in payments.keys(): payments[addr] += (amount * COIN)
             else: payments[addr] = (amount * COIN)
             serviced_txns.append(order['when'])
         except:
             continue
     if len(payments) > 0:
         print 'Calling send'
         txid = dogecoin_rpc.sendmany(fromaccount='', payments=payments)
         lxtxid = b2lx(txid)
         print '%s' % lxtxid
         for when in serviced_txns:
             webserver_x.put('dogecoin_txns', when, {'txid': str(lxtxid)})
     webserver_x.commit()
Ejemplo n.º 26
0
    def validate_merkle_block(self, current_block_hash, merkle_root,
                              total_transactions, hashes, flags):

        # Check coherence between the stored block header and the downloaded merkle block
        block = self.block_chain[current_block_hash]
        assert block["merkle_root"] == merkle_root
        '''
        Read the section "Parsing a partial merkle tree object" of BIP 37 to understand 
        the following code
        '''
        hashes_list = []
        bit_list = []
        for _hash in hashes:
            hashes_list.append(_hash)
        raw_data = flags  # Flag bits, packed per 8 in a byte, least significant bit first (WTF)
        for i in range(0, len(raw_data)):
            byte_string = bin(raw_data[i])[2:].rjust(8, "0")[::-1]
            bit_list = bit_list + list(byte_string)

        leaves = []
        for i in range(0, total_transactions):
            leaves.append(Node(0))
        merkle_tree_root_node = self.build_merkle_tree_structure(leaves)

        # Transaction hashes that have matched with the bloom filter
        # (some could be false positive)
        transaction_hashes = []
        computed_merkle_root = b2lx(
            self.parse_partial_mekel_tree(merkle_tree_root_node, bit_list,
                                          hashes_list, transaction_hashes))
        assert computed_merkle_root == merkle_root
        return transaction_hashes
Ejemplo n.º 27
0
 def recv_votes(self, msg):
     """ vote (transaction lock) collation """
     txid = b2lx(msg.txlvote.hash)
     vin = (b2lx(msg.txlvote.vin.prevout.hash) + "-" +
            str(msg.txlvote.vin.prevout.n))
     if txid not in self.mempool:
         self.mempool[txid] = {}
     if 'recv_time' not in self.mempool[txid]:
         self.mempool[txid]['recv_time'] = int(time.time())
     if 'locks' not in self.mempool[txid]:
         self.mempool[txid]['locks'] = set()
     self.mempool[txid]['locks'].add(vin)
     # only print locks for target addresses
     if 'processed' in self.mempool[txid]:
         info("    LOCK: %s from %s" % (txid, vin))
     self._check_ix_threshold(txid)
Ejemplo n.º 28
0
 def recv_tx(self, msg):
     """ tx handler """
     txid = b2lx(msg.tx.GetHash())
     info("   tx: %s" % txid)
     if self._find_payment(msg, txid, 'tx'):
         # refund at next block
         self.vend.show_txrefund()
Ejemplo n.º 29
0
    def do_verify_input(self, tx, in_idx):
        if tx.is_coinbase():
            self.result_edit.setText('Error: Cannot verify coinbase transactions.')
            self.error('Attempted to verify coinbase transaction.')
            return False
        raw_prev_tx = None
        tx_in = tx.vin[in_idx]
        txid = b2lx(tx_in.prevout.hash)
        prev_out_n = tx_in.prevout.n

        try:
            raw_prev_tx = self.handler.download_blockchain_data('raw_transaction', txid)
        except Exception as e:
            self.error(str(e))
            return False

        try:
            prev_tx = Transaction.deserialize(raw_prev_tx.decode('hex'))
            result = bitcoin.core.scripteval.VerifyScript(tx_in.scriptSig, prev_tx.vout[prev_out_n].scriptPubKey, tx, in_idx)
            self.result_edit.setText('Successfully verified input {}'.format(in_idx))
            self.inputs_table_model.set_verified(in_idx, True)
        except Exception as e:
            self.result_edit.setText(str(e))
            self.inputs_table_model.set_verified(in_idx, False)
            self.error(str(e))
            return False

        return True
Ejemplo n.º 30
0
    def getrawtransaction(self, txid, verbose=False):
        """Return transaction with hash txid

        Raises IndexError if transaction not found.

        verbose - If true a dict is returned instead with additional
        information on the transaction.

        Note that if all txouts are spent and the transaction index is not
        enabled the transaction may not be available.
        """
        try:
            r = self._call("getrawtransaction", b2lx(txid), 1 if verbose else 0)
        except JSONRPCError as ex:
            raise IndexError(
                "%s.getrawtransaction(): %s (%d)" % (self.__class__.__name__, ex.error["message"], ex.error["code"])
            )
        if verbose:
            r["tx"] = CTransaction.deserialize(unhexlify(r["hex"]))
            del r["hex"]
            del r["txid"]
            del r["version"]
            del r["locktime"]
            del r["vin"]
            del r["vout"]
            r["blockhash"] = lx(r["blockhash"]) if "blockhash" in r else None
        else:
            r = CTransaction.deserialize(unhexlify(r))

        return r
Ejemplo n.º 31
0
 def recv_tx(self, msg):
     """ tx handler """
     txid = b2lx(msg.tx.GetHash())
     info("   tx: %s" % txid)
     if self._find_payment(msg, txid, "tx"):
         # refund at next block
         self.vend.show_txrefund()
Ejemplo n.º 32
0
def spend_escrow(serial_tx, redeem_script, payer_sig, redeemer_sig):
    '''
        Sends a transaction fulfilling the redeem script of escrow tx
    '''
    # Read in transaction
    temp_tx = CTransaction.deserialize(serial_tx)
    tx = CMutableTransaction.from_tx(temp_tx)

    txin = tx.vin[0]

    # Set script sig
    txin.scriptSig = CScript([OP_0,
                             payer_sig + '\x01',
                             redeemer_sig + '\x01',
                             redeem_script])

    # Verify script
    redeem_script = CScript(redeem_script)
    serial_tx = tx.serialize()
    VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(),
                 tx, 0, [SCRIPT_VERIFY_P2SH])

    serial_tx = tx.serialize()
    txid = b2lx(Hash(serial_tx))

    print("spend_escrow: TXID is %s" % txid)
    print("spend_escrow: RAW TX is %s" % b2x(serial_tx))

    return serial_tx
Ejemplo n.º 33
0
    def is_pending(self, commitment):
        """Return whether or not a commitment is waiting to be stamped

        Returns False if not, or str reason if it is
        """
        if commitment in self.pending_commitments:
            return "Pending confirmation in Bitcoin blockchain"

        else:
            journal = Journal(self.calendar.path + '/journal')
            idx = self.journal_cursor
            while idx is not None:
                # cursor is None when stamper loop never executed once
                try:
                    recent_commitment = journal[idx]
                except KeyError:
                    break
                if recent_commitment == commitment:
                    return "Pending confirmation in Bitcoin blockchain"
                idx += 1

            for height, ttx in self.txs_waiting_for_confirmation.items():
                for commitment_timestamp in ttx.commitment_timestamps:
                    if commitment == commitment_timestamp.msg:
                        return "Timestamped by transaction %s; waiting for %d confirmations"\
                               % (b2lx(ttx.tx.GetTxid()), self.min_confirmations-1)

        return False
Ejemplo n.º 34
0
    def get_start_hash(self):
        try:
            logging.debug('received get_start_hash over cli')

            return core.b2lx(self.chain.start_hash)
        finally:
            logging.debug('send start_hash over cli')
Ejemplo n.º 35
0
    async def run(self):
        verb('Starting solver with command {}'.format(self.cmdline))
        create = asyncio.create_subprocess_exec(
                *self.cmdline,
                stdout=asyncio.subprocess.PIPE,
                stderr=asyncio.subprocess.STDOUT)
        try:
            self.solver = await create
            verb('Solver started.')
        except FileNotFoundError as e:
            raise SolverException("Could not find binary {}; is the path correct?".format(self.cmdline[0]))
        except Exception as e:
            raise SolverException("Failed to execute '{}': {}".format(self.cmdline, e))

        self.banner = await self.eat_banner()
        verb('Banner:\n' + self.banner)

        try:
            while True:
                nonce, sols = await self.parse_solutions()
                verb('Solver returned {:d} solutions for nonce {}'
                        .format(len(sols), b2lx(nonce)))
                for sol in sols:
                    if IsValidSolution(self.header, nonce, sol):
                        return (sol, nonce)
        finally:
            self.solver.terminate()
            await self.solver.communicate() # .wait() would deadlock if pipe is full
Ejemplo n.º 36
0
	def provide_transaction(self, transaction_data):
		self.send_lock.acquire()

		if self.send_transaction_cache.contains(transaction_data):
			self.send_lock.release()
			return
		if len(transaction_data) > self.MAX_RELAY_TRANSACTION_BYTES and (len(transaction_data) > self.MAX_RELAY_OVERSIZE_TRANSACTION_BYTES or self.send_transaction_cache.get_flag_count() >= MAX_EXTRA_OVERSIZE_TRANSACTIONS):
			self.send_lock.release()
			return

		try:
			relay_data = pack('>3I', self.MAGIC_BYTES, self.TRANSACTION_TYPE, len(transaction_data))
			relay_data += transaction_data
			self.relay_sock.sendall(relay_data)
			self.send_transaction_cache.add(transaction_data, len(transaction_data) > self.MAX_RELAY_OVERSIZE_TRANSACTION_BYTES)

			if deserialize_utils:
				transaction = CTransaction.deserialize(transaction_data)
				print("Sent transaction " + str(b2lx(transaction.GetHash())) + " of size " + str(len(transaction_data)))
			else:
				print("Sent transaction of size " + str(len(transaction_data)))
		except (OSError, socket.error) as err:
			print("Failed to send to relay node: ", err)

		self.send_lock.release()
Ejemplo n.º 37
0
def calculate_tx_fees(coins, currency, tx_hex):
    #Process source TX.
    rpc = coins[currency]["rpc"]["sock"]
    tx = CTransaction.deserialize(binascii.unhexlify(tx_hex))

    #Tally input coins.
    input_total = decimal.Decimal(0)
    for vin in tx.vin:
        txid = b2lx(vin.prevout.hash) 
        vin_tx_hex = rpc.getrawtransaction(txid)
        vin_tx = CTransaction.deserialize(binascii.unhexlify(vin_tx_hex))
        input_value = vin_tx.vout[vin.prevout.n].nValue
        input_total += decimal.Decimal(str_money_value(input_value))

    #Tally output coins.
    output_total = decimal.Decimal(0)
    for vout in tx.vout:
        output_value = decimal.Decimal(str_money_value(vout.nValue))
        output_total += output_value

    #TX fees are the difference between the source and 
    fees = input_total - output_total
    
    #Return totals and fees.
    return [input_total, output_total, fees]
Ejemplo n.º 38
0
def submit_opreturn(rpc_connection, address, data):
    from bitcoin.core import CTxIn, CMutableTxOut, CScript, CMutableTransaction, COIN, CENT, b2x, b2lx
    from bitcoin.core.script import OP_CHECKSIG, OP_RETURN

    txouts = []

    unspent = sorted([y for y in rpc_connection.listunspent(0) if str(y['address']) == address], key=lambda x: hash(x['amount']))

    txins = [CTxIn(unspent[-1]['outpoint'])]

    value_in = unspent[-1]['amount']

    change_pubkey = rpc_connection.validateaddress(address)['pubkey']
    change_out = CMutableTxOut(int(value_in - 2*CENT), CScript([change_pubkey, OP_CHECKSIG]))
    digest_outs = [CMutableTxOut(CENT, CScript([OP_RETURN, data]))]
    txouts = [change_out] + digest_outs
    tx = CMutableTransaction(txins, txouts)
    
    print tx.serialize().encode('hex')
    r = rpc_connection.signrawtransaction(tx)
    assert r['complete']
    tx = r['tx']


    #print b2x(tx.serialize())
    #print len(tx.serialize()), 'bytes'
    print(b2lx(rpc_connection.sendrawtransaction(tx)))
Ejemplo n.º 39
0
    def getblockheader(self, block_hash, verbose=False):
        """Get block header <block_hash>

        verbose - If true a dict is returned with the values returned by
                  getblockheader that are not in the block header itself
                  (height, nextblockhash, etc.)

        Raises IndexError if block_hash is not valid.
        """
        try:
            block_hash = b2lx(block_hash)
        except TypeError:
            raise TypeError(
                '%s.getblockheader(): block_hash must be bytes; got %r instance'
                % (self.__class__.__name__, block_hash.__class__))
        try:
            r = self._call('getblockheader', block_hash, verbose)
        except InvalidAddressOrKeyError as ex:
            raise IndexError('%s.getblockheader(): %s (%d)' %
                             (self.__class__.__name__, ex.error['message'],
                              ex.error['code']))

        if verbose:
            nextblockhash = None
            if 'nextblockhash' in r:
                nextblockhash = lx(r['nextblockhash'])
            return {
                'confirmations': r['confirmations'],
                'height': r['height'],
                'mediantime': r['mediantime'],
                'nextblockhash': nextblockhash,
                'chainwork': x(r['chainwork'])
            }
        else:
            return CBlockHeader.deserialize(unhexlify(r))
Ejemplo n.º 40
0
def submit_opreturn(rpc_raw, rpc_connection, address, data):
    from bitcoin.core import CTxIn, CMutableTxOut, CScript, CMutableTransaction, COIN, CENT, b2x, b2lx
    from bitcoin.core.script import OP_CHECKSIG, OP_RETURN

    txouts = []

    unspent = sorted(
        [y for y in rpc_connection.listunspent(0) if str(y["address"]) == address], key=lambda x: hash(x["amount"])
    )

    txins = [CTxIn(unspent[-1]["outpoint"])]

    value_in = unspent[-1]["amount"]

    change_pubkey = rpc_connection.validateaddress(address)["pubkey"]
    change_out = CMutableTxOut(int(value_in - 1 * CENT), CScript([change_pubkey, OP_CHECKSIG]))
    digest_outs = [CMutableTxOut(0, CScript([OP_RETURN, data]))]
    txouts = [change_out] + digest_outs
    tx = CMutableTransaction(txins, txouts)

    tx_hex = tx.serialize().encode("hex")
    print "decoderawtransaction", tx_hex
    transaction_decoded = rpc_raw.decoderawtransaction(tx_hex)
    print json.dumps(transaction_decoded, indent=4, default=json_custom_parser)
    r = rpc_connection.signrawtransaction(tx)
    assert r["complete"]
    tx = r["tx"]

    # print b2x(tx.serialize())
    # print len(tx.serialize()), 'bytes'
    sent_tx_id = rpc_connection.sendrawtransaction(tx)
    return b2lx(sent_tx_id)
Ejemplo n.º 41
0
    def getblockheader(self, block_hash, verbose=False):
        """Get block header <block_hash>

        verbose - If true a dict is returned with the values returned by
                  getblockheader that are not in the block header itself
                  (height, nextblockhash, etc.)

        Raises IndexError if block_hash is not valid.
        """
        try:
            block_hash = b2lx(block_hash)
        except TypeError:
            raise TypeError('%s.getblockheader(): block_hash must be bytes; got %r instance' %
                    (self.__class__.__name__, block_hash.__class__))
        try:
            r = self._call('getblockheader', block_hash, verbose)
        except InvalidAddressOrKeyError as ex:
            raise IndexError('%s.getblockheader(): %s (%d)' %
                    (self.__class__.__name__, ex.error['message'], ex.error['code']))

        if verbose:
            nextblockhash = None
            if 'nextblockhash' in r:
                nextblockhash = lx(r['nextblockhash'])
            return {'confirmations':r['confirmations'],
                    'height':r['height'],
                    'mediantime':r['mediantime'],
                    'nextblockhash':nextblockhash,
                    'chainwork':x(r['chainwork'])}
        else:
            return CBlockHeader.deserialize(unhexlify(r))
Ejemplo n.º 42
0
 def __save_confirmed_timestamp_tx(self, confirmed_tx):
     """Save a fully confirmed timestamp to disk"""
     self.calendar.add_commitment_timestamps(
         confirmed_tx.commitment_timestamps)
     logging.info("tx %s fully confirmed, %d timestamps added to calendar" %
                  (b2lx(confirmed_tx.tx.GetTxid()),
                   len(confirmed_tx.commitment_timestamps)))
Ejemplo n.º 43
0
 def lockunspent(self, unlock, outpoints):
     """Lock or unlock outpoints"""
     json_outpoints = [{
         'txid': b2lx(outpoint.hash),
         'vout': outpoint.n
     } for outpoint in outpoints]
     return self._call('lockunspent', unlock, json_outpoints)
Ejemplo n.º 44
0
def cmd_witnessinfo(args):
    witness = BitcoinSealWitness.deserialize(args.witness_fd.read())

    print('Hash:\t\t%s' % b2x(witness.hash))
    print('Txid:\t\t%s' % b2lx(witness.txinproof.txproof.txhash))
    print('Seal Hash:\t%s' % b2x(witness.seal.hash))
    print('Seal OutPoint:\t%s:%d' % (b2x(witness.seal.outpoint.hash), witness.seal.outpoint.n))
Ejemplo n.º 45
0
    def getrawtransaction(self, txid, verbose=False):
        """Return transaction with hash txid

        Raises IndexError if transaction not found.

        verbse - If true a dict is returned instead with additional information
                 on the transaction.

        Note that if all txouts are spent and the transaction index is not
        enabled the transaction may not be available.
        """
        try:
            r = self._call('getrawtransaction', b2lx(txid), 1 if verbose else 0)
        except JSONRPCException as ex:
            raise IndexError('%s.getrawtransaction(): %s (%d)' %
                    (self.__class__.__name__, ex.error['message'], ex.error['code']))
        if verbose:
            r['tx'] = CTransaction.deserialize(unhexlify(r['hex']))
            del r['hex']
            del r['txid']
            del r['version']
            del r['locktime']
            del r['vin']
            del r['vout']
            r['blockhash'] = lx(r['blockhash']) if 'blockhash' in r else None
        else:
            r = CTransaction.deserialize(unhexlify(r))

        return r
Ejemplo n.º 46
0
 def parse_tx(self, timestamp, bHash, bHeight, tx, batch=None):
     txid = b2lx(tx.GetTxid())
     tx_data = {
         "txid": txid,
         "vout": [], 
         "vin": [], 
         "input_value": 0, 
         "output_value": 0, 
         "block": bHash, 
         "block_height": bHeight, 
         "addresses_in": {}, 
         "addresses_out": {}, 
         "timestamp": timestamp
     }
     for idx, vin in enumerate(tx.vin):
         self.parse_vin(tx, txid, tx_data, vin, idx, batch)
     for idx, vout in enumerate(tx.vout):
         self.parse_vout(tx, txid, tx_data, vout, idx, batch, blockHeight=bHeight)
     if batch:
         batch.put(('pg_tx:%s' % txid).encode(), json.dumps(tx_data).encode())
         self.transaction_change_count += 1
         # connect inputs to wallet group tree
         addrs = list(map(lambda x: x[0], tx_data['addresses_in'].items()))
         self.wallet_group.connect_input(batch, addrs)
     return tx_data
Ejemplo n.º 47
0
    def get_confirmations(self, block_id):
        """
        Given a block id, return the number of confirmations
        """
        block_height = self.get_block_height(b2lx(block_id))
        if block_height is None:
            return 0
        tip_height = self.get_height()

        parent = self.get_block_id(self.get_height())
        for i in range(tip_height - block_height):
            parent = self._get_parent(parent)

        if parent == b2lx(block_id):
            return tip_height - block_height + 1
        else:
            return 0
Ejemplo n.º 48
0
 def _get_parent_height(self, header):
     cursor = self.db.cursor()
     cursor.execute('''SELECT height FROM blocks WHERE blockID=?''', (b2lx(header.hashPrevBlock),))
     height = cursor.fetchone()
     if height is not None:
         return height[0]
     else:
         return None
Ejemplo n.º 49
0
 def set_block(self, block):
     self.clear()
     if not isinstance(block, Block):
         return
     txids = [b2lx(i.GetHash()) for i in block.vtx]
     items = map(lambda x: QStandardItem(x), txids)
     for item in items:
         self.model.appendRow(item)
Ejemplo n.º 50
0
 def __save_confirmed_timestamp_tx(self, confirmed_tx):
     """Save a fully confirmed timestamp to disk"""
     for timestamp in confirmed_tx.commitment_timestamps:
         self.calendar.add_commitment_timestamp(timestamp)
     logging.info(
         "tx %s fully confirmed, %d timestamps added to calendar"
         % (b2lx(confirmed_tx.tx.GetHash()), len(confirmed_tx.commitment_timestamps))
     )
Ejemplo n.º 51
0
    def broadcast(self, libbitcoin_client):
        """
        Broadcast the tx to the network

        Args:
            libbitcoin_server: an `obelisk.Libbitcoin_client` object.
        """
        libbitcoin_client.broadcast(self.to_raw_tx())
        self.log.info("Broadcasting payout tx %s to network" % b2lx(self.tx.GetHash()))
Ejemplo n.º 52
0
 def determine_status():
     try:
         proxy = bitcoin.rpc.Proxy(btc_conf_file=local_settings.BITCOIN_CONF_FILE)
         bestblockhash = proxy.getbestblockhash()
         proxy.call('getblock', b2lx(bestblockhash))
         return 'Up and running'
     except (ConnectionRefusedError, bitcoin.rpc.JSONRPCError) as error:
         print(error)
         return 'Error: Connection Refused'
Ejemplo n.º 53
0
 def set_block(self, block):
     self.clear()
     if not isinstance(block, Block):
         return
     txids = [b2lx(i.GetHash()) for i in block.vtx]
     items = map(lambda x: QStandardItem(x), txids)
     for item in items:
         item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
         self.model.appendRow(item)
Ejemplo n.º 54
0
    def record_block(self, state):
        self.height = state.height
        self.entries = {txid: copy(entry)
                        for txid, entry in state.entries.iteritems()}
        self.time = state.time
        for entry in self.entries.values():
            entry.inblock = False
            entry.isconflict = False
            entry.leadtime = self.time - entry.time

        self.blockheight = state.height + 1
        block = proxy.getblock(proxy.getblockhash(self.blockheight))
        self.blocksize = len(block.serialize())
        blockname = BlockMetadata(self.blockheight).get_poolname()

        blocktxids = [b2lx(tx.GetHash()) for tx in block.vtx]
        entries_inblock = set(self.entries) & set(blocktxids)
        for txid in entries_inblock:
            self.entries[txid].inblock = True
            # Delete it, because state.entries will be used for the next block
            # if there are > 1 blocks in this update cycle.
            del state.entries[txid]

        # Get rid of broken deps, for multiple blocks
        for entry in state.entries.values():
            entry.depends = filter(lambda dep: dep in state.entries,
                                   entry.depends)

        stats = self.calc_stranding_feerate(bootstrap=False)
        if stats:
            stranding_feerate = stats['sfr']
            abovekn = stats['abovekn']
            belowkn = stats['belowkn']
        else:
            stranding_feerate = None
            abovekn = None
            belowkn = None

        blocktext = (
            'Block {} ({} bytes) by {}: {}/{} in mempool, '
            'SFR/akn/bkn: {}/{}/{}'.format(
                self.blockheight, self.blocksize, blockname,
                len(entries_inblock), len(blocktxids)-1,
                stranding_feerate, abovekn, belowkn))
        logger.info(blocktext)

        # As a measure of our node's connectivity, we want to note the
        # ratio below. If it is low, it means that our node is not being
        # informed of many transactions.
        if len(blocktxids) > 1:
            incl_ratio = len(entries_inblock) / (len(blocktxids)-1)
            if incl_ratio < 0.9:
                logger.warning("Only {}/{} in block {}.".format(
                               len(entries_inblock), len(blocktxids)-1,
                               self.blockheight))

        state.height += 1
Ejemplo n.º 55
0
    def find_confirmed_txouts(self, rpc, starting_height=2**32):
        """Find new confirmed transaction outputs"""

        # Detect reorgs first
        if self.known_blocks:
            while len(self.known_blocks) > starting_height \
                  or self.known_blocks[-1] != rpc.getblockhash(len(self.known_blocks)-1):

                reorged_block_hash = self.known_blocks.pop()

                # Top block hash not longer valid, remove it and all related txouts
                if reorged_block_hash in self.outpoints_by_block:
                    logging.info('Block %s no longer exists, removing %d transactions' %
                            (b2lx(reorged_block_hash), len(self.outpoints_by_block[reorged_block_hash])))
                    del self.outpoints_by_block[reorged_block_hash]

        # When initializing the wallet for the first time quickly scan until we
        # reach the seed birthday
        if not len(self.known_blocks):
            last_nTime = 0
            stride = 1000
            while last_nTime < self.seed_birthday:
                self.known_blocks.extend([b'\x00'*32] * stride)

                if len(self.known_blocks) >= rpc.getblockcount():
                    break

                last_block_hash = rpc.getblockhash(len(self.known_blocks))
                last_nTime = rpc.getblock(last_block_hash).nTime

            self.known_blocks = self.known_blocks[:-stride]


        # Get new blocks
        while len(self.known_blocks) <= rpc.getblockcount():
            new_block_hash = rpc.getblockhash(len(self.known_blocks))
            new_block = rpc.getblock(new_block_hash)

            num_found = self.scan_block(new_block)
            logging.info('New block %s at height %d; found %d txouts' %
                         (b2lx(new_block_hash), len(self.known_blocks), num_found))

            self.known_blocks.append(new_block_hash)
Ejemplo n.º 56
0
    def getrawtransaction(self, txid, *args, **kwargs):
        """
        Get parsed transaction.

        :type txid: bytes or str
        :rtype: dict
        """
        if isinstance(txid, bytes):
            txid = b2lx(txid)
        return self.transactions[txid]
Ejemplo n.º 57
0
 def recv_ix(self, msg):
     """ ix handler """
     txid = b2lx(msg.tx.GetHash())
     info("   IX: %s" % txid)
     if self._find_payment(msg, txid, "ix"):
         p = self.mempool[txid]["processed"]
         info(
             "    --> address match! %s received %s -- %s "
             % (p["addr"], float(p["value"] / 1e8), p["sale"] and "SALE!" or "")
         )
         if self.mempool[txid]["processed"]["sale"]:
             self._check_ix_threshold(txid)