XRPLF / xrpl.js

A JavaScript/TypeScript API for interacting with the XRP Ledger in Node.js and the browser
https://xrpl.org/
1.22k stars 513 forks source link

LastLedgerSequence error #2052

Closed lijianl closed 1 year ago

lijianl commented 2 years ago

send xrp always get error:

let tx = {
        Fee: xrpMAP.tx_cost,
        TransactionType: 'Payment',
        Account: fromAddress,
        Amount: xrpl.xrpToDrops(amtXRP),
        Destination: toAddress,
        LastLedgerSequence: validated_ledger + 77, // 2 mins to confirm
        Memos: [
            {Memo: {MemoData: xrpl.convertStringToHex(recordId)}},
            {Memo: {MemoData: xrpl.convertStringToHex(tagInt)}},
        ]
    }
    if (tagInt) {
        tx.DestinationTag = parseInt(tagInt); // int need
    }
    console.log(`xrp-send-data-${JSON.stringify(tx)},${recordId}`);
    let res = await client.submitAndWait(tx, {
        autofill: true,
        failHard: true,
        wallet: fromWallet,
    }).then(res => res.result).catch(err => console.log(`xrp-send-error-${recordId}`, err));

always return error XrplError: The latest ledger sequence 73215626 is greater than the transaction's LastLedgerSequence (73215625).

how to optimize this

lijianl commented 2 years ago
  1. upgrade tx cost to 15 drops.
  2. LastLedgerSequence = validated_ledger got from server_state then add 77
  3. using ws endpoint => wss://xrplcluster.com/
  4. after the submitAndWait called, the response will cost 4mins to return, why cost so many time at here

still always return error, what should i do or where to optimize

lijianl commented 2 years ago

doc

Notice also the LastLedgerSequence based on the last validated ledger our application learned from server_state. The recommendation for backend applications is to use (last validated ledger index + 4). Alternately, use a value of (current ledger + 3). If LastLedgerSequence is miscalculated and less than the last validated ledger, the transaction fails with tefMAX_LEDGER error. any ways to solve this? i am using the last validated ledger index + 77

lijianl commented 2 years ago

transaction verify code from https://xrpl.org/reliable-transaction-submission.html#lastledgersequence

For each persisted transaction without validated result:
    Query transaction by hash
    If (result appears in any validated ledger)
        # Outcome is final
        Persist the final result
        If (result code is tesSUCCESS)
            Application may act based on successful transaction
        Else
            #### ====> submit tx with LastLedgerSequence from client
            The transaction failed (1)
            If appropriate for the application and failure type, submit with
                new LastLedgerSequence and Fee

    Else if (LastLedgerSequence > newest validated ledger)
        # Outcome is not yet final 
        ##### =====>  wait LastLedgerSequence at server 
        Wait for more ledgers to be validated
    Else ....

why to wait some many times when LastLedgerSequence > newest validated ledger

  1. why can not autofill LastLedgerSequence at server side
  2. why confirm the LastLedgerSequence at client side, and then the submission wait at server side

i can understand the code design

i think the LastLedgerSequence in new sdk make it hard to use than the old sdk

JST5000 commented 2 years ago

If you omit the LastLedgerSequence from the Transaction definition, submitAndWait with autofill = true will automatically populate that field for you before sending the transaction. Let me know if that helps. (If not, it may be that the way the transaction is formatted prevents it from being accepted, potentially due to the fee)

lijianl commented 2 years ago
  1. I have tried this way before, it threw these error more frequently. so i tried add LastLedgerSequence to the Transaction definition.
  2. the tx cost i using is 15 drops
  3. everytime the summitAndWait() cost 4min to return will always throw this error.

In my opinion, the ledgerId looks like the blockId at BTC chain, why i have to added this to the transaction definition.

how to avoid the error completely

or the endpoint was unstable or net latency cause this?

how to keep a xrp wallet stable? hope your advice

  1. unstable, this error always happen...
  2. cost 4-5mind to return, will block all wallet service...

this is a big problem for sdk in my opinion

mvadari commented 2 years ago

LastLedgerSequence is not autofill-able by the server, because its use is user-dependent. Its purpose is essentially that unless there's something malformed about the tx, the server will keep trying to put your tx into the next validated ledger, until it hits the LastLedgerSequence ledger ID, at which point it will stop trying and consider the tx invalid now. That's the error that you're getting. It's taking 4-5 minutes because you're using validated_ledger + 77, which means that it's waiting for 77 ledgers to close before throwing an error. With a ledger closing every ~4 seconds, that's about 5 minutes. You can pick a smaller value for the LastLedgerSequence and it'll error faster.

If you're always getting this error, then there's probably something wrong with your transaction. If you upgrade to version >=2.1.1, it'll give you a preliminary transaction error as a part of the error message, which should help you debug.

lijianl commented 2 years ago

ive you a preliminary transaction error as a part of the error message, which should help you debug.

what i wanted is not error faster, but the tx broadcast on chain successfully faster

i will try the newest version today, any problem occured let you know

mvadari commented 2 years ago

what i wanted is not error faster, but the tx broadcast on chain successfully faster

The tx gets broadcast very quickly - within a few seconds. It's not actually taking 5 minutes to broadcast, it's taking 5 minutes to error - the LastLedgerSequence value you're using means that it's continuing to attempt to validate the transaction and include it in the next ledger for every ledger that passes, until the ledger index/ID (which, yes, is similar to the block ID) passes the LastLedgerSequence you used in your transaction. Each time the server tries to do this, it fails to be included in the validated ledger. So there's something wrong with your transaction, and the preliminary error message should help you debug that issue.

lijianl commented 2 years ago

i will try on your advice

lijianl commented 2 years ago

what i wanted is not error faster, but the tx broadcast on chain successfully faster

The tx gets broadcast very quickly - within a few seconds. It's not actually taking 5 minutes to broadcast, it's taking 5 minutes to error - the LastLedgerSequence value you're using means that it's continuing to attempt to validate the transaction and include it in the next ledger for every ledger that passes, until the ledger index/ID (which, yes, is similar to the block ID) passes the LastLedgerSequence you used in your transaction. Each time the server tries to do this, it fails to be included in the validated ledger. So there's something wrong with your transaction, and the preliminary error message should help you debug that issue.

i only get this error back

XrplError: The latest ledger sequence 73276581 is greater than the transaction's LastLedgerSequence (73276580).

could i get more detail such like an error_code, so that i can resend a tx

mvadari commented 2 years ago

What version of the library are you using? I recommend upgrading to at least v2.1.1, which will provide a more detailed error

lijianl commented 2 years ago

What version of the library are you using? I recommend upgrading to at least v2.1.1, which will provide a more detailed error

i am using "xrpl": { "version": "2.3.1"} , i did not get any error detail response,

i haved to send 2 or 5 times, the same data sent out finally, it was not tx-data error certainly

i dont think that waiting LastLedgerSequence is a good design

lijianl commented 2 years ago

What version of the library are you using? I recommend upgrading to at least v2.1.1, which will provide a more detailed error

i am using "xrpl": { "version": "2.3.1"} , i did not get any error detail response,

i haved to send 2 or 5 times, the same data sent out finally, it was not tx-data error certainly

i dont think that waiting LastLedgerSequence is a good design

as for the error

XrplError: The latest ledger sequence 73276581 is greater than the transaction's LastLedgerSequence (73276580)

i think this was caused from server side and it should not threw to the client side

lijianl commented 2 years ago

i chage the code

    let tx = {
        Fee: xrpMAP.tx_cost, // 15 drops
        TransactionType: 'Payment',
        Account: fromAddress,
        Amount: xrpl.xrpToDrops(amtXRP),
        Destination: toAddress,
        Memos: [
            {Memo: {MemoData: xrpl.convertStringToHex(recordId)}},
            {Memo: {MemoData: xrpl.convertStringToHex(tagInt)}},
        ]
    }
    if (tagInt) {
        tx.DestinationTag = parseInt(tagInt); // int need
    }
    let res = await client.submitAndWait(tx, {
        autofill: true,
        failHard: true,
        wallet: fromWallet,
    }).then(res => res.result).catch(err => {console.log(`xrp-send-error-${recordId}`, err);});
  1. error as usually happen.

  2. from call sendAndWait to catch it cost 3 mins....

  3. same tx-data try 3rd times finally success

mvadari commented 2 years ago

What response do you get when you use client.submit instead of client.submitAndWait?

lijianl commented 2 years ago

i am not using submit and using sendAndWait met the error several times one day

mvadari commented 2 years ago

client.submitAndWait is really just calling client.submit and waiting for the transaction to be finalized. What response do you get from the server when you use client.submit instead? That will give you the preliminary response from the server, which might help with debugging.

lijianl commented 2 years ago

will try your advice

lijianl commented 2 years ago

client.submitAndWait is really just calling client.submit and waiting for the transaction to be finalized. What response do you get from the server when you use client.submit instead? That will give you the preliminary response from the server, which might help with debugging.

i test some stages with submit, it could return error code such as tecUNFUNDED_PAYMENT,tecNO_DST_INSUF_XRP

but for the LastLedgerSequence, return nothing; => i dont think this is a data error

node code

let tx = {
        Fee: xrpMAP.tx_cost,
        TransactionType: 'Payment',
        Account: fromAddress,
        Amount: xrpl.xrpToDrops(amtXRP),
        Destination: toAddress,
        Memos: [
            {Memo: {MemoData: xrpl.convertStringToHex(recordId)}},
            {Memo: {MemoData: xrpl.convertStringToHex(tagInt)}},
        ]
    }
    if (tagInt) {
        tx.DestinationTag = parseInt(tagInt); // int need
    }

    console.log(`xrp-send-data-${JSON.stringify(tx)},${recordId}`);
    let res = await client.submit(tx, {
        autofill: true,
        failHard: true,
        wallet: fromWallet,
    }).then(res => res.result).catch(err => console.log(`xrp-send-error-${recordId}`, err));
    console.log(`xrp-send-res-${JSON.stringify(res)},${recordId}`);

get error from catch not then

xrp-send-error-DR1002262642968010752 XrplError: The latest ledger sequence 73306830 is greater than the transaction's LastLedgerSequence (73306829).

and try send again make the tx accepted

mvadari commented 2 years ago

https://xrpl.org/tec-codes.html tecUNFUNDED_PAYMENT means that the amount you're trying to send is more than the account holds. You can check how much XRP you have via the account_info RPC. tecNO_DST_INSUF_XRP means that the account you're trying to send to doesn't exist, and you're not sending enough XRP (10 XRP) for it to exist.

mvadari commented 2 years ago

but for the LastLedgerSequence, return nothing; => i dont think this is a data error

I don't understand what you mean by this.

lijianl commented 2 years ago

but for the LastLedgerSequence, return nothing; => i dont think this is a data error

I don't understand what you mean by this.

when i get XrplError: The latest ledger sequence 73306830 is greater than the transaction's LastLedgerSequence (73306829). from catch, there is no error detail return

and try send second time will success

mvadari commented 2 years ago

What the submitAndWait function does is submit the transaction (essentially with client.submit), then wait for it to be validated (confirmed) on the ledger. If that doesn't happen, usually there's something wrong with your transaction, and the error code will tell you what's wrong so that you can fix it. The purpose of LastLedgerSequence is because the server will keep trying to submit your transaction until that ledger index is hit (it's the "last ledger sequence" that it could be included in), unless something is wrong with the transaction. submitAndWait just waits until the current ledger index is past that point, at which point it will never be included in a validated ledger.

lijianl commented 2 years ago

i am using submit not submitAndWait anymore, code below

console.log(`xrp-send-data-${JSON.stringify(tx)},${recordId}`);
    let res = await client.submit(tx, {
        autofill: true,
        failHard: true,
        wallet: fromWallet,
    }).then(res => res.result).catch(err => console.log(`xrp-send-error-${recordId}`, err));
    console.log(`xrp-send-res-${JSON.stringify(res)},${recordId}`);
mvadari commented 2 years ago

What is the output?

lijianl commented 2 years ago

What is the output?

xrp-send-error-DR1002262642968010752 XrplError: The latest ledger sequence 73306830 is greater than the transaction's LastLedgerSequence (73306829).

mvadari commented 2 years ago

Are you sure you're building properly after changing the code? That error message is literally not possible with client.submit.

lijianl commented 2 years ago

code:

  let tx = {
        Fee: xrpMAP.tx_cost,
        TransactionType: 'Payment',
        Account: fromAddress,
        Amount: xrpl.xrpToDrops(amtXRP),
        Destination: toAddress,
        Memos: [
            {Memo: {MemoData: xrpl.convertStringToHex(recordId)}},
            {Memo: {MemoData: xrpl.convertStringToHex(tagInt)}},
        ]
    }
    if (tagInt) {
        tx.DestinationTag = parseInt(tagInt); // int need
    }
    console.log(`xrp-send-data-${JSON.stringify(tx)},${recordId}`);
    let res = await client.submit(tx, {
        autofill: true,
        failHard: true,
        wallet: fromWallet,
    }).then(res => res.result).catch(err => console.log(`xrp-send-error-${recordId}`, err));
    console.log(`xrp-send-res-${JSON.stringify(res)},${recordId}`);
  1. send first time and cost 3 mins about
2022-07-28 09:16:01.254: xrp-send-data-{"Fee":"15","TransactionType":"Payment","Account":"rHxtRRUMVAnPZUyRgXhRSyWZ2MrHx8AvVs","Amount":"9923400","Destination":"rE8YdxtfLUtYx2cm24BCPnsZrf4um9UpQf","Memos":[{"Memo":{"MemoData":"445231303032323632363432393638303130373532"}},{"Memo":{"MemoData":""}}],"LastLedgerSequence":73306829},DR1002262642968010752
2022-07-28 09:19:38.692: xrp-send-error-DR1002262642968010752 XrplError: The latest ledger sequence 73306830 is greater than the transaction's LastLedgerSequence (73306829).
xrp-send-res-undefined,DR1002262642968010752
  1. send second time
send-crypto->wallet:record:state:DR1002262642968010752,pending
2022-07-28 10:50:00.231: xrp-send-data-{"Fee":"15","TransactionType":"Payment","Account":"rHxtRRUMVAnPZUyRgXhRSyWZ2MrHx8AvVs","Amount":"9923400","Destination":"rE8YdxtfLUtYx2cm24BCPnsZrf4um9UpQf","Memos":[{"Memo":{"MemoData":"445231303032323632363432393638303130373532"}},{"Memo":{"MemoData":""}}]},DR1002262642968010752
2022-07-28 10:50:00.355: xrp-send-res-{"accepted":false,"account_sequence_available":33015,"account_sequence_next":33015,"applied":false,"broadcast":false,"engine_result":"tecNO_DST_INSUF_XRP","engine_result_code":125,"engine_result_message":"Destination does not exist. Too little XRP sent to create it.","kept":false,"open_ledger_cost":"10","queued":false,"tx_blob":"120000220000000024000080F7201B045E985D614000000000976B4868400000000000000F732103B513FA8C9344BFEDE5C4ADCAADDB444F1552942B1EEC1F6AA28ACFA99AEAFE7C74473045022100DE9455BB9A2D5E6570FA1704F9B960E1677E8A225FD0273A8E6BDAC47D78AB98022042529D6A6325BA82CA606E973FA45BC6CF13914E939BB4DF238BDE34BBD157958114BA13D0841F7AB63C131B29600E1F5F8FE9FDCB7D8314A22EE384A040C324E1A635DE30D3F251B6A4948DF9EA7D15445231303032323632363432393638303130373532E1EA7D00E1F1","tx_json":{"Account":"rHxtRRUMVAnPZUyRgXhRSyWZ2MrHx8AvVs","Amount":"9923400","Destination":"rE8YdxtfLUtYx2cm24BCPnsZrf4um9UpQf","Fee":"15","Flags":0,"LastLedgerSequence":73308253,"Memos":[{"Memo":{"MemoData":"445231303032323632363432393638303130373532"}},{"Memo":{"MemoData":""}}],"Sequence":33015,"SigningPubKey":"03B513FA8C9344BFEDE5C4ADCAADDB444F1552942B1EEC1F6AA28ACFA99AEAFE7C","TransactionType":"Payment","TxnSignature":"3045022100DE9455BB9A2D5E6570FA1704F9B960E1677E8A225FD0273A8E6BDAC47D78AB98022042529D6A6325BA82CA606E973FA45BC6CF13914E939BB4DF238BDE34BBD15795","hash":"234CC9F7A4AB7CDA776A991DF6075D16192B7F96C0D8EBA7E861A28E52AEB813"},"validated_ledger_index":73308233},DR1002262642968010752
mvadari commented 2 years ago

tecNO_DST_INSUF_XRP means that your toAddress doesn't exist, and amtXRP isn't enough to make it exist. So you'll have to increase amtXRP to at least 10 XRP, and that will allow toAddress to exist as an account. https://xrpl.org/tec-codes.html for more details

mvadari commented 2 years ago

This is the relevant part of the output:

engine_result":"tecNO_DST_INSUF_XRP","engine_result_code":125,"engine_result_message":"Destination does not exist. Too little XRP sent to create it."
lijianl commented 2 years ago

yes, i know how to deal with station 2, but i dont know how to solve station 1, i cant send too many times for xrp security

mvadari commented 2 years ago

If you deal with the problem in situation 2, it'll fix your problem in situation 1. Situation 2 is just doing a better job of telling you what the problem is in situation 1.

client.submit submits and doesn't wait, client.submitAndWait submits and waits for it to be confirmed (which doesn't happen because it's failing). Your XRP with situation 1 is not actually being sent, the transaction was never confirmed so you never lost your funds.

mvadari commented 2 years ago

I recommend testing out your code with the testnet first: https://xrpl.org/parallel-networks.html#parallel-networks

lijianl commented 2 years ago

If you deal with the problem in situation 2, it'll fix your problem in situation 1. Situation 2 is just doing a better job of telling you what the problem is in situation 1.

client.submit submits and doesn't wait, client.submitAndWait submits and waits for it to be confirmed (which doesn't happen because it's failing). Your XRP with situation 1 is not actually being sent, the transaction was never confirmed so you never lost your funds.

so, what should i do to get my tx accepted stably, so that i dont need to send one tx too many times till it success

mvadari commented 2 years ago

What is the objective of your payment? If it's to create a new account (an account doesn't actually exist until it has the minimum amount of funds), then you'll need to send at least 10 XRP, and then it'll work (very reliably - I rarely have issues with sending transactions, and when I do, it's always because I messed something up in my transaction). 10 XRP is the minimum amount of XRP an account needs to exist. https://xrpl.org/reserves.html#reserves

lijianl commented 2 years ago

https://xrpl.org/parallel-networks.html#parallel-networks

i know this, i am asking how to avoid the error XrplError: The latest ledger sequence 73306830 is greater than the transaction's LastLedgerSequence (73306829). xrp-send-res-undefined,DR1002262642968010752

the error tecNO_DST_INSUF_XRP was caused when i send my tx second time;

mvadari commented 2 years ago

The first error has the same root cause as the second error. The problem is the same, the two commands are just displaying it in different ways. I'm not sure why the preliminary result isn't showing up in the first error for you, because it works just fine for me (and has many times in the past).

lijianl commented 2 years ago

The first error has the same root cause as the second error. The problem is the same, the two commands are just displaying it in different ways. I'm not sure why the preliminary result isn't showing up in the first error for you, because it works just fine for me (and has many times in the past).

no,i dont think these two error has some link , i will send you another case when i met this error,

mvadari commented 2 years ago

I assure you, they do have the same cause in this case. The client.submitAndWait LastLedgerSequence error that you're getting is just not displaying the original error, which you get via client.submit. Neither transaction was successful on the ledger.

mvadari commented 1 year ago

Closing because this issue has not had any response in months. Please reopen if you continue to have this problem.