mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-27 06:25:51 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
@@ -1066,6 +1066,8 @@ STAmount LedgerEntrySet::rippleHolds(const uint160& uAccountID, const uint160& u
|
|||||||
return saBalance;
|
return saBalance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the amount an account can spend without going into debt.
|
||||||
|
//
|
||||||
// <-- saAmount: amount of uCurrencyID held by uAccountID. May be negative.
|
// <-- saAmount: amount of uCurrencyID held by uAccountID. May be negative.
|
||||||
STAmount LedgerEntrySet::accountHolds(const uint160& uAccountID, const uint160& uCurrencyID, const uint160& uIssuerID)
|
STAmount LedgerEntrySet::accountHolds(const uint160& uAccountID, const uint160& uCurrencyID, const uint160& uIssuerID)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1785,6 +1785,8 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays
|
|||||||
|
|
||||||
// unsigned int iLeft = iLimit;
|
// unsigned int iLeft = iLimit;
|
||||||
|
|
||||||
|
uint32 uTransferRate = lesActive.rippleTransferRate(uTakerGetsIssuerID);
|
||||||
|
|
||||||
while (!bDone) {
|
while (!bDone) {
|
||||||
if (bDirectAdvance) {
|
if (bDirectAdvance) {
|
||||||
bDirectAdvance = false;
|
bDirectAdvance = false;
|
||||||
@@ -1814,33 +1816,62 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays
|
|||||||
{
|
{
|
||||||
SLE::pointer sleOffer = lesActive.entryCache(ltOFFER, uOfferIndex);
|
SLE::pointer sleOffer = lesActive.entryCache(ltOFFER, uOfferIndex);
|
||||||
const uint160 uOfferOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID();
|
const uint160 uOfferOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID();
|
||||||
|
STAmount saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
|
||||||
|
STAmount saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
|
||||||
STAmount saOwnerFunds;
|
STAmount saOwnerFunds;
|
||||||
|
|
||||||
boost::unordered_map<uint160, STAmount>::const_iterator umBalanceEntry = umBalance.find(uOfferOwnerID);
|
if (uTakerGetsIssuerID == uOfferOwnerID)
|
||||||
|
|
||||||
if (umBalanceEntry == umBalance.end())
|
|
||||||
{
|
{
|
||||||
// Did not find balance in table.
|
// If offer is selling issuer's own IOUs, it is fully funded.
|
||||||
STAmount saDefault(uTakerGetsCurrencyID, uTakerGetsIssuerID);
|
saOwnerFunds = saTakerGets;
|
||||||
// cLog(lsINFO) << boost::str(boost::format("getBookPage: saDefault=%s") % saDefault.getFullText());
|
|
||||||
|
|
||||||
saOwnerFunds = lesActive.accountFunds(uOfferOwnerID, saDefault);
|
|
||||||
// cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s (new)") % saOwnerFunds.getFullText());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
boost::unordered_map<uint160, STAmount>::const_iterator umBalanceEntry = umBalance.find(uOfferOwnerID);
|
||||||
|
|
||||||
|
if (umBalanceEntry != umBalance.end())
|
||||||
|
{
|
||||||
|
// Found in running balance table.
|
||||||
|
|
||||||
saOwnerFunds = umBalanceEntry->second;
|
saOwnerFunds = umBalanceEntry->second;
|
||||||
// cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s (cached)") % saOwnerFunds.getFullText());
|
// cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s (cached)") % saOwnerFunds.getFullText());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Did not find balance in table.
|
||||||
|
|
||||||
STAmount saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
|
saOwnerFunds = lesActive.accountHolds(uOfferOwnerID, uTakerGetsCurrencyID, uTakerGetsIssuerID);
|
||||||
STAmount saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
|
// cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s (new)") % saOwnerFunds.getFullText());
|
||||||
|
if (saOwnerFunds.isNegative())
|
||||||
|
{
|
||||||
|
// Treat negative funds as zero.
|
||||||
|
|
||||||
|
saOwnerFunds.zero();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Json::Value jvOffer = sleOffer->getJson(0);
|
Json::Value jvOffer = sleOffer->getJson(0);
|
||||||
|
|
||||||
STAmount saTakerGetsFunded;
|
STAmount saTakerGetsFunded;
|
||||||
|
STAmount saOwnerFundsLimit;
|
||||||
|
uint32 uOfferRate;
|
||||||
|
|
||||||
if (saOwnerFunds >= saTakerGets)
|
|
||||||
|
if (uTransferRate != QUALITY_ONE // Have a tranfer fee.
|
||||||
|
&& uTakerID != uTakerGetsIssuerID // Not taking offers of own IOUs.
|
||||||
|
&& uTakerGetsIssuerID != uOfferOwnerID) { // Offer owner not issuing ownfunds
|
||||||
|
// Need to charge a transfer fee to offer owner.
|
||||||
|
uOfferRate = uTransferRate;
|
||||||
|
saOwnerFundsLimit = STAmount::divide(saOwnerFunds, STAmount(CURRENCY_ONE, ACCOUNT_ONE, uOfferRate, -9));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uOfferRate = QUALITY_ONE;
|
||||||
|
saOwnerFundsLimit = saOwnerFunds;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saOwnerFundsLimit >= saTakerGets)
|
||||||
{
|
{
|
||||||
// Sufficient funds no shenanigans.
|
// Sufficient funds no shenanigans.
|
||||||
saTakerGetsFunded = saTakerGets;
|
saTakerGetsFunded = saTakerGets;
|
||||||
@@ -1855,15 +1886,19 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays
|
|||||||
// cLog(lsINFO) << boost::str(boost::format("getBookPage: multiply=%s") % STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays).getFullText());
|
// cLog(lsINFO) << boost::str(boost::format("getBookPage: multiply=%s") % STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays).getFullText());
|
||||||
STAmount saTakerPaysFunded;
|
STAmount saTakerPaysFunded;
|
||||||
|
|
||||||
saTakerGetsFunded = saOwnerFunds;
|
saTakerGetsFunded = saOwnerFundsLimit;
|
||||||
saTakerPaysFunded = std::min(saTakerPays, STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays));
|
saTakerPaysFunded = std::min(saTakerPays, STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays));
|
||||||
|
|
||||||
// Only provide, if not fully funded.
|
// Only provide, if not fully funded.
|
||||||
jvOffer["taker_gets_funded"] = saTakerGetsFunded.getJson(0);
|
jvOffer["taker_gets_funded"] = saTakerGetsFunded.getJson(0);
|
||||||
jvOffer["taker_pays_funded"] = saTakerPaysFunded.getJson(0);
|
jvOffer["taker_pays_funded"] = saTakerPaysFunded.getJson(0);
|
||||||
}
|
|
||||||
|
|
||||||
STAmount saOwnerBalance = saOwnerFunds-saTakerGetsFunded;
|
}
|
||||||
|
STAmount saOwnerPays = QUALITY_ONE == uOfferRate
|
||||||
|
? saTakerGetsFunded
|
||||||
|
: std::min(saOwnerFunds, STAmount::multiply(saTakerGetsFunded, STAmount(CURRENCY_ONE, ACCOUNT_ONE, uOfferRate, -9)));
|
||||||
|
|
||||||
|
STAmount saOwnerBalance = saOwnerFunds-saOwnerPays;
|
||||||
|
|
||||||
umBalance[uOfferOwnerID] = saOwnerBalance;
|
umBalance[uOfferOwnerID] = saOwnerBalance;
|
||||||
|
|
||||||
|
|||||||
@@ -321,6 +321,7 @@ TER OfferCreateTransactor::doApply()
|
|||||||
cLog(lsWARNING) << "OfferCreate> " << mTxn.getJson(0);
|
cLog(lsWARNING) << "OfferCreate> " << mTxn.getJson(0);
|
||||||
const uint32 uTxFlags = mTxn.getFlags();
|
const uint32 uTxFlags = mTxn.getFlags();
|
||||||
const bool bPassive = isSetBit(uTxFlags, tfPassive);
|
const bool bPassive = isSetBit(uTxFlags, tfPassive);
|
||||||
|
const bool bMarket = isSetBit(uTxFlags, tfMarket);
|
||||||
STAmount saTakerPays = mTxn.getFieldAmount(sfTakerPays);
|
STAmount saTakerPays = mTxn.getFieldAmount(sfTakerPays);
|
||||||
STAmount saTakerGets = mTxn.getFieldAmount(sfTakerGets);
|
STAmount saTakerGets = mTxn.getFieldAmount(sfTakerGets);
|
||||||
|
|
||||||
@@ -460,6 +461,7 @@ TER OfferCreateTransactor::doApply()
|
|||||||
if (tesSUCCESS != terResult
|
if (tesSUCCESS != terResult
|
||||||
|| !saTakerPays // Wants nothing more.
|
|| !saTakerPays // Wants nothing more.
|
||||||
|| !saTakerGets // Offering nothing more.
|
|| !saTakerGets // Offering nothing more.
|
||||||
|
|| bMarket // Do not persist.
|
||||||
|| !mEngine->getNodes().accountFunds(mTxnAccountID, saTakerGets).isPositive() // Not funded.
|
|| !mEngine->getNodes().accountFunds(mTxnAccountID, saTakerGets).isPositive() // Not funded.
|
||||||
|| bUnfunded) // Consider unfunded.
|
|| bUnfunded) // Consider unfunded.
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -68,7 +68,8 @@ const uint32 tfAccountSetMask = ~(tfRequireDestTag|tfOptionalDestTag|tfRequireA
|
|||||||
|
|
||||||
// OfferCreate flags:
|
// OfferCreate flags:
|
||||||
const uint32 tfPassive = 0x00010000;
|
const uint32 tfPassive = 0x00010000;
|
||||||
const uint32 tfOfferCreateMask = ~(tfPassive);
|
const uint32 tfMarket = 0x00020000;
|
||||||
|
const uint32 tfOfferCreateMask = ~(tfPassive|tfMarket);
|
||||||
|
|
||||||
// Payment flags:
|
// Payment flags:
|
||||||
const uint32 tfNoRippleDirect = 0x00010000;
|
const uint32 tfNoRippleDirect = 0x00010000;
|
||||||
|
|||||||
@@ -876,6 +876,15 @@ Remote.prototype.request_transaction_entry = function (hash) {
|
|||||||
.tx_hash(hash);
|
.tx_hash(hash);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// DEPRECATED: use request_transaction_entry
|
||||||
|
Remote.prototype.request_tx = function (hash) {
|
||||||
|
var request = new Request(this, 'tx');
|
||||||
|
|
||||||
|
request.message.transaction = hash;
|
||||||
|
|
||||||
|
return request;
|
||||||
|
};
|
||||||
|
|
||||||
Remote.prototype.request_account_info = function (accountID) {
|
Remote.prototype.request_account_info = function (accountID) {
|
||||||
var request = new Request(this, 'account_info');
|
var request = new Request(this, 'account_info');
|
||||||
|
|
||||||
|
|||||||
@@ -106,14 +106,14 @@ UInt.prototype.parse_generic = function (j) {
|
|||||||
case undefined:
|
case undefined:
|
||||||
case "0":
|
case "0":
|
||||||
case this.constructor.STR_ZERO:
|
case this.constructor.STR_ZERO:
|
||||||
case this.constructor.ADDRESS_ZERO:
|
case this.constructor.ACCOUNT_ZERO:
|
||||||
case this.constructor.HEX_ZERO:
|
case this.constructor.HEX_ZERO:
|
||||||
this._value = nbi();
|
this._value = nbi();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "1":
|
case "1":
|
||||||
case this.constructor.STR_ONE:
|
case this.constructor.STR_ONE:
|
||||||
case this.constructor.ADDRESS_ONE:
|
case this.constructor.ACCOUNT_ONE:
|
||||||
case this.constructor.HEX_ONE:
|
case this.constructor.HEX_ONE:
|
||||||
this._value = new BigInteger([1]);
|
this._value = new BigInteger([1]);
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ UInt160.width = 20;
|
|||||||
UInt160.prototype = extend({}, UInt.prototype);
|
UInt160.prototype = extend({}, UInt.prototype);
|
||||||
UInt160.prototype.constructor = UInt160;
|
UInt160.prototype.constructor = UInt160;
|
||||||
|
|
||||||
var ADDRESS_ZERO = UInt160.ADDRESS_ZERO = "rrrrrrrrrrrrrrrrrrrrrhoLvTp";
|
var ACCOUNT_ZERO = UInt160.ACCOUNT_ZERO = "rrrrrrrrrrrrrrrrrrrrrhoLvTp";
|
||||||
var ADDRESS_ONE = UInt160.ADDRESS_ONE = "rrrrrrrrrrrrrrrrrrrrBZbvji";
|
var ACCOUNT_ONE = UInt160.ACCOUNT_ONE = "rrrrrrrrrrrrrrrrrrrrBZbvji";
|
||||||
var HEX_ZERO = UInt160.HEX_ZERO = "0000000000000000000000000000000000000000";
|
var HEX_ZERO = UInt160.HEX_ZERO = "0000000000000000000000000000000000000000";
|
||||||
var HEX_ONE = UInt160.HEX_ONE = "0000000000000000000000000000000000000001";
|
var HEX_ONE = UInt160.HEX_ONE = "0000000000000000000000000000000000000001";
|
||||||
var STR_ZERO = UInt160.STR_ZERO = utils.hexToString(HEX_ZERO);
|
var STR_ZERO = UInt160.STR_ZERO = utils.hexToString(HEX_ZERO);
|
||||||
|
|||||||
@@ -24,9 +24,6 @@ UInt256.width = 32;
|
|||||||
UInt256.prototype = extend({}, UInt.prototype);
|
UInt256.prototype = extend({}, UInt.prototype);
|
||||||
UInt256.prototype.constructor = UInt256;
|
UInt256.prototype.constructor = UInt256;
|
||||||
|
|
||||||
// XXX Generate these constants (or remove them)
|
|
||||||
var ADDRESS_ZERO = UInt256.ADDRESS_ZERO = "XXX";
|
|
||||||
var ADDRESS_ONE = UInt256.ADDRESS_ONE = "XXX";
|
|
||||||
var HEX_ZERO = UInt256.HEX_ZERO = "00000000000000000000000000000000" +
|
var HEX_ZERO = UInt256.HEX_ZERO = "00000000000000000000000000000000" +
|
||||||
"00000000000000000000000000000000";
|
"00000000000000000000000000000000";
|
||||||
var HEX_ONE = UInt256.HEX_ONE = "00000000000000000000000000000000" +
|
var HEX_ONE = UInt256.HEX_ONE = "00000000000000000000000000000000" +
|
||||||
|
|||||||
@@ -17,16 +17,16 @@ buster.testCase("Amount", {
|
|||||||
buster.assert.equals(nbi(), UInt160.from_generic("0")._value);
|
buster.assert.equals(nbi(), UInt160.from_generic("0")._value);
|
||||||
},
|
},
|
||||||
"Parse 0 export" : function () {
|
"Parse 0 export" : function () {
|
||||||
buster.assert.equals(UInt160.ADDRESS_ZERO, UInt160.from_generic("0").to_json());
|
buster.assert.equals(UInt160.ACCOUNT_ZERO, UInt160.from_generic("0").to_json());
|
||||||
},
|
},
|
||||||
"Parse 1" : function () {
|
"Parse 1" : function () {
|
||||||
buster.assert.equals(new BigInteger([1]), UInt160.from_generic("1")._value);
|
buster.assert.equals(new BigInteger([1]), UInt160.from_generic("1")._value);
|
||||||
},
|
},
|
||||||
"Parse rrrrrrrrrrrrrrrrrrrrrhoLvTp export" : function () {
|
"Parse rrrrrrrrrrrrrrrrrrrrrhoLvTp export" : function () {
|
||||||
buster.assert.equals(UInt160.ADDRESS_ZERO, UInt160.from_json("rrrrrrrrrrrrrrrrrrrrrhoLvTp").to_json());
|
buster.assert.equals(UInt160.ACCOUNT_ZERO, UInt160.from_json("rrrrrrrrrrrrrrrrrrrrrhoLvTp").to_json());
|
||||||
},
|
},
|
||||||
"Parse rrrrrrrrrrrrrrrrrrrrBZbvji export" : function () {
|
"Parse rrrrrrrrrrrrrrrrrrrrBZbvji export" : function () {
|
||||||
buster.assert.equals(UInt160.ADDRESS_ONE, UInt160.from_json("rrrrrrrrrrrrrrrrrrrrBZbvji").to_json());
|
buster.assert.equals(UInt160.ACCOUNT_ONE, UInt160.from_json("rrrrrrrrrrrrrrrrrrrrBZbvji").to_json());
|
||||||
},
|
},
|
||||||
"Parse mtgox export" : function () {
|
"Parse mtgox export" : function () {
|
||||||
buster.assert.equals(config.accounts["mtgox"].account, UInt160.from_json("mtgox").to_json());
|
buster.assert.equals(config.accounts["mtgox"].account, UInt160.from_json("mtgox").to_json());
|
||||||
|
|||||||
Reference in New Issue
Block a user