예제 #1
0
def slave_tx_generate(ctx, src, master, number_of_slaves, access_type, fee, pk,
                      ots_key_index):
    """
    Generates Slave Transaction for the wallet
    """
    try:
        _, src_xmss = _select_wallet(ctx, src)

        ots_key_index = validate_ots_index(ots_key_index, src_xmss)
        src_xmss.set_ots_index(ots_key_index)

        if src_xmss:
            address_src_pk = src_xmss.pk
        else:
            address_src_pk = pk.encode()

        master_addr = None
        if master:
            master_addr = parse_qaddress(master)
        fee_shor = _quanta_to_shor(fee)
    except Exception as e:
        click.echo("Error validating arguments: {}".format(e))
        quit(1)

    slave_xmss = []
    slave_pks = []
    access_types = []
    slave_xmss_seed = []
    if number_of_slaves > 100:
        click.echo("Error: Max Limit for the number of slaves is 100")
        quit(1)

    for i in range(number_of_slaves):
        print("Generating Slave #" + str(i + 1))
        xmss = XMSS.from_height(config.dev.xmss_tree_height)
        slave_xmss.append(xmss)
        slave_xmss_seed.append(xmss.extended_seed)
        slave_pks.append(xmss.pk)
        access_types.append(access_type)
        print("Successfully Generated Slave %s/%s" %
              (str(i + 1), number_of_slaves))

    try:
        tx = SlaveTransaction.create(slave_pks=slave_pks,
                                     access_types=access_types,
                                     fee=fee_shor,
                                     xmss_pk=address_src_pk,
                                     master_addr=master_addr)
        tx.sign(src_xmss)
        with open('slaves.json', 'w') as f:
            json.dump(
                [bin2hstr(src_xmss.address), slave_xmss_seed,
                 tx.to_json()], f)
        click.echo('Successfully created slaves.json')
        click.echo(
            'Move slaves.json file from current directory to the mining node inside ~/.qrl/'
        )
    except Exception as e:
        click.echo("Unhandled error: {}".format(str(e)))
        quit(1)
예제 #2
0
def slave_tx_generate(ctx, src, addr_from, number_of_slaves, access_type, fee, pk, otsidx):
    """
    Generates Slave Transaction for the wallet
    """
    try:
        address_src, src_xmss = _select_wallet(ctx, src)
        src_xmss.set_ots_index(otsidx)
        if len(addr_from.strip()) == 0:
            addr_from = address_src
        if src_xmss:
            address_src_pk = src_xmss.pk
        else:
            address_src_pk = pk.encode()

        fee_shor = int(fee * 1.e9)
    except Exception as e:
        click.echo("Error validating arguments")
        quit(1)

    slave_xmss = []
    slave_pks = []
    access_types = []
    slave_xmss_seed = []
    if number_of_slaves > 100:
        click.echo("Error: Max Limit for the number of slaves is 100")
        quit(1)

    for i in range(number_of_slaves):
        print("Generating Slave #" + str(i + 1))
        xmss = XMSS.from_height(config.dev.xmss_tree_height)
        slave_xmss.append(xmss)
        slave_xmss_seed.append(xmss.extended_seed)
        slave_pks.append(xmss.pk)
        access_types.append(access_type)
        print("Successfully Generated Slave %s/%s" % (str(i + 1), number_of_slaves))

    channel = grpc.insecure_channel(ctx.obj.node_public_address)
    stub = qrl_pb2_grpc.PublicAPIStub(channel)
    # FIXME: This could be problematic. Check
    slaveTxnReq = qrl_pb2.SlaveTxnReq(address_from=addr_from,
                                      slave_pks=slave_pks,
                                      access_types=access_types,
                                      fee=fee_shor,
                                      xmss_pk=address_src_pk, )

    try:
        slaveTxnResp = stub.GetSlaveTxn(slaveTxnReq, timeout=5)
        tx = Transaction.from_pbdata(slaveTxnResp.transaction_unsigned)
        tx.sign(src_xmss)
        with open('slaves.json', 'w') as f:
            json.dump([bin2hstr(src_xmss.address), slave_xmss_seed, tx.to_json()], f)
        click.echo('Successfully created slaves.json')
        click.echo('Move slaves.json file from current directory to the mining node inside ~/.qrl/')
    except grpc.RpcError as e:
        click.echo(e.details())
        quit(1)
    except Exception as e:
        click.echo("Unhandled error: {}".format(str(e)))
        quit(1)
예제 #3
0
    def add_new_address(self, height, hash_function="shake128"):
        if self.encrypted or self.encrypted_partially:
            raise WalletEncryptionError("Please decrypt all addresses in this wallet before adding a new address!")

        tmp_xmss = XMSS.from_height(height, hash_function)

        self.append_xmss(tmp_xmss)
        return tmp_xmss
예제 #4
0
    def add_slave(self, index, height, number_of_slaves=1, passphrase: str=None, hash_function="shake128", force=False):
        if not force:
            if self.encrypted or self.encrypted_partially:
                raise WalletEncryptionError("Please decrypt all addresses in this wallet before adding a new address!")

        slaves_xmss = []

        for i in range(number_of_slaves):
            tmp_xmss = XMSS.from_height(height, hash_function)
            if i == number_of_slaves - 1:
                tmp_xmss.set_ots_index(UNRESERVED_OTS_INDEX_START)  # Start from unreserved ots index
            slaves_xmss.append(tmp_xmss)

        self.append_slave(slaves_xmss, passphrase, index)
        return slaves_xmss
예제 #5
0
    def get_new_address(signature_tree_height=config.dev.xmss_tree_height,
                        seed=None) -> AddressBundle:
        """
        Get a new wallet address
        The address format is a list of two items [address, data structure from random_mss call]
        :param signature_tree_height:
        :param address_type:
        :param seed:
        :return: a wallet address
        """
        # FIXME: This should be always using the extended seed instead
        if seed and signature_tree_height:
            xmss = XMSS(XmssFast(seed, signature_tree_height))
        elif seed:
            xmss = XMSS.from_extended_seed(seed)
        else:
            xmss = XMSS.from_height(signature_tree_height)

        return AddressBundle(bin2hstr(xmss.address).encode(), xmss)
예제 #6
0
def get_mining_slave_addresses(args):
    slaves_filename = os.path.join(config.user.wallet_dir,
                                   config.user.slaves_filename)

    if args.randomizeSlaveXMSS:
        xmss = XMSS.from_height(config.dev.slave_xmss_height)
        slaves = [bin2hstr(xmss.address), [xmss.extended_seed], None]
        write_slaves(slaves_filename, slaves)

    if not os.path.isfile(slaves_filename):
        generate_slave_from_input(slaves_filename)

    slaves = None
    try:
        slaves = read_slaves(slaves_filename)
    except KeyboardInterrupt:
        quit(1)
    except Exception as e:
        logger.error('Exception %s', e)
        quit(1)

    return slaves
예제 #7
0
파일: Wallet.py 프로젝트: som-dev/QRL
 def add_new_address(self, height):
     tmp_xmss = XMSS.from_height(height)
     self.append_xmss(tmp_xmss)
     return tmp_xmss
예제 #8
0
파일: helper.py 프로젝트: som-dev/QRL
def get_random_xmss(xmss_height=6) -> XMSS:
    return XMSS.from_height(xmss_height)
예제 #9
0
파일: test_xmss.py 프로젝트: zeta1999/QRL
 def test_from_height_custom_hash(self):
     xmss_height = 4
     xmss = XMSS.from_height(xmss_height, "shake128")
     self.assertEqual('shake128', xmss.hash_function)
예제 #10
0
    def create_block(self, last_block, mining_nonce, tx_pool, signing_xmss,
                     master_address) -> Optional[Block]:
        # TODO: Persistence will move to rocksdb
        # FIXME: Difference between this and create block?????????????

        # FIXME: Break encapsulation
        if not self._dummy_xmss:
            self._dummy_xmss = XMSS.from_height(signing_xmss.height)

        dummy_block = Block.create(block_number=last_block.block_number + 1,
                                   prevblock_headerhash=last_block.headerhash,
                                   transactions=[],
                                   signing_xmss=self._dummy_xmss,
                                   master_address=master_address,
                                   nonce=0)
        dummy_block.set_mining_nonce(mining_nonce)

        t_pool2 = copy.deepcopy(tx_pool.transaction_pool)
        del tx_pool.transaction_pool[:]
        ######

        # recreate the transaction pool as in the tx_hash_list, ordered by txhash..
        total_txn = len(t_pool2)
        txnum = 0
        addresses_set = set()
        while txnum < total_txn:
            tx = t_pool2[txnum]
            tx.set_effected_address(addresses_set)
            txnum += 1

        addresses_state = dict()
        for address in addresses_set:
            addresses_state[address] = self.state.get_address(address)

        block_size = dummy_block.size
        block_size_limit = self.state.get_block_size_limit(last_block)
        txnum = 0
        while txnum < total_txn:
            tx = t_pool2[txnum]
            # Skip Transactions for later, which doesn't fit into block
            if block_size + tx.size + config.dev.tx_extra_overhead > block_size_limit:
                txnum += 1
                continue

            addr_from_pk_state = addresses_state[tx.addr_from]
            addr_from_pk = Transaction.get_slave(tx)
            if addr_from_pk:
                addr_from_pk_state = addresses_state[addr_from_pk]

            if addr_from_pk_state.ots_key_reuse(tx.ots_key):
                del t_pool2[txnum]
                total_txn -= 1
                continue

            if isinstance(tx, TransferTransaction):
                if addresses_state[
                        tx.addr_from].balance < tx.total_amount + tx.fee:
                    logger.warning('%s %s exceeds balance, invalid tx', tx,
                                   tx.addr_from)
                    logger.warning('type: %s', tx.type)
                    logger.warning(
                        'Buffer State Balance: %s  Transfer Amount %s',
                        addresses_state[tx.addr_from].balance, tx.total_amount)
                    del t_pool2[txnum]
                    total_txn -= 1
                    continue

            if isinstance(tx, MessageTransaction):
                if addresses_state[tx.addr_from].balance < tx.fee:
                    logger.warning('%s %s exceeds balance, invalid message tx',
                                   tx, tx.addr_from)
                    logger.warning('type: %s', tx.type)
                    logger.warning('Buffer State Balance: %s  Free %s',
                                   addresses_state[tx.addr_from].balance,
                                   tx.fee)
                    total_txn -= 1
                    continue

            if isinstance(tx, TokenTransaction):
                if addresses_state[tx.addr_from].balance < tx.fee:
                    logger.warning('%s %s exceeds balance, invalid tx', tx,
                                   tx.addr_from)
                    logger.warning('type: %s', tx.type)
                    logger.warning('Buffer State Balance: %s  Fee %s',
                                   addresses_state[tx.addr_from].balance,
                                   tx.fee)
                    del t_pool2[txnum]
                    total_txn -= 1
                    continue

            if isinstance(tx, TransferTokenTransaction):
                if addresses_state[tx.addr_from].balance < tx.fee:
                    logger.warning('%s %s exceeds balance, invalid tx', tx,
                                   tx.addr_from)
                    logger.warning('type: %s', tx.type)
                    logger.warning(
                        'Buffer State Balance: %s  Transfer Amount %s',
                        addresses_state[tx.addr_from].balance, tx.fee)
                    del t_pool2[txnum]
                    total_txn -= 1
                    continue

                if bin2hstr(tx.token_txhash).encode() not in addresses_state[
                        tx.addr_from].tokens:
                    logger.warning(
                        '%s doesnt own any token with token_txnhash %s',
                        tx.addr_from,
                        bin2hstr(tx.token_txhash).encode())
                    del t_pool2[txnum]
                    total_txn -= 1
                    continue

                if addresses_state[tx.addr_from].tokens[bin2hstr(
                        tx.token_txhash).encode()] < tx.total_amount:
                    logger.warning(
                        'Token Transfer amount exceeds available token')
                    logger.warning('Token Txhash %s',
                                   bin2hstr(tx.token_txhash).encode())
                    logger.warning(
                        'Available Token Amount %s',
                        addresses_state[tx.addr_from].tokens[bin2hstr(
                            tx.token_txhash).encode()])
                    logger.warning('Transaction Amount %s', tx.total_amount)
                    del t_pool2[txnum]
                    total_txn -= 1
                    continue

            if isinstance(tx, LatticePublicKey):
                if addresses_state[tx.addr_from].balance < tx.fee:
                    logger.warning(
                        'Lattice TXN %s %s exceeds balance, invalid tx', tx,
                        tx.addr_from)
                    logger.warning('type: %s', tx.type)
                    logger.warning(
                        'Buffer State Balance: %s  Transfer Amount %s',
                        addresses_state[tx.addr_from].balance, tx.fee)
                    del t_pool2[txnum]
                    total_txn -= 1
                    continue

            if isinstance(tx, SlaveTransaction):
                if addresses_state[tx.addr_from].balance < tx.fee:
                    logger.warning(
                        'Slave TXN %s %s exceeds balance, invalid tx', tx,
                        tx.addr_from)
                    logger.warning('type: %s', tx.type)
                    logger.warning(
                        'Buffer State Balance: %s  Transfer Amount %s',
                        addresses_state[tx.addr_from].balance, tx.fee)
                    del t_pool2[txnum]
                    total_txn -= 1
                    continue

            tx.apply_on_state(addresses_state)

            tx_pool.add_tx_to_pool(tx)
            tx._data.nonce = addresses_state[tx.addr_from].nonce
            txnum += 1
            block_size += tx.size + config.dev.tx_extra_overhead

        coinbase_nonce = self.state.get_address(signing_xmss.address).nonce
        if signing_xmss.address in addresses_state:
            coinbase_nonce = addresses_state[signing_xmss.address].nonce + 1

        block = Block.create(block_number=last_block.block_number + 1,
                             prevblock_headerhash=last_block.headerhash,
                             transactions=t_pool2,
                             signing_xmss=signing_xmss,
                             master_address=master_address,
                             nonce=coinbase_nonce)

        return block