コード例 #1
0
def token_list(ctx, owner):
    """
    Fetch the list of tokens owned by an address.
    """
    try:
        owner_address = parse_qaddress(owner)
    except Exception as e:
        click.echo("Error validating arguments: {}".format(e))
        quit(1)

    try:
        stub = ctx.obj.get_stub_public_api()
        address_state_req = qrl_pb2.GetAddressStateReq(address=owner_address)
        address_state_resp = stub.GetAddressState(address_state_req,
                                                  timeout=CONNECTION_TIMEOUT)

        for token_hash in address_state_resp.state.tokens:
            get_object_req = qrl_pb2.GetObjectReq(
                query=bytes(hstr2bin(token_hash)))
            get_object_resp = stub.GetObject(get_object_req,
                                             timeout=CONNECTION_TIMEOUT)

            click.echo('Hash: %s' % (token_hash, ))
            click.echo(
                'Symbol: %s' %
                (get_object_resp.transaction.tx.token.symbol.decode(), ))
            click.echo('Name: %s' %
                       (get_object_resp.transaction.tx.token.name.decode(), ))
            click.echo('Balance: %s' %
                       (address_state_resp.state.tokens[token_hash], ))

    except Exception as e:
        print("Error {}".format(str(e)))
コード例 #2
0
ファイル: qrl-query.py プロジェクト: som-dev/qrl-tools
def query_txn(qrl_client, txn):
    #request = qrl_pb2.GetTransactionReq(tx_hash=bytes.fromhex(txn))
    #response = qrl_client.GetTransaction(request)
    request = qrl_pb2.GetObjectReq(query=bytes.fromhex(txn))
    response = qrl_client.GetObject(request)
    log_msg('', response)
    if response.found and response.transaction.tx.HasField('multi_sig_spend'):
        vote_req = qrl_pb2.GetVoteStatsReq(
            multi_sig_spend_tx_hash=response.transaction.tx.transaction_hash)
        vote_resp = qrl_client.GetVoteStats(vote_req)
        log_msg('', vote_resp)
コード例 #3
0
ファイル: qrl-query.py プロジェクト: som-dev/qrl-tools
def query_addr(qrl_client, addr):
    request = qrl_pb2.GetObjectReq(query=bytes.fromhex(addr[1:]))
    response = qrl_client.GetObject(request)
    log_msg('', response)
    if addr.startswith('Q1'):
        request = qrl_pb2.GetMultiSigAddressStateReq(
            address=bytes.fromhex(addr[1:]))
        response = qrl_client.GetMultiSigAddressState(request)
        log_msg('', response)
        request = qrl_pb2.GetMultiSigSpendTxsByAddressReq(
            address=bytes.fromhex(addr[1:]),
            item_per_page=8,
            page_number=1,
            filter_type=qrl_pb2.GetMultiSigSpendTxsByAddressReq.NONE)
        response = qrl_client.GetMultiSigSpendTxsByAddress(request)
        log_msg('', response)
    else:
        request = qrl_pb2.GetAddressStateReq(address=bytes.fromhex(addr[1:]))
        response = qrl_client.GetAddressState(request)
        log_msg('', response)
コード例 #4
0
def audit_regular_addr(qrl_client, addr):
    """ Validate the provided regular address """
    balance = 0
    tx_count = 0
    bad_tx_count = 0
    request_addr = qrl_pb2.GetAddressStateReq(address=bytes.fromhex(addr[1:]))
    response_addr = qrl_client.GetAddressState(request_addr)
    if not response_addr.HasField('state'):
        logging.error('could not find address {}'.format(addr))
        return balance, tx_count, bad_tx_count
    balance = response_addr.state.balance
    tx_count = len(response_addr.state.transaction_hashes)
    for txhash in response_addr.state.transaction_hashes:
        request_tx = qrl_pb2.GetObjectReq(query=bytes.fromhex(txhash.hex()))
        response_tx = qrl_client.GetObject(request_tx)
        if not response_tx.HasField('transaction'):
            bad_tx_count += 1
            logging.error('txhash {} for addr {} does not exist'.format(
                txhash, addr))
            continue
        tx = response_tx.transaction.tx
        if tx.HasField('transfer') or tx.HasField('multi_sig_spend'):
            tmptxhash = (tx.master_addr + to_bytes(tx.fee))
            if tx.HasField('transfer'):
                tmptxhash += (tx.transfer.message_data +
                              get_tx_hash(tx.transfer))
            if tx.HasField('multi_sig_spend'):
                tmptxhash += (
                    tx.multi_sig_spend.multi_sig_address +
                    to_bytes(tx.multi_sig_spend.expiry_block_number) +
                    get_tx_hash(tx.multi_sig_spend))
            data_hash = sha256(tmptxhash)
            signature = tx.signature
            public_key = tx.public_key
            if not XmssFast.verify(data_hash, signature, public_key):
                logging.info(
                    'txhash {} for addr {} failed XmssFast verification'.
                    format(txhash, addr))
    return balance, tx_count, bad_tx_count
コード例 #5
0
    def test_getObject(self):
        SOME_ODD_HASH = sha256(b'this should not be found')
        SOME_ADDR1 = b'Q' + sha256(b'address1')
        SOME_ADDR2 = b'Q' + sha256(b'address2')

        db_state = Mock(spec=State)

        p2p_factory = Mock(spec=P2PFactory)
        buffered_chain = Mock(spec=BufferedChain)
        buffered_chain.tx_pool = Mock()
        buffered_chain.tx_pool.transaction_pool = []

        qrlnode = QRLNode(db_state)
        qrlnode.set_p2pfactory(p2p_factory)
        qrlnode.set_chain(buffered_chain)
        qrlnode._peer_addresses = ['127.0.0.1', '192.168.1.1']

        service = PublicAPIService(qrlnode)

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        context.set_details.assert_not_called()
        self.assertFalse(response.found)

        # Find an address
        db_state.get_address = MagicMock(return_value=AddressState.create(
            address=SOME_ADDR1,
            nonce=25,
            balance=10,
            pubhashes=[sha256(b'a'), sha256(b'b')],
            tokens=dict()))
        db_state.get_address_tx_hashes = MagicMock(
            return_value=[sha256(b'0'), sha256(b'1')])

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        request.query = SOME_ODD_HASH
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertFalse(response.found)

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        request.query = SOME_ADDR1
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertTrue(response.found)
        self.assertIsNotNone(response.address_state)

        self.assertEqual(SOME_ADDR1, response.address_state.address)
        self.assertEqual(25, response.address_state.nonce)
        self.assertEqual(10, response.address_state.balance)
        self.assertEqual([sha256(b'a'), sha256(b'b')],
                         response.address_state.pubhashes)
        self.assertEqual([sha256(b'0'), sha256(b'1')],
                         response.address_state.transaction_hashes)

        # Find a transaction
        db_state.address_used = MagicMock(return_value=False)
        tx1 = TransferTransaction.create(addr_from=SOME_ADDR1,
                                         addr_to=SOME_ADDR2,
                                         amount=125,
                                         fee=19,
                                         xmss_pk=sha256(b'pk'),
                                         xmss_ots_index=13)

        buffered_chain.tx_pool.transaction_pool = [tx1]

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        request.query = tx1.txhash
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertTrue(response.found)
        self.assertIsNotNone(response.transaction)
        self.assertEqual(qrl_pb2.Transaction.TRANSFER,
                         response.transaction.type)
        self.assertEqual(SOME_ADDR1, response.transaction.addr_from)
        self.assertEqual(sha256(b'pk'), response.transaction.public_key)
        self.assertEqual(tx1.txhash, response.transaction.transaction_hash)
        self.assertEqual(13, response.transaction.ots_key)
        self.assertEqual(b'', response.transaction.signature)

        self.assertEqual(SOME_ADDR2, response.transaction.transfer.addr_to)
        self.assertEqual(125, response.transaction.transfer.amount)
        self.assertEqual(19, response.transaction.transfer.fee)

        # Find a block
        buffered_chain.get_block = MagicMock(return_value=Block.create(
            staking_address=qrladdress('staking_addr'),
            block_number=1,
            reveal_hash=sha256(b'reveal'),
            prevblock_headerhash=sha256(b'reveal'),
            transactions=[],
            duplicate_transactions=OrderedDict(),
            vote=VoteMetadata(),
            signing_xmss=get_alice_xmss(),
            nonce=1))

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        request.query = bytes(str2bin('1'))
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertTrue(response.found)
        self.assertIsNotNone(response.block)
        self.assertEqual(1, response.block.header.block_number)
コード例 #6
0
    def test_getObject(self):
        SOME_ODD_HASH = sha256(b'this should not be found')

        db_state = Mock(spec=State)
        db_state.get_tx_metadata = MagicMock(return_value=None)
        db_state.get_block = MagicMock(return_value=None)

        p2p_factory = Mock(spec=P2PFactory)
        p2p_factory.pow = Mock(spec=POW)

        chain_manager = ChainManager(db_state)

        qrlnode = QRLNode(mining_address=b'')
        qrlnode.set_chain_manager(chain_manager)
        qrlnode._p2pfactory = p2p_factory
        qrlnode._pow = p2p_factory.pow
        qrlnode._peer_addresses = ['127.0.0.1', '192.168.1.1']

        service = PublicAPIService(qrlnode)

        # First try an empty request
        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        context.set_details.assert_not_called()
        self.assertFalse(response.found)

        # Some odd address
        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        request.query = SOME_ODD_HASH
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertFalse(response.found)

        # Find an address
        bob_xmss = get_bob_xmss()
        addr1_state = AddressState.create(address=bob_xmss.address,
                                          nonce=25,
                                          balance=10,
                                          ots_bitfield=[b'\x00'] *
                                          config.dev.ots_bitfield_size,
                                          tokens=dict(),
                                          slave_pks_access_type=dict(),
                                          ots_counter=0)
        addr1_state.transaction_hashes.append(sha256(b'0'))
        addr1_state.transaction_hashes.append(sha256(b'1'))

        db_state.get_address_state = MagicMock(return_value=addr1_state)

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        request.query = bob_xmss.address
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertTrue(response.found)
        self.assertIsNotNone(response.address_state)

        self.assertEqual(bob_xmss.address, response.address_state.address)
        self.assertEqual(25, response.address_state.nonce)
        self.assertEqual(10, response.address_state.balance)
        self.assertEqual([sha256(b'0'), sha256(b'1')],
                         response.address_state.transaction_hashes)

        # Find a transaction
        alice_xmss = get_alice_xmss()
        db_state.address_used = MagicMock(return_value=False)
        tx1 = TransferTransaction.create(addrs_to=[bob_xmss.address],
                                         amounts=[125],
                                         fee=19,
                                         xmss_pk=bob_xmss.pk,
                                         master_addr=alice_xmss.address)

        chain_manager.tx_pool.transaction_pool = [(0, TransactionInfo(tx1, 0))]

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        request.query = tx1.txhash
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertTrue(response.found)
        self.assertIsNotNone(response.transaction)
        self.assertEqual('transfer',
                         response.transaction.tx.WhichOneof('transactionType'))
        self.assertEqual(alice_xmss.address,
                         response.transaction.tx.master_addr)
        self.assertEqual(bob_xmss.pk, response.transaction.tx.public_key)
        self.assertEqual(tx1.txhash, response.transaction.tx.transaction_hash)
        self.assertEqual(b'', response.transaction.tx.signature)

        self.assertEqual(bob_xmss.address,
                         response.transaction.tx.transfer.addrs_to[0])
        self.assertEqual(125, response.transaction.tx.transfer.amounts[0])
        self.assertEqual(19, response.transaction.tx.fee)

        alice_xmss = get_alice_xmss()
        # Find a block
        db_state.get_block_by_number = MagicMock(
            return_value=Block.create(block_number=1,
                                      prev_headerhash=sha256(b'reveal'),
                                      prev_timestamp=10,
                                      transactions=[],
                                      miner_address=alice_xmss.address))

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetObjectReq()
        request.query = bytes(str2bin('1'))
        response = service.GetObject(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertTrue(response.found)
        self.assertIsNotNone(response.block_extended)
        self.assertEqual(1, response.block_extended.header.block_number)
コード例 #7
0
def audit_chain(qrl_client, dbg_addr):
    """
    Request and store each blockself.
    Iterate thru each block, replaying each transaction to recreate address balances.
    Query each address comparing the reported vs calculated balances.
    """
    total_blocks = 0
    block_store = dict()
    balances_store = dict()
    transaction_store = dict()
    if dbg_addr is not None:
        dbg_addr = bytes.fromhex(dbg_addr[1:]).hex()
    # load the blocks
    while True:
        request = qrl_pb2.GetObjectReq(query=str(total_blocks).encode(
            encoding='ascii'))
        response = qrl_client.GetObject(request)
        if not response.HasField('block_extended'):
            # we reached the end of the chain
            break
        # get and store block
        block = response.block_extended
        block_store[total_blocks] = block
        total_blocks += 1

    logging.info('loaded up to block number {}'.format(total_blocks))

    # re-create balances by replaying each block
    for block_num in range(0, total_blocks):
        block = block_store[block_num]

        # store transactions in each block
        for txn in range(0, len(block.extended_transactions)):
            txhash = block.extended_transactions[txn].tx.transaction_hash.hex()
            transaction_store[txhash] = block.extended_transactions[txn]

        # handle coinbase
        address = block.extended_transactions[0].tx.coinbase.addr_to.hex()
        amount = block.extended_transactions[0].tx.coinbase.amount
        if not address in balances_store:
            balances_store[address] = 0
        balances_store[address] += amount
        if dbg_addr in [address]:
            print('coinbase amnt {} -> Q{} via blk {}'.format(
                amount, address, block_num))

        # handle all other transactions outside of coinbase
        for txn in range(1, len(block.extended_transactions)):
            tx = block.extended_transactions[txn].tx
            addr_from = block.extended_transactions[txn].addr_from.hex()
            tx_hash = tx.transaction_hash.hex()
            if tx.fee > 0:
                balances_store[addr_from] -= tx.fee
                if dbg_addr in [addr_from]:
                    print('fee amnt {} Q{} -> Q{} via tx {}'.format(
                        tx.fee, addr_from, address, tx_hash))
            if tx.HasField('transfer'):
                update_balances(balances_store, addr_from, tx.transfer,
                                dbg_addr, tx_hash)
            if tx.HasField('multi_sig_spend'):
                if has_multi_sig_spend_executed(qrl_client,
                                                tx.transaction_hash):
                    addr_from = tx.multi_sig_spend.multi_sig_address.hex()
                    update_balances(balances_store, addr_from,
                                    tx.multi_sig_spend, dbg_addr, tx_hash)

    logging.info('loaded {} addresses and {} transactions'.format(
        len(balances_store), len(transaction_store)))

    # audit each block, checking the block header and building a list
    for block_num in range(0, total_blocks):
        block = block_store[block_num]
        if block_num > 0:
            blockPrev = block_store[block_num - 1]
            if block.header.hash_header_prev != blockPrev.header.hash_header:
                logging.error('prev block error at {}'.format(block_num))
            if block.header.timestamp_seconds < blockPrev.header.timestamp_seconds:
                logging.error('timestamp error at {}'.format(block_num))
        if block.header.block_number != block_num:
            logging.error('block num error at {}'.format(block_num))
        hashedtransactions = [
            block.extended_transactions[0].tx.transaction_hash
        ]
        reward = block.header.reward_block
        for txn in range(1, len(block.extended_transactions)):
            reward += block.extended_transactions[txn].tx.fee
            hashedtransactions.append(
                block.extended_transactions[txn].tx.transaction_hash)
        if block.extended_transactions[0].tx.coinbase.amount != reward:
            logging.error('coinbase error at {}'.format(block_num))
        if block.header.reward_fee + block.header.reward_block != reward:
            logging.error('reward error at {}'.format(block_num))
        merkle_root = merkle_tx_hash(hashedtransactions)
        if block.header.merkle_root != merkle_root:
            logging.error('merkle_root error at {}'.format(block_num))

    for addr in balances_store:
        try:
            balance = audit_address(qrl_client, 'Q' + addr, False)
            if balance != balances_store[addr]:
                logging.error('balance for {} does not match'.format('Q' +
                                                                     addr))
                logging.error('node-reported balance: {}'.format(balance))
                logging.error('calculated balance:    {}'.format(
                    balances_store[addr]))
        except:
            logging.error('could not query addr {}'.format('Q' + addr))
            raise
コード例 #8
0
ファイル: qrl-query.py プロジェクト: som-dev/qrl-tools
def query_block(qrl_client, block):
    #request = qrl_pb2.GetBlockByNumberReq(block_number=block)
    #response = qrl_client.GetBlockByNumber(request)
    request = qrl_pb2.GetObjectReq(query=str(block).encode(encoding='ascii'))
    response = qrl_client.GetObject(request)
    log_msg('', response)
コード例 #9
0
args = parser.parse_args()

addressA = '{}:{}'.format(args.hostA, args.portA)
channelA = grpc.insecure_channel(addressA)
qrlClientA = qrl_pb2_grpc.PublicAPIStub(channelA)
logging.info('Connected to {}'.format(addressA))

addressB = '{}:{}'.format(args.hostB, args.portB)
channelB = grpc.insecure_channel(addressB)
qrlClientB = qrl_pb2_grpc.PublicAPIStub(channelB)
logging.info('Connected to {}'.format(addressB))

# load the blocks for addressA & addressB
start = time.monotonic()
for blockNum in range(int(args.startBlock), int(args.endBlock) + 1):
    request = qrl_pb2.GetObjectReq(query=str(blockNum).encode(
        encoding='ascii'))
    responseA = qrlClientA.GetObject(request)
    responseB = qrlClientB.GetObject(request)
    if not responseA.HasField('block_extended') or not responseB.HasField(
            'block_extended'):
        # we reached the end of the chain on either A or B
        break

    # update status
    if blockNum > 0 and blockNum % 10000 == 0:
        logging.info('loaded up to {}'.format(blockNum))

    # compare the blocks
    blockA = responseA.block_extended
    blockB = responseB.block_extended
コード例 #10
0
    def test_getObject(self):
        SOME_ODD_HASH = sha256(b'this should not be found')

        with set_qrl_dir('no_data'):
            db_state = State()

            p2p_factory = Mock(spec=P2PFactory)
            p2p_factory.pow = Mock(spec=POW)

            chain_manager = ChainManager(db_state)

            qrlnode = QRLNode(mining_address=b'')
            qrlnode.set_chain_manager(chain_manager)
            qrlnode._p2pfactory = p2p_factory
            qrlnode._pow = p2p_factory.pow
            qrlnode._peer_addresses = ['127.0.0.1', '192.168.1.1']

            service = PublicAPIService(qrlnode)

            # First try an empty request
            context = Mock(spec=ServicerContext)
            request = qrl_pb2.GetObjectReq()
            response = service.GetObject(request=request, context=context)
            context.set_code.assert_not_called()
            context.set_details.assert_not_called()
            self.assertFalse(response.found)

            # Some odd address
            context = Mock(spec=ServicerContext)
            request = qrl_pb2.GetObjectReq()
            request.query = SOME_ODD_HASH
            response = service.GetObject(request=request, context=context)
            context.set_code.assert_not_called()
            self.assertFalse(response.found)

            # Find an address
            bob_xmss = get_bob_xmss()
            addr1_state = OptimizedAddressState.create(address=bob_xmss.address,
                                                       nonce=25,
                                                       balance=10,
                                                       ots_bitfield_used_page=0,
                                                       transaction_hash_count=0,
                                                       tokens_count=0,
                                                       lattice_pk_count=0,
                                                       slaves_count=0,
                                                       multi_sig_address_count=0)

            AddressState.put_address_state(db_state, addr1_state, None)

            context = Mock(spec=ServicerContext)
            request = qrl_pb2.GetObjectReq()
            request.query = bob_xmss.address
            response = service.GetObject(request=request, context=context)
            context.set_code.assert_not_called()
            self.assertTrue(response.found)
            self.assertIsNotNone(response.address_state)

            self.assertEqual(bob_xmss.address, response.address_state.address)
            self.assertEqual(25, response.address_state.nonce)
            self.assertEqual(10, response.address_state.balance)

            # Find a transaction
            alice_xmss = get_alice_xmss()
            db_state.address_used = MagicMock(return_value=False)
            tx1 = TransferTransaction.create(
                addrs_to=[bob_xmss.address],
                amounts=[125],
                message_data=None,
                fee=19,
                xmss_pk=bob_xmss.pk,
                master_addr=alice_xmss.address)

            chain_manager.tx_pool.transaction_pool = [(0, TransactionInfo(tx1, 0))]

            context = Mock(spec=ServicerContext)
            request = qrl_pb2.GetObjectReq()
            request.query = tx1.txhash
            response = service.GetObject(request=request, context=context)
            context.set_code.assert_not_called()
            self.assertTrue(response.found)
            self.assertIsNotNone(response.transaction)
            self.assertEqual('transfer', response.transaction.tx.WhichOneof('transactionType'))
            self.assertEqual(alice_xmss.address, response.transaction.tx.master_addr)
            self.assertEqual(bob_xmss.pk, response.transaction.tx.public_key)
            self.assertEqual(tx1.txhash, response.transaction.tx.transaction_hash)
            self.assertEqual(b'', response.transaction.tx.signature)

            self.assertEqual(bob_xmss.address, response.transaction.tx.transfer.addrs_to[0])
            self.assertEqual(125, response.transaction.tx.transfer.amounts[0])
            self.assertEqual(19, response.transaction.tx.fee)

            alice_xmss = get_alice_xmss()
            # Find a block
            block = Block.create(dev_config=config.dev,
                                 block_number=1,
                                 prev_headerhash=sha256(b'reveal'),
                                 prev_timestamp=10,
                                 transactions=[],
                                 miner_address=alice_xmss.address,
                                 seed_height=0,
                                 seed_hash=None)

            Block.put_block(db_state, block, None)
            Block.put_block_number_mapping(db_state,
                                           block.block_number,
                                           qrl_pb2.BlockNumberMapping(headerhash=block.headerhash),
                                           None)
            context = Mock(spec=ServicerContext)
            request = qrl_pb2.GetObjectReq()
            request.query = bytes(str2bin('1'))
            response = service.GetObject(request=request, context=context)
            context.set_code.assert_not_called()
            self.assertTrue(response.found)
            self.assertIsNotNone(response.block_extended)
            self.assertEqual(1, response.block_extended.header.block_number)