Skip to content

Commit

Permalink
Fix transaction summary for transactions that fail with remoteError
Browse files Browse the repository at this point in the history
  • Loading branch information
wltsmrz committed May 16, 2015
1 parent e66978f commit 6ec61f6
Show file tree
Hide file tree
Showing 4 changed files with 268 additions and 74 deletions.
55 changes: 31 additions & 24 deletions src/transaction.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

var util = require('util');
var lodash = require('lodash');
var EventEmitter = require('events').EventEmitter;
var utils = require('./utils');
var sjcl = require('./utils').sjcl;
Expand Down Expand Up @@ -143,7 +144,11 @@ Transaction.set_clear_flags = {
Transaction.MEMO_TYPES = {
};

Transaction.ASCII_REGEX = /^[\x00-\x7F]*$/;
/* eslint-disable max-len */

// URL characters per RFC 3986
Transaction.MEMO_REGEX = /^[0-9a-zA-Z-\.\_\~\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\%]+$/;
/* eslint-enable max-len */

Transaction.formats = require('./binformat').tx;

Expand Down Expand Up @@ -813,44 +818,37 @@ Transaction.prototype.setFlags = function(flags) {
/**
* Add a Memo to transaction.
*
* @param {String} memoType
* - describes what the data represents, needs to be valid ASCII
* * @param {String} memoFormat
* - describes what format the data is in, MIME type, needs to be valid ASCII
* @param {String} memoData
* @param [String] memoType
* - describes what the data represents, must contain valid URL characters
* @param [String] memoFormat
* - describes what format the data is in, MIME type, must contain valid URL
* - characters
* @param [String] memoData
* - data for the memo, can be any JS object. Any object other than string will
* be stringified (JSON) for transport
*/

Transaction.prototype.addMemo = function(memoType, memoFormat, memoData) {

if (typeof memoType === 'object') {
var opts = memoType;
memoType = opts.memoType;
memoFormat = opts.memoFormat;
memoData = opts.memoData;
}

if (!/(undefined|string)/.test(typeof memoType)) {
throw new Error('MemoType must be a string');
} else if (!Transaction.ASCII_REGEX.test(memoType)) {
throw new Error('MemoType must be valid ASCII');
}

if (!/(undefined|string)/.test(typeof memoFormat)) {
throw new Error('MemoFormat must be a string');
} else if (!Transaction.ASCII_REGEX.test(memoFormat)) {
throw new Error('MemoFormat must be valid ASCII');
}

function convertStringToHex(string) {
var utf8String = sjcl.codec.utf8String.toBits(string);
return sjcl.codec.hex.fromBits(utf8String).toUpperCase();
}

var memo = {};
var memoRegex = Transaction.MEMO_REGEX;

if (memoType) {
if (!(lodash.isString(memoType) && memoRegex.test(memoType))) {
throw new Error(
'MemoType must be a string containing only valid URL characters');
}
if (Transaction.MEMO_TYPES[memoType]) {
// XXX Maybe in the future we want a schema validator for
// memo types
Expand All @@ -860,6 +858,11 @@ Transaction.prototype.addMemo = function(memoType, memoFormat, memoData) {
}

if (memoFormat) {
if (!(lodash.isString(memoFormat) && memoRegex.test(memoFormat))) {
throw new Error(
'MemoFormat must be a string containing only valid URL characters');
}

memo.MemoFormat = convertStringToHex(memoFormat);
}

Expand Down Expand Up @@ -1211,8 +1214,9 @@ Transaction.prototype.abort = function() {
* @return {Object} transaction summary
*/

Transaction.prototype.getSummary =
Transaction.prototype.summary = function() {
var result = {
var txSummary = {
tx_json: this.tx_json,
clientID: this._clientID,
submittedIDs: this.submittedIDs,
Expand All @@ -1221,21 +1225,24 @@ Transaction.prototype.summary = function() {
initialSubmitIndex: this.initialSubmitIndex,
lastLedgerSequence: this.lastLedgerSequence,
state: this.state,
server: this._server ? this._server._opts.url : undefined,
finalized: this.finalized
};

if (this.result) {
result.result = {
txSummary.result = {
engine_result: this.result.engine_result,
engine_result_message: this.result.engine_result_message,
ledger_hash: this.result.ledger_hash,
ledger_index: this.result.ledger_index,
transaction_hash: this.result.tx_json.hash
transaction_hash: undefined
};

if (this.result.tx_json) {
txSummary.result.transaction_hash = this.result.tx_json.hash;
}
}

return result;
return txSummary;
};

exports.Transaction = Transaction;
Expand Down
78 changes: 45 additions & 33 deletions test/fixtures/transactionmanager.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,24 +56,24 @@
"meta": {
"AffectedNodes": [
{
"ModifiedNode": {
"FinalFields": {
"Account": "rNP2Y5EZrVZdFKsow11NoKTE5FjXuBQd3d",
"Balance": "1000",
"Flags": 4849664,
"OwnerCount": 1,
"Sequence": 1
},
"LedgerEntryType": "AccountRoot",
"LedgerIndex": "A4B28FB972EF890DC39A8557DF8960D41DADA00D39B0F1EFCD4BBB85FCA13A30",
"PreviousFields": {
"Balance": "1000",
"Sequence": 3864
},
"PreviousTxnID": "F4910E55A39C42AB82071212D84119631DDE0B0F4F8F9040F252B0066898DBDF",
"PreviousTxnLgrSeq": 11693103
}
"ModifiedNode": {
"FinalFields": {
"Account": "rNP2Y5EZrVZdFKsow11NoKTE5FjXuBQd3d",
"Balance": "1000",
"Flags": 4849664,
"OwnerCount": 1,
"Sequence": 1
},
"LedgerEntryType": "AccountRoot",
"LedgerIndex": "A4B28FB972EF890DC39A8557DF8960D41DADA00D39B0F1EFCD4BBB85FCA13A30",
"PreviousFields": {
"Balance": "1000",
"Sequence": 3864
},
"PreviousTxnID": "F4910E55A39C42AB82071212D84119631DDE0B0F4F8F9040F252B0066898DBDF",
"PreviousTxnLgrSeq": 11693103
}
}
],
"TransactionIndex": 9,
"TransactionResult": "tesSUCCESS"
Expand Down Expand Up @@ -101,24 +101,24 @@
"TransactionIndex": 3,
"AffectedNodes": [
{
"ModifiedNode": {
"LedgerEntryType": "AccountRoot",
"PreviousTxnLgrSeq": 11693103,
"PreviousTxnID": "F4910E55A39C42AB82071212D84119631DDE0B0F4F8F9040F252B0066898DBDF",
"LedgerIndex": "A4B28FB972EF890DC39A8557DF8960D41DADA00D39B0F1EFCD4BBB85FCA13A30",
"PreviousFields": {
"Sequence": 3864,
"Balance": "1000"
},
"FinalFields": {
"Flags": 4849664,
"Sequence": 3865,
"OwnerCount": 1,
"Balance": "1000",
"Account": "rNP2Y5EZrVZdFKsow11NoKTE5FjXuBQd3d"
}
"ModifiedNode": {
"LedgerEntryType": "AccountRoot",
"PreviousTxnLgrSeq": 11693103,
"PreviousTxnID": "F4910E55A39C42AB82071212D84119631DDE0B0F4F8F9040F252B0066898DBDF",
"LedgerIndex": "A4B28FB972EF890DC39A8557DF8960D41DADA00D39B0F1EFCD4BBB85FCA13A30",
"PreviousFields": {
"Sequence": 3864,
"Balance": "1000"
},
"FinalFields": {
"Flags": 4849664,
"Sequence": 3865,
"OwnerCount": 1,
"Balance": "1000",
"Account": "rNP2Y5EZrVZdFKsow11NoKTE5FjXuBQd3d"
}
}
}
],
"TransactionResult": "tesSUCCESS"
},
Expand Down Expand Up @@ -290,5 +290,17 @@
},
"status": "success",
"type": "response"
},
"SUBMIT_REMOTE_ERROR": {
"error": "invalidTransaction",
"error_exception": "fails local checks: The MemoType and MemoFormat fields may only contain characters that are allowed in URLs under RFC 3986.",
"id": 1,
"request": {
"command": "submit",
"id": 1,
"tx_blob": "12000022800000002400000001201B00CCEAD0614000000000000001684000000000002EE0732102999FB4BC17144F83CDC2F17EA642519FF115EE7B0CC8C78DE9061F1A473F7BAC7447304502210098DC7E9ED1CE860FB6B0904E6E8140D5463D288BA633F36E69A68ACB3D6FCA06022014E76E22F5173B37239F9F56F904839B462F5019169C56A324D3F074FBA39A2A811492DECA2DC92352BE97C1F6347F7E6CCB9A8241C883143108B9AC27BF036EFE5CBE787921F54D622B7A5BF9EA7C0B6D79206D656D6F747970657E0C6D79206D656D6F5F64617461E1F1"
},
"status": "error",
"type": "response"
}
}
Loading

0 comments on commit 6ec61f6

Please sign in to comment.