Merge branch 'develop' of github.com:jedmccaleb/NewCoin into develop

This commit is contained in:
JoelKatz
2013-04-21 20:38:11 -07:00
3 changed files with 167 additions and 8 deletions

159
bin/rlint.js Executable file
View File

@@ -0,0 +1,159 @@
#!/usr/bin/node
var async = require('async');
var Remote = require('../src/js/remote').Remote;
var Transaction = require('../src/js/transaction').Transaction;
var UInt160 = require('../src/js/uint160').UInt160;
var Amount = require('../src/js/amount').Amount;
var book_key = function (book) {
return book.taker_pays.currency
+ ":" + book.taker_pays.issuer
+ ":" + book.taker_gets.currency
+ ":" + book.taker_gets.issuer;
};
var book_key_cross = function (book) {
return book.taker_gets.currency
+ ":" + book.taker_gets.issuer
+ ":" + book.taker_pays.currency
+ ":" + book.taker_pays.issuer;
};
var ledger_verify = function (ledger) {
var dir_nodes = ledger.accountState.filter(function (entry) {
return entry.LedgerEntryType === 'DirectoryNode' // Only directories
&& entry.index === entry.RootIndex // Only root nodes
&& 'TakerGetsCurrency' in entry; // Only offer directories
});
var books = {};
dir_nodes.forEach(function (node) {
var book = {
taker_gets: {
currency: UInt160.from_generic(node.TakerGetsCurrency).to_json(),
issuer: UInt160.from_generic(node.TakerGetsIssuer).to_json()
},
taker_pays: {
currency: UInt160.from_generic(node.TakerPaysCurrency).to_json(),
issuer: UInt160.from_generic(node.TakerPaysIssuer).to_json()
},
quality: Amount.from_quality(node.RootIndex)
};
books[book_key(book)] = book;
// console.log(JSON.stringify(node, undefined, 2));
});
// console.log(JSON.stringify(dir_entry, undefined, 2));
console.log("#%s books: %s", ledger.ledger_index, Object.keys(books).length);
Object.keys(books).forEach(function (key) {
var book = books[key];
var key_cross = book_key_cross(book);
var book_cross = books[key_cross];
if (book && book_cross && !book_cross.done)
{
var book_cross_quality_inverted = Amount.from_json("1.0/1/1").divide(book_cross.quality);
if (book_cross_quality_inverted.compareTo(book.quality) > 0)
{
console.log("crossing: #%s :: %s :: %s :: %s", ledger.ledger_index, key, book.quality.to_text(), book_cross.quality.to_text());
}
book_cross.done = true;
}
});
};
var ledger_request = function (remote, ledger_index, done) {
remote.request_ledger(undefined, {
accounts: true,
expand: true,
})
.ledger_index(ledger_index)
.on('success', function (m) {
// console.log("ledger: ", ledger_index);
// console.log("ledger: ", JSON.stringify(m, undefined, 2));
done(m.ledger);
})
.on('error', function (m) {
console.log("error");
done();
})
.request();
};
var usage = function () {
console.log("rlint.js _websocket_ip_ _websocket_port_ ");
};
var finish = function (remote) {
remote.disconnect();
// XXX Because remote.disconnect() doesn't work:
process.exit();
};
console.log("args: ", process.argv.length);
console.log("args: ", process.argv);
if (process.argv.length < 4) {
usage();
}
else {
var remote = Remote.from_config({
websocket_ip: process.argv[2],
websocket_port: process.argv[3],
})
.once('ledger_closed', function (m) {
console.log("ledger_closed: ", JSON.stringify(m, undefined, 2));
if (process.argv.length === 5) {
var ledger_index = process.argv[4];
ledger_request(remote, ledger_index, function (l) {
if (l) {
ledger_verify(l);
}
finish(remote);
});
} else if (process.argv.length === 6) {
var ledger_start = Number(process.argv[4]);
var ledger_end = Number(process.argv[5]);
var ledger_cursor = ledger_end;
async.whilst(
function () {
return ledger_start <= ledger_cursor && ledger_cursor <=ledger_end;
},
function (callback) {
// console.log(ledger_cursor);
--ledger_cursor;
ledger_request(remote, ledger_cursor, function (l) {
if (l) {
ledger_verify(l);
}
callback();
});
},
function (error) {
finish(remote);
});
} else {
finish(remote);
}
})
.connect();
}
// vim:sw=2:sts=2:ts=8:et

View File

@@ -1057,7 +1057,7 @@ bool STAmount::applyOffer(
// Offer has limited funding, limit offer gets and pays by funds available.
saOfferPaysAvailable = saOfferFundsAvailable;
saOfferGetsAvailable = std::min(saOfferGets, multiply(saOfferPaysAvailable, saOfferRate, saOfferGets));
saOfferGetsAvailable = std::min(saOfferGets, mulRound(saOfferPaysAvailable, saOfferRate, saOfferGets, true));
}
cLog(lsINFO) << "applyOffer: saOfferPaysAvailable=" << saOfferFundsAvailable.getFullText();
@@ -1069,14 +1069,14 @@ bool STAmount::applyOffer(
cLog(lsINFO) << "applyOffer: saTakerPaysMax=" << saTakerPaysMax.getFullText();
STAmount saTakerGetsMax = saTakerPaysMax >= saOfferGetsAvailable
? saOfferPaysAvailable // Potentially take entire offer. Avoid math shenanigans.
: std::min(saOfferPaysAvailable, divide(saTakerPaysMax, saOfferRate, saTakerGets)); // Taker a portion of offer.
: std::min(saOfferPaysAvailable, divRound(saTakerPaysMax, saOfferRate, saTakerGets, !saTakerGets.isNative())); // Taker a portion of offer.
cLog(lsINFO) << "applyOffer: saOfferRate=" << saOfferRate.getFullText();
cLog(lsINFO) << "applyOffer: saTakerGetsMax=" << saTakerGetsMax.getFullText();
saTakerGot = std::min(saTakerGets, saTakerGetsMax); // Limit by wanted.
saTakerPaid = saTakerGot == saOfferPaysAvailable
? saOfferGetsAvailable
: std::min(saOfferGetsAvailable, multiply(saTakerGot, saOfferRate, saTakerFunds));
: std::min(saOfferGetsAvailable, mulRound(saTakerGot, saOfferRate, saTakerFunds, true));
cLog(lsINFO) << "applyOffer: saTakerGot=" << saTakerGot.getFullText();
cLog(lsINFO) << "applyOffer: saTakerPaid=" << saTakerPaid.getFullText();
@@ -1093,7 +1093,7 @@ bool STAmount::applyOffer(
cLog(lsINFO) << "applyOffer: saTransferRate=" << saTransferRate.getFullText();
// TakerCost includes transfer fees.
STAmount saTakerCost = STAmount::multiply(saTakerPaid, saTransferRate);
STAmount saTakerCost = STAmount::mulRound(saTakerPaid, saTransferRate, true);
cLog(lsINFO) << "applyOffer: saTakerCost=" << saTakerCost.getFullText();
cLog(lsINFO) << "applyOffer: saTakerFunds=" << saTakerFunds.getFullText();
@@ -1111,7 +1111,7 @@ bool STAmount::applyOffer(
else
{
// Compute fees in a rounding safe way.
STAmount saOfferCost = STAmount::multiply(saTakerGot, STAmount(CURRENCY_ONE, ACCOUNT_ONE, uOfferPaysRate, -9));
STAmount saOfferCost = STAmount::mulRound(saTakerGot, STAmount(CURRENCY_ONE, ACCOUNT_ONE, uOfferPaysRate, -9), true);
saOfferIssuerFee = saOfferCost > saOfferFunds
? saOfferFunds-saTakerGot // Not enough funds to cover fee, stiff issuer the rounding error.

View File

@@ -1306,7 +1306,7 @@ TER RippleCalc::calcNodeDeliverRev(
{
// Adjust output to conform to limited input.
// XXX Verify it is impossible for these to be larger than available funds.
saOutPass = STAmount::divRound(saInPassAct, saOfrRate, saTakerGets, true);
saOutPass = STAmount::divRound(saInPassAct, saOfrRate, saTakerGets, !saTakerGets.isNative());
saOutPlusFees = STAmount::mulRound(saOutPass, saOutFeeRate, true);
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverRev: adjusted: saOutPass=%s saOutPlusFees=%s")
@@ -1447,7 +1447,7 @@ TER RippleCalc::calcNodeDeliverFwd(
STAmount saInTotal = STAmount::mulRound(saInFunded, saInFeeRate, true); // Offer maximum in with fees.
STAmount saInSum = std::min(saInTotal, saInReq-saInAct-saInFees); // In limited by remaining.
STAmount saInPassAct = STAmount::divRound(saInSum, saInFeeRate, true); // In without fees.
STAmount saOutPassMax = STAmount::divRound(saInPassAct, saOfrRate, saTakerGets, true); // Out limited by in remaining.
STAmount saOutPassMax = STAmount::divRound(saInPassAct, saOfrRate, saTakerGets, !saTakerGets.isNative()); // Out limited by in remaining.
STAmount saInPassFeesMax = saInSum-saInPassAct;
@@ -2280,7 +2280,7 @@ TER RippleCalc::calcNodeAccountFwd(
STAmount saIssueCrd = uQualityIn >= QUALITY_ONE
? saPrvIssueReq // No fee.
: STAmount::mulRound(saPrvIssueReq, STAmount(CURRENCY_ONE, ACCOUNT_ONE, uQualityIn, -9), false); // Amount to credit.
: STAmount::mulRound(saPrvIssueReq, STAmount(CURRENCY_ONE, ACCOUNT_ONE, uQualityIn, -9), true); // Amount to credit.
// Amount to credit. Credit for less than received as a surcharge.
saCurReceive = saPrvRedeemReq+saIssueCrd;