diff --git a/src/js/ripple/serializedobject.js b/src/js/ripple/serializedobject.js index 2c0e2ed7..d7589425 100644 --- a/src/js/ripple/serializedobject.js +++ b/src/js/ripple/serializedobject.js @@ -72,11 +72,40 @@ SerializedObject.from_json = function (obj) { ' TransactionType, LedgerEntryType or AffectedNodes.'); } + // ND: This from_*json* seems a reasonable place to put validation of `json` + SerializedObject.check_no_missing_fields(typedef, obj); so.serialize(typedef, obj); return so; }; +SerializedObject.check_no_missing_fields = function (typedef, obj) { + var missing_fields = []; + + for (var i = typedef.length - 1; i >= 0; i--) { + var spec = typedef[i]; + var field = spec[0] + var requirement = spec[1]; + + if (binformat.REQUIRED === requirement && obj[field] == null) { + missing_fields.push(field); + }; + }; + + if (missing_fields.length > 0) { + var object_name; + if (obj.TransactionType != null) { + object_name = SerializedObject.lookup_type_tx(obj.TransactionType); + } else { + object_name = "TransactionMetaData"; + } /*else { + TODO: LedgerEntryType ... + }*/ + throw new Error(object_name + " is missing fields: " + + JSON.stringify(missing_fields)); + }; +} + SerializedObject.prototype.append = function (bytes) { if (bytes instanceof SerializedObject) { bytes = bytes.buffer; diff --git a/test/serializedobject-test.js b/test/serializedobject-test.js index 21c8a2ed..0efdf2ba 100644 --- a/test/serializedobject-test.js +++ b/test/serializedobject-test.js @@ -35,6 +35,27 @@ describe('Serialized object', function() { assert.deepEqual(input_json, output_json); }); }); + describe('Format validation', function() { + // Peercover actually had a problem submitting transactions without a `Fee` + // and rippled was only informing of "transaction is invalid" + it('should throw an Error when there is a missing field', function() { + var input_json = { + Account: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', + Amount: '274579388', + Destination: 'r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS', + Sequence: 351, + SigningPubKey: '02854B06CE8F3E65323F89260E9E19B33DA3E01B30EA4CA172612DE77973FAC58A', + TransactionType: 'Payment', + TxnSignature: '30450221009DA3A42DD25E3B22EC45AD8BA8FC7A954264264A816D300B2DF69F814D7D4DD2022072C9627F97EEC6DA13DE841E06E2CD985EF06A0FBB15DDBF0800D0730C8986BF' + }; + assert.throws ( + function() { + var output_json = SerializedObject.from_json(input_json); + }, + /Payment is missing fields: \["Fee"\]/ + ); + }); + }); }); // vim:sw=2:sts=2:ts=8:et