theQRL / QRL

Quantum Resistant Ledger
https://theqrl.org/
MIT License
414 stars 108 forks source link

message_data not optional parameter for QRL CLI bundled with node #1733

Open jackalyst opened 3 years ago

jackalyst commented 3 years ago

Describe the bug

When sending a transaction with the QRL CLI bundled with the node, message_data isn't an optional field.

To Reproduce

Initiate a transfer without the message_data field.

$ qrl tx_transfer --src 0 --dsts Q010600cea6ad85212aaa60d424413975c6c936f0b687382a6d947503491368310de4ed4fe33ec7 --amounts 0.05 --fee 0 --ots_key_index 4

results in a prompt for message data

Message data: |

After filling out the prompt, the transaction is successfully executed.

Expected behavior

Returned transaction information indicating a successful transfer without indicating message_data

Desktop (please complete the following information):

successor1 commented 3 years ago

Click documentation https://click.palletsprojects.com/en/8.0.x/options/

prompt_required=False

If the option has prompt enabled, then setting prompt_required=False tells Click to only show the prompt if the option’s flag is given, instead of if the option is not provided at all.

$ hello
Hello Default!
$ hello --name Value
Hello Value!
$ hello --name
Name [Default]: 
@qrl.command(name='tx_transfer')
@click.option('--src', type=str, default='', prompt=True, help='signer QRL address')
@click.option('--master', type=str, default='', help='master QRL address')
@click.option('--dsts', type=str, prompt=True, help='List of destination addresses')
@click.option('--amounts', type=str, prompt=True, help='List of amounts to transfer (Quanta)')
@click.option('--message_data', type=str, default=None, help='Message (Optional)')
@click.option('--fee', type=Decimal, default=0.0, prompt=True, help='fee in Quanta')
@click.option('--ots_key_index', default=1, help='OTS key Index (1..XMSS num signatures)')
@click.pass_context
def tx_transfer(ctx, src, master, dsts, amounts, message_data, fee, ots_key_index):
    """
    Transfer coins from src to dsts
    """
    address_src_pk = None
    master_addr = None

    addresses_dst = []
    shor_amounts = []
    fee_shor = []

    signing_object = None
    if message_data == None:
        pass
    else:
        message_data = message_data.encode()

    try:
        # Retrieve signing object
        selected_wallet = _select_wallet(ctx, src)
        if selected_wallet is None or len(selected_wallet) != 2:
            click.echo("A wallet was not found")
            quit(1)

        _, src_xmss = selected_wallet

        if not src_xmss:
            click.echo("A local wallet is required to sign the transaction")
            quit(1)

        address_src_pk = src_xmss.pk

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

        signing_object = src_xmss

        # Get and validate other inputs
        if master:
            master_addr = parse_qaddress(master)
        addresses_dst, shor_amounts = _parse_dsts_amounts(dsts, amounts, check_multi_sig_address=True)
        fee_shor = _quanta_to_shor(fee)
    except Exception as e:
        click.echo("Error validating arguments: {}".format(e))
        quit(1)

    try:
        # Create transaction
        tx = TransferTransaction.create(addrs_to=addresses_dst,
                                        amounts=shor_amounts,
                                        message_data=message_data,
                                        fee=fee_shor,
                                        xmss_pk=address_src_pk,
                                        master_addr=master_addr)

        # Sign transaction
        tx.sign(signing_object)

        # Print result
        txjson = tx_unbase64(tx.to_json())
        print(txjson)

        if not tx.validate():
            print("It was not possible to validate the signature")
            quit(1)

        print("\nTransaction Blob (signed): \n")
        txblob = tx.pbdata.SerializeToString()
        txblobhex = hexlify(txblob).decode()
        print(txblobhex)

        # Push transaction
        print("Sending to a QRL Node...")
        stub = ctx.obj.get_stub_public_api()
        push_transaction_req = qrl_pb2.PushTransactionReq(transaction_signed=tx.pbdata)
        push_transaction_resp = stub.PushTransaction(push_transaction_req, timeout=CONNECTION_TIMEOUT)

        # Print result
        print(push_transaction_resp)
    except Exception as e:
        print("Error {}".format(str(e)))

I tried the attempt above, however, i get this error.

Traceback (most recent call last):
  File "cli.py", line 699, in <module>
    def tx_transfer(ctx, src, master, dsts, amounts, message_data, fee, ots_key_index):
  File "/home/alpine/.local/lib/python3.8/site-packages/click/decorators.py", line 192, in decorator
    _param_memo(f, OptionClass(param_decls, **option_attrs))
  File "/home/alpine/.local/lib/python3.8/site-packages/click/core.py", line 1714, in __init__
    Parameter.__init__(self, param_decls, type=type, **attrs)
TypeError: __init__() got an unexpected keyword argument 'prompt_required''