Coder Social home page Coder Social logo

Transactions sometimes fail and sometimes say they fail when they succeed - any idempotent way to resubmit manually? about xrpl.js HOT 8 CLOSED

xrplf avatar xrplf commented on May 24, 2024
Transactions sometimes fail and sometimes say they fail when they succeed - any idempotent way to resubmit manually?

from xrpl.js.

Comments (8)

wltsmrz avatar wltsmrz commented on May 24, 2024

Can I glean some id from this and check transaction status later?

A transaction might have more than one ID. If local signing is enabled, submission fails, fee changes, and transaction is resubmitted, there should be a new ID. All of the submitted transaction IDs are stored in transaction.submittedTxnIDs.

The tejLost event indicates that excessive ledgers have passed (currently we define this to be 8) before the validated transaction was received from the server where the transaction was submitted. You can listen for the lost event on a transaction, and your listener will be provided a ledger object.

transaction.once('lost', function(ledger) {
  console.log('Transaction lost, ' + (leder.ledger_index - transaction.submitIndex) + ' ledgers have passed during the submission cycle');
});

from xrpl.js.

Sam-Izdat avatar Sam-Izdat commented on May 24, 2024

Thank you, that makes things clearer. Is there any documentation on how to look up a transaction by its ID(s)? Any best practices on checking the transaction's current status?

from xrpl.js.

wltsmrz avatar wltsmrz commented on May 24, 2024

https://ripple.com/tools/api/#tx

remote.requestTx('id', console.log);

If you like, you can listen for ledger_closed events and query the server using transaction_entry with the current ledger index and iterating over transaction.submittedTxnIDs.

This is the way ripple-lib used to validate transactions, but it's switched to passive validation using the account transaction stream. Of course, it's not inconceivable that you will get a tejLost response despite a transaction's eventually succeeding. The tejLost event does not represent a final state; it just means that the transaction was not found in a reasonable amount of time.

from xrpl.js.

Sam-Izdat avatar Sam-Izdat commented on May 24, 2024

One other question. Since one transaction can produce multiple IDs, assuming transaction.submittedTxnIDs stores all of them, how can I parse the 'redundant' IDs that required re-submission (as with a higher fee) from those which actually represent the 'final' transaction?

For example, let's say I'm just going to send all submittedTxnIDs to Redis, by popping them off the array intermittently, and then iterate over that list in the data store at a later time to see which ones failed to go through.

Does request_tx(hash, function(err, res){ callback }) return anything in the res object to tell them apart?

from xrpl.js.

wltsmrz avatar wltsmrz commented on May 24, 2024

If you request_tx with a transaction that hasn't succeeded you'll receive "Transaction not found."

For now, if you needed to check which ID in submittedTxnIDs refers to the successful transaction (It will almost always be the zeroth index, but theoretically it could be any of them), you could either refer to result.transaction.hash (result being the response to submit, assuming it eventually succeeds) or use something like

var successfulID = transaction._submittedTxnIDs.filter(function(id) {
return remote.account(JR_ADDRESS)._transactionManager._cache.hasOwnProperty(id);
})[0];

Transactions received from the transaction stream are cached (in case of a server disconnect, etc.). I can't guarantee that the transaction cache will never be pruned in the future though.

from xrpl.js.

Sam-Izdat avatar Sam-Izdat commented on May 24, 2024

edit2 -

Apologies -- I just realized that submittedTxnIDs hangs off each separate transaction and not the remote. I'll have to rethink the following.


Sorry, I may be doing a really poor job explaining what I'm trying to accomplish. Thanks for bearing with me. I'll try to describe it a different way.

Let's say my node script submits several transactions:

  • transaction A - fails and is automatically resubmitted by ripple-lib for some reason (e.g. because of insufficient fee). The second time, it's successful (e.g. fee cushion).
  • transaction B -- fails with tejLost and for some odd reason truly never makes it to a ledger and is lost to the sands of time
  • transaction C reports tejLost but eventually does make it through

So, now the submittedTxnIDs array has:

  • two hashes for successful for transaction A
  • one hash for unsuccessful transaction B
  • one hash for successful transaction C

Is that right? I can check them all, say, ten or thirty minutes later with request_tx to determine their status, and file them away accordingly. (at least, I think the server finding a validated transaction on some ledger means it really went through)

But one of the transaction hashes for A (the first) is redundant. It failed, but then it succeeded. There's ostensibly no link between the first and second transaction id. How do I know (programmatically) that the hash for B represents a "real" failure when it's not found by request_tx, but that redundant attempt for A should not be considered a failure, on account of having been automatically already resubmitted in a safe/idempotent manner?

Does that make sense?

edit -

Alternately, if I set local_fee to false in the config, is it safe to assume that each transaction (successful or not) will only have one hash in submittedTxnIDs? Is there reason other than insufficient fee that ripple-lib would resubmit by default?

from xrpl.js.

justmoon avatar justmoon commented on May 24, 2024

We're working on adding a maximum ledger sequence number field to transactions. If you set that field, then your signature for that transaction is only valid until that ledger sequence is reached. That way, if your transaction hasn't gone in by that point, it will never go in. In other words, once we switch to the new process, tejLost will be deterministic.

Until then, if a transaction fails you can either do something like what you're outlining (wait a long time and then check if it made it) or you can submit another transaction that consumes the sequence number. Once the sequence number is consumed, the other transaction is invalid and will no longer be able to go in. Of course, you can only consume the sequence number by submitting another transaction, so it does pose the question - what if that one is tejLost, too?

Practically speaking, the most robust thing you can do right now is pretty much what you're describing:

I can check them all, say, ten or thirty minutes later with request_tx to determine their status, and file them away accordingly.

Second question:

How do I know (programmatically) that the hash for B represents a "real" failure when it's not found by request_tx, but that redundant attempt for A should not be considered a failure, on account of having been automatically already resubmitted in a safe/idempotent manner?

Just an idea, but maybe we should add an event to the Transaction object that fires every time ripple-lib changes and re-signs the transaction, that way it would be easy for an external library to keep track of the hash.

from xrpl.js.

wltsmrz avatar wltsmrz commented on May 24, 2024

Transactions will now emit 'signed' event when they're resigned.

b44f22c

from xrpl.js.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.