From edce4a83ce905ff82ac4aebf296e39b3675d4d8b Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sun, 3 Mar 2013 20:04:32 -0800 Subject: [PATCH 1/5] JS: Add temporary support for RPC tx. --- src/js/remote.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/js/remote.js b/src/js/remote.js index 7eca87f002..c241a8b33e 100644 --- a/src/js/remote.js +++ b/src/js/remote.js @@ -876,6 +876,15 @@ Remote.prototype.request_transaction_entry = function (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) { var request = new Request(this, 'account_info'); From da184a97c47e7415fdb5b9ca5714a4689f4571c5 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sun, 3 Mar 2013 20:52:28 -0800 Subject: [PATCH 2/5] Fix RPC book_offers handling of negative balances and self-issued IOUs. --- src/cpp/ripple/NetworkOPs.cpp | 181 +++++++++++++++++++--------------- 1 file changed, 100 insertions(+), 81 deletions(-) diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index fd3ff143a4..2de3b9cb3e 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -1784,102 +1784,121 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays STAmount saDirRate; // unsigned int iLeft = iLimit; + SLE::pointer sleGetsIssuer = lesActive.entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uTakerGetsIssuerID)); - while (!bDone) { - if (bDirectAdvance) { - bDirectAdvance = false; + if (!sleGetsIssuer) + { + // Order book can not exist if TakerGetsIssuer account does not exist. - cLog(lsTRACE) << boost::str(boost::format("getBookPage: bDirectAdvance")); + nothing(); + } + else + { + while (!bDone) { + if (bDirectAdvance) { + bDirectAdvance = false; - sleOfferDir = lesActive.entryCache(ltDIR_NODE, lpLedger->getNextLedgerIndex(uTipIndex, uBookEnd)); - if (!sleOfferDir) - { - cLog(lsTRACE) << boost::str(boost::format("getBookPage: bDone")); - bDone = true; - } - else - { - uTipIndex = sleOfferDir->getIndex(); - saDirRate = STAmount::setRate(Ledger::getQuality(uTipIndex)); - SLE::pointer sleBookNode; + cLog(lsTRACE) << boost::str(boost::format("getBookPage: bDirectAdvance")); - lesActive.dirFirst(uTipIndex, sleBookNode, uBookEntry, uOfferIndex); + sleOfferDir = lesActive.entryCache(ltDIR_NODE, lpLedger->getNextLedgerIndex(uTipIndex, uBookEnd)); + if (!sleOfferDir) + { + cLog(lsTRACE) << boost::str(boost::format("getBookPage: bDone")); + bDone = true; + } + else + { + uTipIndex = sleOfferDir->getIndex(); + saDirRate = STAmount::setRate(Ledger::getQuality(uTipIndex)); + SLE::pointer sleBookNode; - cLog(lsTRACE) << boost::str(boost::format("getBookPage: uTipIndex=%s") % uTipIndex); - cLog(lsTRACE) << boost::str(boost::format("getBookPage: uOfferIndex=%s") % uOfferIndex); - } - } + lesActive.dirFirst(uTipIndex, sleBookNode, uBookEntry, uOfferIndex); - if (!bDone) - { - SLE::pointer sleOffer = lesActive.entryCache(ltOFFER, uOfferIndex); - const uint160 uOfferOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID(); - STAmount saOwnerFunds; - - boost::unordered_map::const_iterator umBalanceEntry = umBalance.find(uOfferOwnerID); - - if (umBalanceEntry == umBalance.end()) - { - // Did not find balance in table. - STAmount saDefault(uTakerGetsCurrencyID, uTakerGetsIssuerID); - // 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 - { - saOwnerFunds = umBalanceEntry->second; - // cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s (cached)") % saOwnerFunds.getFullText()); + cLog(lsTRACE) << boost::str(boost::format("getBookPage: uTipIndex=%s") % uTipIndex); + cLog(lsTRACE) << boost::str(boost::format("getBookPage: uOfferIndex=%s") % uOfferIndex); + } } - STAmount saTakerGets = sleOffer->getFieldAmount(sfTakerGets); - STAmount saTakerPays = sleOffer->getFieldAmount(sfTakerPays); - - Json::Value jvOffer = sleOffer->getJson(0); - - STAmount saTakerGetsFunded; - - if (saOwnerFunds >= saTakerGets) + if (!bDone) { - // Sufficient funds no shenanigans. - saTakerGetsFunded = saTakerGets; - } - else - { - // cLog(lsINFO) << boost::str(boost::format("getBookPage: saTakerGets=%s") % saTakerGets.getFullText()); - // cLog(lsINFO) << boost::str(boost::format("getBookPage: saTakerPays=%s") % saTakerPays.getFullText()); - // cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s") % saOwnerFunds.getFullText()); - // cLog(lsINFO) << boost::str(boost::format("getBookPage: saDirRate=%s") % saDirRate.getText()); - // cLog(lsINFO) << boost::str(boost::format("getBookPage: multiply=%s") % STAmount::multiply(saTakerGetsFunded, saDirRate).getFullText()); - // cLog(lsINFO) << boost::str(boost::format("getBookPage: multiply=%s") % STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays).getFullText()); - STAmount saTakerPaysFunded; + SLE::pointer sleOffer = lesActive.entryCache(ltOFFER, uOfferIndex); + const uint160 uOfferOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID(); + STAmount saTakerGets = sleOffer->getFieldAmount(sfTakerGets); + STAmount saTakerPays = sleOffer->getFieldAmount(sfTakerPays); + STAmount saOwnerFunds; - saTakerGetsFunded = saOwnerFunds; - saTakerPaysFunded = std::min(saTakerPays, STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays)); + if (uTakerGetsIssuerID == uOfferOwnerID) + { + // If offer is selling issuer's own IOUs, it is fully funded. + saOwnerFunds = saTakerGets; + } + else + { + boost::unordered_map::const_iterator umBalanceEntry = umBalance.find(uOfferOwnerID); - // Only provide, if not fully funded. - jvOffer["taker_gets_funded"] = saTakerGetsFunded.getJson(0); - jvOffer["taker_pays_funded"] = saTakerPaysFunded.getJson(0); - } + if (umBalanceEntry != umBalance.end()) + { + // Found in running balance table. - STAmount saOwnerBalance = saOwnerFunds-saTakerGetsFunded; + saOwnerFunds = umBalanceEntry->second; + // cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s (cached)") % saOwnerFunds.getFullText()); + } + else + { + // Did not find balance in table. - umBalance[uOfferOwnerID] = saOwnerBalance; + saOwnerFunds = lesActive.accountHolds(uOfferOwnerID, uTakerGetsCurrencyID, uTakerGetsIssuerID); + // cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s (new)") % saOwnerFunds.getFullText()); + if (saOwnerFunds.isNegative()) + saOwnerFunds.zero(); + } + } - if (!saOwnerFunds.isZero() || uOfferOwnerID == uTakerID) - { - // Only provide funded offers and offers of the taker. - jvOffers.append(jvOffer); - } + Json::Value jvOffer = sleOffer->getJson(0); - if (!lesActive.dirNext(uTipIndex, sleOfferDir, uBookEntry, uOfferIndex)) - { - bDirectAdvance = true; - } - else - { - cLog(lsTRACE) << boost::str(boost::format("getBookPage: uOfferIndex=%s") % uOfferIndex); + STAmount saTakerGetsFunded; + + if (saOwnerFunds >= saTakerGets) + { + // Sufficient funds no shenanigans. + saTakerGetsFunded = saTakerGets; + } + else + { + // cLog(lsINFO) << boost::str(boost::format("getBookPage: saTakerGets=%s") % saTakerGets.getFullText()); + // cLog(lsINFO) << boost::str(boost::format("getBookPage: saTakerPays=%s") % saTakerPays.getFullText()); + // cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s") % saOwnerFunds.getFullText()); + // cLog(lsINFO) << boost::str(boost::format("getBookPage: saDirRate=%s") % saDirRate.getText()); + // cLog(lsINFO) << boost::str(boost::format("getBookPage: multiply=%s") % STAmount::multiply(saTakerGetsFunded, saDirRate).getFullText()); + // cLog(lsINFO) << boost::str(boost::format("getBookPage: multiply=%s") % STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays).getFullText()); + STAmount saTakerPaysFunded; + + saTakerGetsFunded = saOwnerFunds; + saTakerPaysFunded = std::min(saTakerPays, STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays)); + + // Only provide, if not fully funded. + jvOffer["taker_gets_funded"] = saTakerGetsFunded.getJson(0); + jvOffer["taker_pays_funded"] = saTakerPaysFunded.getJson(0); + } + + STAmount saOwnerBalance = saOwnerFunds-saTakerGetsFunded; + + umBalance[uOfferOwnerID] = saOwnerBalance; + + if (!saOwnerFunds.isZero() || uOfferOwnerID == uTakerID) + { + // Only provide funded offers and offers of the taker. + jvOffers.append(jvOffer); + } + + if (!lesActive.dirNext(uTipIndex, sleOfferDir, uBookEntry, uOfferIndex)) + { + bDirectAdvance = true; + } + else + { + cLog(lsTRACE) << boost::str(boost::format("getBookPage: uOfferIndex=%s") % uOfferIndex); + } } } } From 49458bff57650bf5593f95de928c1c6194b236c2 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sun, 3 Mar 2013 21:31:34 -0800 Subject: [PATCH 3/5] Add support for transfer fees to RPC book_offers. --- src/cpp/ripple/LedgerEntrySet.cpp | 2 + src/cpp/ripple/NetworkOPs.cpp | 202 ++++++++++++++++-------------- 2 files changed, 111 insertions(+), 93 deletions(-) diff --git a/src/cpp/ripple/LedgerEntrySet.cpp b/src/cpp/ripple/LedgerEntrySet.cpp index e47ed099d9..09ecc4ab7e 100644 --- a/src/cpp/ripple/LedgerEntrySet.cpp +++ b/src/cpp/ripple/LedgerEntrySet.cpp @@ -1066,6 +1066,8 @@ STAmount LedgerEntrySet::rippleHolds(const uint160& uAccountID, const uint160& u return saBalance; } +// Returns the amount an account can spend without going into debt. +// // <-- saAmount: amount of uCurrencyID held by uAccountID. May be negative. STAmount LedgerEntrySet::accountHolds(const uint160& uAccountID, const uint160& uCurrencyID, const uint160& uIssuerID) { diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 2de3b9cb3e..a3106768d0 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -1784,121 +1784,137 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays STAmount saDirRate; // unsigned int iLeft = iLimit; - SLE::pointer sleGetsIssuer = lesActive.entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uTakerGetsIssuerID)); - if (!sleGetsIssuer) - { - // Order book can not exist if TakerGetsIssuer account does not exist. + uint32 uTransferRate = lesActive.rippleTransferRate(uTakerGetsIssuerID); - nothing(); - } - else - { - while (!bDone) { - if (bDirectAdvance) { - bDirectAdvance = false; + while (!bDone) { + if (bDirectAdvance) { + bDirectAdvance = false; - cLog(lsTRACE) << boost::str(boost::format("getBookPage: bDirectAdvance")); + cLog(lsTRACE) << boost::str(boost::format("getBookPage: bDirectAdvance")); - sleOfferDir = lesActive.entryCache(ltDIR_NODE, lpLedger->getNextLedgerIndex(uTipIndex, uBookEnd)); - if (!sleOfferDir) + sleOfferDir = lesActive.entryCache(ltDIR_NODE, lpLedger->getNextLedgerIndex(uTipIndex, uBookEnd)); + if (!sleOfferDir) + { + cLog(lsTRACE) << boost::str(boost::format("getBookPage: bDone")); + bDone = true; + } + else + { + uTipIndex = sleOfferDir->getIndex(); + saDirRate = STAmount::setRate(Ledger::getQuality(uTipIndex)); + SLE::pointer sleBookNode; + + lesActive.dirFirst(uTipIndex, sleBookNode, uBookEntry, uOfferIndex); + + cLog(lsTRACE) << boost::str(boost::format("getBookPage: uTipIndex=%s") % uTipIndex); + cLog(lsTRACE) << boost::str(boost::format("getBookPage: uOfferIndex=%s") % uOfferIndex); + } + } + + if (!bDone) + { + SLE::pointer sleOffer = lesActive.entryCache(ltOFFER, uOfferIndex); + const uint160 uOfferOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID(); + STAmount saTakerGets = sleOffer->getFieldAmount(sfTakerGets); + STAmount saTakerPays = sleOffer->getFieldAmount(sfTakerPays); + STAmount saOwnerFunds; + + if (uTakerGetsIssuerID == uOfferOwnerID) + { + // If offer is selling issuer's own IOUs, it is fully funded. + saOwnerFunds = saTakerGets; + } + else + { + boost::unordered_map::const_iterator umBalanceEntry = umBalance.find(uOfferOwnerID); + + if (umBalanceEntry != umBalance.end()) { - cLog(lsTRACE) << boost::str(boost::format("getBookPage: bDone")); - bDone = true; + // Found in running balance table. + + saOwnerFunds = umBalanceEntry->second; + // cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s (cached)") % saOwnerFunds.getFullText()); } else { - uTipIndex = sleOfferDir->getIndex(); - saDirRate = STAmount::setRate(Ledger::getQuality(uTipIndex)); - SLE::pointer sleBookNode; + // Did not find balance in table. - lesActive.dirFirst(uTipIndex, sleBookNode, uBookEntry, uOfferIndex); + saOwnerFunds = lesActive.accountHolds(uOfferOwnerID, uTakerGetsCurrencyID, uTakerGetsIssuerID); + // cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s (new)") % saOwnerFunds.getFullText()); + if (saOwnerFunds.isNegative()) + { + // Treat negative funds as zero. - cLog(lsTRACE) << boost::str(boost::format("getBookPage: uTipIndex=%s") % uTipIndex); - cLog(lsTRACE) << boost::str(boost::format("getBookPage: uOfferIndex=%s") % uOfferIndex); + saOwnerFunds.zero(); + } } } - if (!bDone) + Json::Value jvOffer = sleOffer->getJson(0); + + STAmount saTakerGetsFunded; + STAmount saOwnerFundsLimit; + uint32 uOfferRate; + + + 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 { - SLE::pointer sleOffer = lesActive.entryCache(ltOFFER, uOfferIndex); - const uint160 uOfferOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID(); - STAmount saTakerGets = sleOffer->getFieldAmount(sfTakerGets); - STAmount saTakerPays = sleOffer->getFieldAmount(sfTakerPays); - STAmount saOwnerFunds; + uOfferRate = QUALITY_ONE; + saOwnerFundsLimit = saOwnerFunds; + } - if (uTakerGetsIssuerID == uOfferOwnerID) - { - // If offer is selling issuer's own IOUs, it is fully funded. - saOwnerFunds = saTakerGets; - } - else - { - boost::unordered_map::const_iterator umBalanceEntry = umBalance.find(uOfferOwnerID); + if (saOwnerFundsLimit >= saTakerGets) + { + // Sufficient funds no shenanigans. + saTakerGetsFunded = saTakerGets; + } + else + { + // cLog(lsINFO) << boost::str(boost::format("getBookPage: saTakerGets=%s") % saTakerGets.getFullText()); + // cLog(lsINFO) << boost::str(boost::format("getBookPage: saTakerPays=%s") % saTakerPays.getFullText()); + // cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s") % saOwnerFunds.getFullText()); + // cLog(lsINFO) << boost::str(boost::format("getBookPage: saDirRate=%s") % saDirRate.getText()); + // cLog(lsINFO) << boost::str(boost::format("getBookPage: multiply=%s") % STAmount::multiply(saTakerGetsFunded, saDirRate).getFullText()); + // cLog(lsINFO) << boost::str(boost::format("getBookPage: multiply=%s") % STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays).getFullText()); + STAmount saTakerPaysFunded; - if (umBalanceEntry != umBalance.end()) - { - // Found in running balance table. + saTakerGetsFunded = saOwnerFundsLimit; + saTakerPaysFunded = std::min(saTakerPays, STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays)); - saOwnerFunds = umBalanceEntry->second; - // cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s (cached)") % saOwnerFunds.getFullText()); - } - else - { - // Did not find balance in table. + // Only provide, if not fully funded. + jvOffer["taker_gets_funded"] = saTakerGetsFunded.getJson(0); + jvOffer["taker_pays_funded"] = saTakerPaysFunded.getJson(0); - saOwnerFunds = lesActive.accountHolds(uOfferOwnerID, uTakerGetsCurrencyID, uTakerGetsIssuerID); - // cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s (new)") % saOwnerFunds.getFullText()); - if (saOwnerFunds.isNegative()) - saOwnerFunds.zero(); - } - } + } + STAmount saOwnerPays = QUALITY_ONE == uOfferRate + ? saTakerGetsFunded + : std::min(saOwnerFunds, STAmount::multiply(saTakerGetsFunded, STAmount(CURRENCY_ONE, ACCOUNT_ONE, uOfferRate, -9))); - Json::Value jvOffer = sleOffer->getJson(0); + STAmount saOwnerBalance = saOwnerFunds-saOwnerPays; - STAmount saTakerGetsFunded; + umBalance[uOfferOwnerID] = saOwnerBalance; - if (saOwnerFunds >= saTakerGets) - { - // Sufficient funds no shenanigans. - saTakerGetsFunded = saTakerGets; - } - else - { - // cLog(lsINFO) << boost::str(boost::format("getBookPage: saTakerGets=%s") % saTakerGets.getFullText()); - // cLog(lsINFO) << boost::str(boost::format("getBookPage: saTakerPays=%s") % saTakerPays.getFullText()); - // cLog(lsINFO) << boost::str(boost::format("getBookPage: saOwnerFunds=%s") % saOwnerFunds.getFullText()); - // cLog(lsINFO) << boost::str(boost::format("getBookPage: saDirRate=%s") % saDirRate.getText()); - // cLog(lsINFO) << boost::str(boost::format("getBookPage: multiply=%s") % STAmount::multiply(saTakerGetsFunded, saDirRate).getFullText()); - // cLog(lsINFO) << boost::str(boost::format("getBookPage: multiply=%s") % STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays).getFullText()); - STAmount saTakerPaysFunded; + if (!saOwnerFunds.isZero() || uOfferOwnerID == uTakerID) + { + // Only provide funded offers and offers of the taker. + jvOffers.append(jvOffer); + } - saTakerGetsFunded = saOwnerFunds; - saTakerPaysFunded = std::min(saTakerPays, STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays)); - - // Only provide, if not fully funded. - jvOffer["taker_gets_funded"] = saTakerGetsFunded.getJson(0); - jvOffer["taker_pays_funded"] = saTakerPaysFunded.getJson(0); - } - - STAmount saOwnerBalance = saOwnerFunds-saTakerGetsFunded; - - umBalance[uOfferOwnerID] = saOwnerBalance; - - if (!saOwnerFunds.isZero() || uOfferOwnerID == uTakerID) - { - // Only provide funded offers and offers of the taker. - jvOffers.append(jvOffer); - } - - if (!lesActive.dirNext(uTipIndex, sleOfferDir, uBookEntry, uOfferIndex)) - { - bDirectAdvance = true; - } - else - { - cLog(lsTRACE) << boost::str(boost::format("getBookPage: uOfferIndex=%s") % uOfferIndex); - } + if (!lesActive.dirNext(uTipIndex, sleOfferDir, uBookEntry, uOfferIndex)) + { + bDirectAdvance = true; + } + else + { + cLog(lsTRACE) << boost::str(boost::format("getBookPage: uOfferIndex=%s") % uOfferIndex); } } } From 522d4f642a0eacca56c5f92a88dc8f22e9d8b6fb Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sun, 3 Mar 2013 22:35:00 -0800 Subject: [PATCH 4/5] JS: Rename ADDRESS_ to ACCOUNT_ to be consistent with C++. --- src/js/uint.js | 4 ++-- src/js/uint160.js | 4 ++-- src/js/uint256.js | 3 --- test/amount-test.js | 6 +++--- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/js/uint.js b/src/js/uint.js index d95ccb51fa..457e3e9590 100644 --- a/src/js/uint.js +++ b/src/js/uint.js @@ -106,14 +106,14 @@ UInt.prototype.parse_generic = function (j) { case undefined: case "0": case this.constructor.STR_ZERO: - case this.constructor.ADDRESS_ZERO: + case this.constructor.ACCOUNT_ZERO: case this.constructor.HEX_ZERO: this._value = nbi(); break; case "1": case this.constructor.STR_ONE: - case this.constructor.ADDRESS_ONE: + case this.constructor.ACCOUNT_ONE: case this.constructor.HEX_ONE: this._value = new BigInteger([1]); diff --git a/src/js/uint160.js b/src/js/uint160.js index 12c7ff04c6..66c980ec0e 100644 --- a/src/js/uint160.js +++ b/src/js/uint160.js @@ -24,8 +24,8 @@ UInt160.width = 20; UInt160.prototype = extend({}, UInt.prototype); UInt160.prototype.constructor = UInt160; -var ADDRESS_ZERO = UInt160.ADDRESS_ZERO = "rrrrrrrrrrrrrrrrrrrrrhoLvTp"; -var ADDRESS_ONE = UInt160.ADDRESS_ONE = "rrrrrrrrrrrrrrrrrrrrBZbvji"; +var ACCOUNT_ZERO = UInt160.ACCOUNT_ZERO = "rrrrrrrrrrrrrrrrrrrrrhoLvTp"; +var ACCOUNT_ONE = UInt160.ACCOUNT_ONE = "rrrrrrrrrrrrrrrrrrrrBZbvji"; var HEX_ZERO = UInt160.HEX_ZERO = "0000000000000000000000000000000000000000"; var HEX_ONE = UInt160.HEX_ONE = "0000000000000000000000000000000000000001"; var STR_ZERO = UInt160.STR_ZERO = utils.hexToString(HEX_ZERO); diff --git a/src/js/uint256.js b/src/js/uint256.js index ab5b6f70b6..42b01504a4 100644 --- a/src/js/uint256.js +++ b/src/js/uint256.js @@ -24,9 +24,6 @@ UInt256.width = 32; UInt256.prototype = extend({}, UInt.prototype); 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" + "00000000000000000000000000000000"; var HEX_ONE = UInt256.HEX_ONE = "00000000000000000000000000000000" + diff --git a/test/amount-test.js b/test/amount-test.js index 31fa7ba085..6a62aff24f 100644 --- a/test/amount-test.js +++ b/test/amount-test.js @@ -17,16 +17,16 @@ buster.testCase("Amount", { buster.assert.equals(nbi(), UInt160.from_generic("0")._value); }, "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 () { buster.assert.equals(new BigInteger([1]), UInt160.from_generic("1")._value); }, "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 () { - 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 () { buster.assert.equals(config.accounts["mtgox"].account, UInt160.from_json("mtgox").to_json()); From 2bb4501553500acce85859e02f2d2fc47229e5df Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sun, 3 Mar 2013 23:01:19 -0800 Subject: [PATCH 5/5] Add tfMarket support to OfferCreate. --- src/cpp/ripple/OfferCreateTransactor.cpp | 2 ++ src/cpp/ripple/TransactionFormats.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cpp/ripple/OfferCreateTransactor.cpp b/src/cpp/ripple/OfferCreateTransactor.cpp index d2acfe9250..e4b59be8c5 100644 --- a/src/cpp/ripple/OfferCreateTransactor.cpp +++ b/src/cpp/ripple/OfferCreateTransactor.cpp @@ -321,6 +321,7 @@ TER OfferCreateTransactor::doApply() cLog(lsWARNING) << "OfferCreate> " << mTxn.getJson(0); const uint32 uTxFlags = mTxn.getFlags(); const bool bPassive = isSetBit(uTxFlags, tfPassive); + const bool bMarket = isSetBit(uTxFlags, tfMarket); STAmount saTakerPays = mTxn.getFieldAmount(sfTakerPays); STAmount saTakerGets = mTxn.getFieldAmount(sfTakerGets); @@ -460,6 +461,7 @@ TER OfferCreateTransactor::doApply() if (tesSUCCESS != terResult || !saTakerPays // Wants nothing more. || !saTakerGets // Offering nothing more. + || bMarket // Do not persist. || !mEngine->getNodes().accountFunds(mTxnAccountID, saTakerGets).isPositive() // Not funded. || bUnfunded) // Consider unfunded. { diff --git a/src/cpp/ripple/TransactionFormats.h b/src/cpp/ripple/TransactionFormats.h index 7e69ce7416..a1c9161bb2 100644 --- a/src/cpp/ripple/TransactionFormats.h +++ b/src/cpp/ripple/TransactionFormats.h @@ -68,7 +68,8 @@ const uint32 tfAccountSetMask = ~(tfRequireDestTag|tfOptionalDestTag|tfRequireA // OfferCreate flags: const uint32 tfPassive = 0x00010000; -const uint32 tfOfferCreateMask = ~(tfPassive); +const uint32 tfMarket = 0x00020000; +const uint32 tfOfferCreateMask = ~(tfPassive|tfMarket); // Payment flags: const uint32 tfNoRippleDirect = 0x00010000;