xrpl-py icon indicating copy to clipboard operation
xrpl-py copied to clipboard

Easier way to get Check ID

Open mDuo13 opened this issue 3 years ago • 2 comments

After you submit a CheckCreate transaction, you need the ID of the resulting Check ledger object in order to cash or cancel it. However, getting a Check ID is currently kind of a pain.

There are two general approaches:

  1. After autofilling the transaction, calculate the ID using SHA-512Half of the relevant pieces.
  2. First, get the transaction's identifying hash, then look up the transaction's results with tx or something similar, then dig through the metadata to find the CreatedNode of type Check and pull its ID from the LedgerIndex field there.

The first approach requires more calculations but less network calls, so I think it's the better one. A helper function could go a long way to making that easier.

Either some kind of "Get Check ID" method that takes a CheckCreate transaction as an argument, or even a special method on the CheckCreate transaction model class, could handle all the hard bits without making the user work through them. This method would:

  1. Use the given CheckCreate transaction's TicketSequence (if present) or Sequence (otherwise), and raise an error if the transaction doesn't have either. (If the user is relying on autofilling to provide the sequence number, they'd have to call this "Get Check ID" method after autofilling.)
  2. Construct a binary buffer consisting of the relevant pieces in order (16-bit Check space key, 160-bit AccountID, 32-bit Sequence or TicketSequence)
  3. Calculate and return the SHA-512Half hash of the buffer, as a hexadecimal string.

Test Case

Take the following CheckCreate transaction:

{
    "Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
    "Destination": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
    "DestinationTag": 13,
    "Fee": "10",
    "Flags": 2147483648,
    "LastLedgerSequence": 61965654,
    "SendMax": {
      "currency": "USD",
      "issuer": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
      "value": "10"
    },
    "Sequence": 384,
    "TransactionType": "CheckCreate"
}

The correct Check ID is C4A46CCD8F096E994C4B0DEAB6CE98E722FC17D7944C28B95127C2659C47CBEB.

Related Work

https://github.com/XRPLF/xrpl.js/issues/876

Payment Channels have the same challenge, by the way. Might be good to kill two birds with one stone and do those the same way.

mDuo13 avatar Feb 16 '22 19:02 mDuo13

This is a problem that I encountered when working with Checks too.

One solution with your ideas from above would be:

Use a GetChannelID like the PaymentChannels channel_authorize methods

This way, use the Sequence of the Check and the Sender's Account as parameters and let the method return the CheckID.

Add an Owner field to the Checks like in Escrows.

Instead of adding the CheckId as a single field, you could add an Owner field to the CheckCash/Cancel methods + the Check Sequence and let the CheckCash/Cancel method calculate the ChannelId when creating the transaction. That would mean that the Account cashing/canceling a check would not go through the trouble of finding the ChannelID , but instead use the Owner and Sequence field to auto-create the ChannelID.

I'm not entirely convinced of my answer now, but I believe some improvements could be made using the ideas from above.

justTil avatar Mar 23 '22 13:03 justTil

Hi, Can we redesign the CheckCreate transaction so that it returns the appropriate Check ID in the rippled codebase? This is an issue faced by all the client libraries. Repeated downstream implementations could be error-prone, hence a single source of truth in rippled would be helpful.

Assuming that a client is willing to wait for sufficient time, can we not return the CheckID as a response in the CheckCreate transaction ? (and similarly for the other ledger object types) ?

ckeshava avatar Jan 22 '24 23:01 ckeshava