function lookup_tx_final(tx_id, max_ledger, min_ledger) { if (typeof min_ledger == "undefined") { min_ledger = -1 } if (typeof max_ledger == "undefined") { max_ledger = -1 } if (min_ledger > max_ledger) { // Assume the args were just passed backwards & swap them [min_ledger, max_ledger] = [max_ledger, min_ledger] } // Helper to determine if we (should) know the transaction's final result yet. // If the server has validated all ledgers the tx could possibly appear in, // then we should know its final result. async function server_has_ledger_range(min_ledger, max_ledger) { const si = await api.request("server_info") if (si.info.complete_ledgers == "empty") { console.warn("Connected server is not synced.") return false } // In case of a discontiguous set, use only the last set, since we need // continuous history from submission to expiration to know that a // transaction failed to achieve consensus. const ledger_ranges = si.info.complete_ledgers.split(',') // Note: last_range can be in the form 'x-y' or just 'y' const last_range = ledger_ranges[ledger_ranges.length -1].split('-') const lr_min = parseInt(last_range[0]) const lr_max = parseInt(last_range[last_range.length - 1]) const max_validated = Math.min(lr_max, lr_max) if (lr_min <= min_ledger && max_validated >= max_ledger) { return true } return false } return new Promise((resolve, reject) => { api.on('ledger', async (ledger) => { try { tx_result = await api.request("tx", { "transaction": tx_id, "min_ledger": min_ledger, "max_ledger": max_ledger }) if (tx_result.validated) { resolve(tx_result.meta.TransactionResult) } else if (max_ledger > ledger.ledgerVersion) { // Transaction found, not validated, but we should have a final result // by now. // Work around https://github.com/ripple/rippled/issues/3727 if (server_has_ledger_range(min_ledger, max_ledger)) { // Transaction should have been validated by now. reject(`Transaction not found in ledgers ${min_ledger}-${max_ledger}. This result is final if this ledger is correct.`) } else { reject("Can't get final result. Check a full history server.") } } else { // Transaction may still be validated later. Keep waiting. } } catch(e) { if (e.data.error == "txnNotFound") { if (e.data.searched_all) { reject(`Transaction not found in ledgers ${min_ledger}-${max_ledger}. This result is final if this range is correct.`) } else { if (max_ledger > ledger.ledgerVersion) { // Transaction may yet be confirmed. This would not be a bad time // to resubmit the transaction just in case. } else { // Work around https://github.com/ripple/rippled/issues/3750 if (server_has_ledger_range(min_ledger, max_ledger)) { reject(`Transaction not found in ledgers ${min_ledger}-${max_ledger}. This result is final if this range is correct.`) } else { reject("Can't get final result. Check a full history server.") } } } } else { // Unknown error; pass it back up reject(`Unknown Error: ${e}`) } } }) // end ledger event handler }) // end promise def }