diff --git a/CHANGELOG b/CHANGELOG index f0f1a88550..5958838c1f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,10 +1,9 @@ Critical protocol changes ------------------------- -* date * The JSON field "metaData" changing to "meta". * RPC ledger will no longer take "ledger", use "ledger_hash" or "ledger_index". -* "closedLedger" events: +* "ledgerClose" events: ** "hash" DEPRECATED: use "ledger_hash" ** "seqNum" DEPRECATED: use "ledger_index" ** "closeTime" DEPRECATED: use "close" or "close_human" diff --git a/package.json b/package.json index 997dbaa684..f8bbd6405c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ripple-lib", - "version": "0.7.3", + "version": "0.7.4", "description": "Ripple JavaScript client library", "files": [ diff --git a/src/js/remote.js b/src/js/remote.js index 713abd0038..085a279858 100644 --- a/src/js/remote.js +++ b/src/js/remote.js @@ -1146,18 +1146,19 @@ Remote.prototype.request_ripple_balance = function (account, issuer, currency, c var balance = Amount.from_json(node.Balance); // accountHigh implies: for account: balance is negated, highLimit is the limit set by account. var accountHigh = UInt160.from_json(account).equals(highLimit.issuer()); - // The limit set by account. - var accountLimit = (accountHigh ? highLimit : lowLimit).parse_issuer(account); - // The limit set by issuer. - var issuerLimit = (accountHigh ? lowLimit : highLimit).parse_issuer(issuer); - var accountBalance = (accountHigh ? balance.negate() : balance).parse_issuer(account); - var issuerBalance = (accountHigh ? balance : balance.negate()).parse_issuer(issuer); request.emit('ripple_state', { - 'issuer_balance' : issuerBalance, // Balance with dst as issuer. - 'account_balance' : accountBalance, // Balance with account as issuer. - 'issuer_limit' : issuerLimit, // Limit set by issuer with src as issuer. - 'account_limit' : accountLimit // Limit set by account with dst as issuer. + 'account_balance' : ( accountHigh ? balance.negate() : balance).parse_issuer(account), + 'peer_balance' : (!accountHigh ? balance.negate() : balance).parse_issuer(issuer), + + 'account_limit' : ( accountHigh ? highLimit : lowLimit).parse_issuer(issuer), + 'peer_limit' : (!accountHigh ? highLimit : lowLimit).parse_issuer(account), + + 'account_quality_in' : ( accountHigh ? node.HighQualityIn : node.LowQualityIn), + 'peer_quality_in' : (!accountHigh ? node.HighQualityIn : node.LowQualityIn), + + 'account_quality_out' : ( accountHigh ? node.HighQualityOut : node.LowQualityOut), + 'peer_quality_out' : (!accountHigh ? node.HighQualityOut : node.LowQualityOut), }); }); }; diff --git a/test/path-test.js b/test/path-test.js index 00fbaef411..59ffd8cc0d 100644 --- a/test/path-test.js +++ b/test/path-test.js @@ -1,9 +1,10 @@ -var async = require("async"); -var buster = require("buster"); +var async = require("async"); +var buster = require("buster"); -var Amount = require("../src/js/amount.js").Amount; -var Remote = require("../src/js/remote.js").Remote; -var Server = require("./server.js").Server; +var Amount = require("../src/js/amount.js").Amount; +var Remote = require("../src/js/remote.js").Remote; +var Transaction = require("../src/js/transaction.js").Transaction; +var Server = require("./server.js").Server; var testutils = require("./testutils.js"); @@ -495,7 +496,7 @@ buster.testCase("More Path finding", { self.remote.request_ripple_path_find("alice", "bob", "5/USD/bob", [ { 'currency' : "USD" } ]) .on('success', function (m) { - console.log("proposed: %s", JSON.stringify(m)); + // console.log("proposed: %s", JSON.stringify(m)); // 1 alternative. // buster.assert.equals(1, m.alternatives.length) @@ -1138,12 +1139,12 @@ buster.testCase("Via offers", { }); buster.testCase("Indirect paths", { - // 'setUp' : testutils.build_setup(), - 'setUp' : testutils.build_setup({ verbose: true }), + 'setUp' : testutils.build_setup(), + // 'setUp' : testutils.build_setup({ verbose: true }), // 'setUp' : testutils.build_setup({ verbose: true, no_server: true }), 'tearDown' : testutils.build_teardown(), - "//path find" : + "path find" : function (done) { var self = this; @@ -1169,7 +1170,7 @@ buster.testCase("Indirect paths", { self.remote.request_ripple_path_find("alice", "carol", "5/USD/carol", [ { 'currency' : "USD" } ]) .on('success', function (m) { - console.log("proposed: %s", JSON.stringify(m)); + // console.log("proposed: %s", JSON.stringify(m)); // 1 alternative. buster.assert.equals(1, m.alternatives.length) @@ -1186,4 +1187,91 @@ buster.testCase("Indirect paths", { }); }, }); + +buster.testCase("Quality paths", { + // 'setUp' : testutils.build_setup(), + 'setUp' : testutils.build_setup({ verbose: true }), + // 'setUp' : testutils.build_setup({ verbose: true, no_server: true }), + 'tearDown' : testutils.build_teardown(), + + "quality set and test" : + function (done) { + var self = this; + + async.waterfall([ + function (callback) { + self.what = "Create accounts."; + + testutils.create_accounts(self.remote, "root", "10000.0", ["alice", "bob"], callback); + }, + function (callback) { + self.what = "Set credit limits extended."; + + testutils.credit_limits(self.remote, + { + "bob" : "1000/USD/alice:2000,1400000000", + }, + callback); + }, + function (callback) { + self.what = "Verify credit limits extended."; + + testutils.verify_limit(self.remote, "bob", "1000/USD/alice:2000,1400000000", callback); + }, + ], function (error) { + buster.refute(error, self.what); + done(); + }); + }, + + "// quality payment (BROKEN DUE TO ROUNDING)" : + function (done) { + var self = this; + + async.waterfall([ + function (callback) { + self.what = "Create accounts."; + + testutils.create_accounts(self.remote, "root", "10000.0", ["alice", "bob"], callback); + }, + function (callback) { + self.what = "Set credit limits extended."; + + testutils.credit_limits(self.remote, + { + "bob" : "1000/USD/alice:" + .9*1e9 + "," + 1e9, + }, + callback); + }, + function (callback) { + self.what = "Payment with auto path"; + + self.remote.transaction() + .payment('alice', 'bob', "100/USD/bob") + .send_max("120/USD/alice") +// .set_flags('PartialPayment') +// .build_path(true) + .once('proposed', function (m) { + // console.log("proposed: %s", JSON.stringify(m)); + callback(m.result !== 'tesSUCCESS'); + }) + .submit(); + }, + function (callback) { + self.what = "Display ledger"; + + self.remote.request_ledger('current', { accounts: true, expand: true }) + .on('success', function (m) { + console.log("Ledger: %s", JSON.stringify(m, undefined, 2)); + + callback(); + }) + .request(); + }, + ], function (error) { + buster.refute(error, self.what); + done(); + }); + }, +}); // vim:sw=2:sts=2:ts=8:et diff --git a/test/send-test.js b/test/send-test.js index e80964fc28..2c2c390a82 100644 --- a/test/send-test.js +++ b/test/send-test.js @@ -152,12 +152,12 @@ buster.testCase("Sending", { // console.log("BALANCE: %s", JSON.stringify(m)); // console.log("account_balance: %s", m.account_balance.to_text_full()); // console.log("account_limit: %s", m.account_limit.to_text_full()); -// console.log("issuer_balance: %s", m.issuer_balance.to_text_full()); -// console.log("issuer_limit: %s", m.issuer_limit.to_text_full()); +// console.log("peer_balance: %s", m.peer_balance.to_text_full()); +// console.log("peer_limit: %s", m.peer_limit.to_text_full()); buster.assert(m.account_balance.equals("0/USD/alice")); - buster.assert(m.account_limit.equals("800/USD/alice")); - buster.assert(m.issuer_balance.equals("0/USD/mtgox")); - buster.assert(m.issuer_limit.equals("0/USD/mtgox")); + buster.assert(m.account_limit.equals("800/USD/mtgox")); + buster.assert(m.peer_balance.equals("0/USD/mtgox")); + buster.assert(m.peer_limit.equals("0/USD/alice")); callback(); }) @@ -172,9 +172,9 @@ buster.testCase("Sending", { self.remote.request_ripple_balance("alice", "mtgox", "USD", 'CURRENT') .on('ripple_state', function (m) { buster.assert(m.account_balance.equals("0/USD/alice")); - buster.assert(m.account_limit.equals("700/USD/alice")); - buster.assert(m.issuer_balance.equals("0/USD/mtgox")); - buster.assert(m.issuer_limit.equals("0/USD/mtgox")); + buster.assert(m.account_limit.equals("700/USD/mtgox")); + buster.assert(m.peer_balance.equals("0/USD/mtgox")); + buster.assert(m.peer_limit.equals("0/USD/alice")); callback(); }) @@ -215,8 +215,8 @@ buster.testCase("Sending", { // Used to keep lines. // buster.assert(m.account_balance.equals("0/USD/alice")); // buster.assert(m.account_limit.equals("0/USD/alice")); - // buster.assert(m.issuer_balance.equals("0/USD/mtgox")); - // buster.assert(m.issuer_limit.equals("0/USD/mtgox")); + // buster.assert(m.peer_balance.equals("0/USD/mtgox")); + // buster.assert(m.peer_limit.equals("0/USD/mtgox")); buster.assert(false); }) @@ -248,9 +248,9 @@ buster.testCase("Sending", { // console.log("proposed: %s", JSON.stringify(m)); buster.assert(m.account_balance.equals("0/USD/alice")); - buster.assert(m.account_limit.equals("600/USD/alice")); - buster.assert(m.issuer_balance.equals("0/USD/bob")); - buster.assert(m.issuer_limit.equals("500/USD/bob")); + buster.assert(m.account_limit.equals("600/USD/bob")); + buster.assert(m.peer_balance.equals("0/USD/bob")); + buster.assert(m.peer_limit.equals("500/USD/alice")); callback(); }) @@ -262,9 +262,9 @@ buster.testCase("Sending", { self.remote.request_ripple_balance("bob", "alice", "USD", 'CURRENT') .on('ripple_state', function (m) { buster.assert(m.account_balance.equals("0/USD/bob")); - buster.assert(m.account_limit.equals("500/USD/bob")); - buster.assert(m.issuer_balance.equals("0/USD/alice")); - buster.assert(m.issuer_limit.equals("600/USD/alice")); + buster.assert(m.account_limit.equals("500/USD/alice")); + buster.assert(m.peer_balance.equals("0/USD/alice")); + buster.assert(m.peer_limit.equals("600/USD/bob")); callback(); }) @@ -325,7 +325,7 @@ buster.testCase("Sending future", { self.remote.request_ripple_balance("alice", "bob", "USD", 'CURRENT') .once('ripple_state', function (m) { buster.assert(m.account_balance.equals("-24/USD/alice")); - buster.assert(m.issuer_balance.equals("24/USD/bob")); + buster.assert(m.peer_balance.equals("24/USD/bob")); callback(); }) @@ -351,7 +351,7 @@ buster.testCase("Sending future", { self.remote.request_ripple_balance("bob", "alice", "USD", 'CURRENT') .once('ripple_state', function (m) { buster.assert(m.account_balance.equals("57/USD/bob")); - buster.assert(m.issuer_balance.equals("-57/USD/alice")); + buster.assert(m.peer_balance.equals("-57/USD/alice")); callback(); }) @@ -473,8 +473,8 @@ buster.testCase("Sending future", { // .once('ripple_state', function (m) { // console.log("account_balance: %s", m.account_balance.to_text_full()); // console.log("account_limit: %s", m.account_limit.to_text_full()); -// console.log("issuer_balance: %s", m.issuer_balance.to_text_full()); -// console.log("issuer_limit: %s", m.issuer_limit.to_text_full()); +// console.log("peer_balance: %s", m.peer_balance.to_text_full()); +// console.log("peer_limit: %s", m.peer_limit.to_text_full()); // // buster.assert(m.account_balance.equals("600/USD/alice")); // diff --git a/test/testutils.js b/test/testutils.js index f809efacca..b81df48612 100644 --- a/test/testutils.js +++ b/test/testutils.js @@ -171,19 +171,68 @@ var create_accounts = function (remote, src, amount, accounts, callback) { var credit_limit = function (remote, src, amount, callback) { assert(4 === arguments.length); - remote.transaction() - .ripple_line_set(src, amount) - .on('proposed', function (m) { - // console.log("proposed: %s", JSON.stringify(m)); + var _m = amount.match(/^(\d+\/...\/[^\:]+)(?::(\d+)(?:,(\d+))?)?$/); + if (!_m) { + console.log("credit_limit: parse error: %s", amount); - callback(m.result != 'tesSUCCESS'); - }) - .on('error', function (m) { - // console.log("error: %s", JSON.stringify(m)); + callback('parse_error'); + } + else + { + // console.log("credit_limit: parsed: %s", JSON.stringify(_m, undefined, 2)); + var _account_limit = _m[1]; + var _quality_in = _m[2]; + var _quality_out = _m[3]; - callback(m); - }) - .submit(); + remote.transaction() + .ripple_line_set(src, _account_limit, _quality_in, _quality_out) + .on('proposed', function (m) { + // console.log("proposed: %s", JSON.stringify(m)); + + callback(m.result != 'tesSUCCESS'); + }) + .on('error', function (m) { + // console.log("error: %s", JSON.stringify(m)); + + callback(m); + }) + .submit(); + } +}; + +var verify_limit = function (remote, src, amount, callback) { + assert(4 === arguments.length); + + var _m = amount.match(/^(\d+\/...\/[^\:]+)(?::(\d+)(?:,(\d+))?)?$/); + if (!_m) { + // console.log("credit_limit: parse error: %s", amount); + + callback('parse_error'); + } + else + { + // console.log("verify_limit: parsed: %s", JSON.stringify(_m, undefined, 2)); + var _account_limit = _m[1]; + var _quality_in = _m[2]; + var _quality_out = _m[3]; + + var _limit = Amount.from_json(_account_limit); + + remote.request_ripple_balance(src, _limit.issuer().to_json(), _limit.currency().to_json(), 'CURRENT') + .once('ripple_state', function (m) { + buster.assert(m.account_limit.equals(_limit)); + buster.assert('undefined' === _quality_in || m.account_quality_in == _quality_in); + buster.assert('undefined' === _quality_out || m.account_quality_out == _quality_out); + + callback(); + }) + .on('error', function (m) { + // console.log("error: %s", JSON.stringify(m)); + + callback(m); + }) + .request(); + } }; var credit_limits = function (remote, balances, callback) { @@ -424,6 +473,7 @@ exports.payments = payments; exports.transfer_rate = transfer_rate; exports.verify_balance = verify_balance; exports.verify_balances = verify_balances; +exports.verify_limit = verify_limit; exports.verify_offer = verify_offer; exports.verify_offer_not_found = verify_offer_not_found; exports.verify_owner_count = verify_owner_count;