From 3932ce95fde25bddd60630070a4e73a37cb53d85 Mon Sep 17 00:00:00 2001 From: Stefan Thomas Date: Sat, 23 Feb 2013 23:25:55 +0100 Subject: [PATCH] JS: Hotfix for sequence issue. --- src/js/remote.js | 3 +- src/js/transaction.js | 83 +++++++++++++++++++++++++++++-------------- 2 files changed, 59 insertions(+), 27 deletions(-) diff --git a/src/js/remote.js b/src/js/remote.js index 8507c4a3f5..72a9f6b627 100644 --- a/src/js/remote.js +++ b/src/js/remote.js @@ -1082,7 +1082,8 @@ Remote.prototype.account_seq = function (account, advance) { { seq = account_info.seq; - if (advance) account_info.seq += 1; + if (advance === "ADVANCE") account_info.seq += 1; + if (advance === "REWIND") account_info.seq -= 1; // console.log("cached: %s current=%d next=%d", account, seq, account_info.seq); } diff --git a/src/js/transaction.js b/src/js/transaction.js index 77b8841d4e..61eb541a1e 100644 --- a/src/js/transaction.js +++ b/src/js/transaction.js @@ -312,32 +312,59 @@ Transaction.prototype.submit = function (callback) { if (self.remote.local_sequence && !self.tx_json.Sequence) { self.tx_json.Sequence = this.remote.account_seq(self.tx_json.Account, 'ADVANCE'); // console.log("Sequence: %s", self.tx_json.Sequence); - } - if (self.remote.local_sequence && !self.tx_json.Sequence) { - // Look in the last closed ledger. - this.remote.account_seq_cache(self.tx_json.Account, false) - .on('success_account_seq_cache', function () { - // Try again. - self.submit(); - }) - .on('error_account_seq_cache', function (message) { - // XXX Maybe be smarter about this. Don't want to trust an untrusted server for this seq number. + if (!self.tx_json.Sequence) { + // Look in the last closed ledger. + this.remote.account_seq_cache(self.tx_json.Account, false) + .on('success_account_seq_cache', function () { + // Try again. + self.submit(); + }) + .on('error_account_seq_cache', function (message) { + // XXX Maybe be smarter about this. Don't want to trust an untrusted server for this seq number. - // Look in the current ledger. - self.remote.account_seq_cache(self.tx_json.Account, 'CURRENT') - .on('success_account_seq_cache', function () { - // Try again. - self.submit(); - }) - .on('error_account_seq_cache', function (message) { - // Forward errors. - self.emit('error', message); - }) - .request(); - }) - .request(); - return this; + // Look in the current ledger. + self.remote.account_seq_cache(self.tx_json.Account, 'CURRENT') + .on('success_account_seq_cache', function () { + // Try again. + self.submit(); + }) + .on('error_account_seq_cache', function (message) { + // Forward errors. + self.emit('error', message); + }) + .request(); + }) + .request(); + return this; + } + + // If the transaction fails we want to either undo incrementing the sequence + // or submit a noop transaction to consume the sequence remotely. + this.on('success', function (res) { + if (!res || "string" !== typeof res.engine_result) return; + + switch (res.engine_result.slice(0, 3)) { + // Synchronous local error + case 'tej': + self.remote.account_seq(self.tx_json.Account, 'REWIND'); + break; + // XXX: What do we do in case of ter? + case 'tel': + case 'tem': + case 'tef': + // XXX Once we have a transaction submission manager class, we can + // check if there are any other transactions pending. If there are, + // we should submit a dummy transaction to ensure those + // transactions are still valid. + //var noop = self.remote.transaction().account_set(self.tx_json.Account); + //noop.submit(); + + // XXX Hotfix. This only works if no other transactions are pending. + self.remote.account_seq(self.tx_json.Account, 'REWIND'); + break; + } + }); } // Prepare request @@ -345,8 +372,12 @@ Transaction.prototype.submit = function (callback) { var request = this.remote.request_submit(); // Forward successes and errors. - request.on('success', function (message) { self.emit('success', message); }); - request.on('error', function (message) { self.emit('error', message); }); + request.on('success', function (message) { + self.emit('success', message); + }); + request.on('error', function (message) { + self.emit('error', message); + }); if (!this._secret && !this.tx_json.Signature) { this.emit('error', {