mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
@@ -651,10 +651,10 @@ STAmount operator-(const STAmount& v1, const STAmount& v2)
|
||||
return STAmount(v1.name, v1.mCurrency, -fv, ov1, true);
|
||||
}
|
||||
|
||||
STAmount STAmount::divide(const STAmount& num, const STAmount& den, const uint160& currencyOut)
|
||||
STAmount STAmount::divide(const STAmount& num, const STAmount& den, const uint160& uCurrencyID, const uint160& uIssuerID)
|
||||
{
|
||||
if (den.isZero()) throw std::runtime_error("division by zero");
|
||||
if (num.isZero()) return STAmount(currencyOut);
|
||||
if (num.isZero()) return STAmount(uCurrencyID, uIssuerID);
|
||||
|
||||
uint64 numVal = num.mValue, denVal = den.mValue;
|
||||
int numOffset = num.mOffset, denOffset = den.mOffset;
|
||||
@@ -690,14 +690,14 @@ STAmount STAmount::divide(const STAmount& num, const STAmount& den, const uint16
|
||||
assert(BN_num_bytes(&v) <= 64);
|
||||
|
||||
if (num.mIsNegative != den.mIsNegative)
|
||||
return -STAmount(currencyOut, v.getulong(), finOffset);
|
||||
else return STAmount(currencyOut, v.getulong(), finOffset);
|
||||
return -STAmount(uCurrencyID, uIssuerID, v.getulong(), finOffset);
|
||||
else return STAmount(uCurrencyID, uIssuerID, v.getulong(), finOffset);
|
||||
}
|
||||
|
||||
STAmount STAmount::multiply(const STAmount& v1, const STAmount& v2, const uint160& currencyOut)
|
||||
STAmount STAmount::multiply(const STAmount& v1, const STAmount& v2, const uint160& uCurrencyID, const uint160& uIssuerID)
|
||||
{
|
||||
if (v1.isZero() || v2.isZero())
|
||||
return STAmount(currencyOut);
|
||||
return STAmount(uCurrencyID, uIssuerID);
|
||||
|
||||
if (v1.mIsNative && v2.mIsNative) // FIXME: overflow
|
||||
return STAmount(v1.name, v1.getSNValue() * v2.getSNValue());
|
||||
@@ -753,8 +753,8 @@ STAmount STAmount::multiply(const STAmount& v1, const STAmount& v2, const uint16
|
||||
assert(BN_num_bytes(&v) <= 64);
|
||||
|
||||
if (v1.mIsNegative != v2.mIsNegative)
|
||||
return -STAmount(currencyOut, v.getulong(), offset1 + offset2 + 14);
|
||||
else return STAmount(currencyOut, v.getulong(), offset1 + offset2 + 14);
|
||||
return -STAmount(uCurrencyID, uIssuerID, v.getulong(), offset1 + offset2 + 14);
|
||||
else return STAmount(uCurrencyID, uIssuerID, v.getulong(), offset1 + offset2 + 14);
|
||||
}
|
||||
|
||||
// Convert an offer into an index amount so they sort by rate.
|
||||
@@ -769,7 +769,7 @@ uint64 STAmount::getRate(const STAmount& offerOut, const STAmount& offerIn)
|
||||
{
|
||||
if (offerOut.isZero()) throw std::runtime_error("Worthless offer");
|
||||
|
||||
STAmount r = divide(offerIn, offerOut, uint160(1));
|
||||
STAmount r = divide(offerIn, offerOut, CURRENCY_ONE, ACCOUNT_ONE);
|
||||
|
||||
assert((r.getExponent() >= -100) && (r.getExponent() <= 155));
|
||||
|
||||
@@ -778,12 +778,12 @@ uint64 STAmount::getRate(const STAmount& offerOut, const STAmount& offerIn)
|
||||
return (ret << (64 - 8)) | r.getMantissa();
|
||||
}
|
||||
|
||||
STAmount STAmount::setRate(uint64 rate, const uint160& currencyOut)
|
||||
STAmount STAmount::setRate(uint64 rate)
|
||||
{
|
||||
uint64 mantissa = rate & ~(255ull << (64 - 8));
|
||||
int exponent = static_cast<int>(rate >> (64 - 8)) - 100;
|
||||
|
||||
return STAmount(currencyOut, mantissa, exponent);
|
||||
return STAmount(CURRENCY_ONE, ACCOUNT_ONE, mantissa, exponent);
|
||||
}
|
||||
|
||||
// Taker gets all taker can pay for with saTakerFunds, limited by saOfferPays and saOfferFunds.
|
||||
@@ -814,7 +814,7 @@ bool STAmount::applyOffer(
|
||||
STAmount saOfferGetsAvailable =
|
||||
saOfferFunds == saOfferPays
|
||||
? saOfferGets // Offer was fully funded, avoid shenanigans.
|
||||
: divide(multiply(saTakerPays, saOfferPaysAvailable, uint160(1)), saTakerGets, saOfferGets.getCurrency());
|
||||
: divide(multiply(saTakerPays, saOfferPaysAvailable, CURRENCY_ONE, ACCOUNT_ONE), saTakerGets, saOfferGets.getCurrency(), saOfferGets.getIssuer());
|
||||
|
||||
if (saOfferGets == saOfferGetsAvailable && saTakerFunds >= saOfferGets)
|
||||
{
|
||||
@@ -836,7 +836,7 @@ bool STAmount::applyOffer(
|
||||
{
|
||||
// Taker only get's a portion of offer.
|
||||
saTakerPaid = saTakerFunds; // Taker paid all he had.
|
||||
saTakerGot = divide(multiply(saTakerFunds, saOfferPaysAvailable, uint160(1)), saOfferGetsAvailable, saOfferPays.getCurrency());
|
||||
saTakerGot = divide(multiply(saTakerFunds, saOfferPaysAvailable, CURRENCY_ONE, ACCOUNT_ONE), saOfferGetsAvailable, saOfferPays.getCurrency(), saOfferPays.getIssuer());
|
||||
|
||||
Log(lsINFO) << "applyOffer: saTakerGot=" << saTakerGot.getFullText();
|
||||
Log(lsINFO) << "applyOffer: saOfferPaysAvailable=" << saOfferPaysAvailable.getFullText();
|
||||
@@ -848,7 +848,7 @@ bool STAmount::applyOffer(
|
||||
STAmount STAmount::getPay(const STAmount& offerOut, const STAmount& offerIn, const STAmount& needed)
|
||||
{ // Someone wants to get (needed) out of the offer, how much should they pay in?
|
||||
if (offerOut.isZero())
|
||||
return STAmount(offerIn.getCurrency());
|
||||
return STAmount(offerIn.getCurrency(), offerIn.getIssuer());
|
||||
|
||||
if (needed >= offerOut)
|
||||
{
|
||||
@@ -856,7 +856,7 @@ STAmount STAmount::getPay(const STAmount& offerOut, const STAmount& offerIn, con
|
||||
return needed;
|
||||
}
|
||||
|
||||
STAmount ret = divide(multiply(needed, offerIn, uint160(1)), offerOut, offerIn.getCurrency());
|
||||
STAmount ret = divide(multiply(needed, offerIn, CURRENCY_ONE, ACCOUNT_ONE), offerOut, offerIn.getCurrency(), offerIn.getIssuer());
|
||||
|
||||
return (ret > offerIn) ? offerIn : ret;
|
||||
}
|
||||
@@ -1063,8 +1063,7 @@ BOOST_AUTO_TEST_CASE( NativeCurrency_test )
|
||||
|
||||
BOOST_AUTO_TEST_CASE( CustomCurrency_test )
|
||||
{
|
||||
uint160 currency(1);
|
||||
STAmount zero(currency), one(currency, 1), hundred(currency, 100);
|
||||
STAmount zero(CURRENCY_ONE, ACCOUNT_ONE), one(CURRENCY_ONE, ACCOUNT_ONE, 1), hundred(CURRENCY_ONE, ACCOUNT_ONE, 100);
|
||||
|
||||
serdes(one).getRaw();
|
||||
|
||||
@@ -1131,33 +1130,33 @@ BOOST_AUTO_TEST_CASE( CustomCurrency_test )
|
||||
if (!(hundred != zero)) BOOST_FAIL("STAmount fail");
|
||||
if (!(hundred != one)) BOOST_FAIL("STAmount fail");
|
||||
if ((hundred != hundred)) BOOST_FAIL("STAmount fail");
|
||||
if (STAmount(currency).getText() != "0") BOOST_FAIL("STAmount fail");
|
||||
if (STAmount(currency,31).getText() != "31") BOOST_FAIL("STAmount fail");
|
||||
if (STAmount(currency,31,1).getText() != "310") BOOST_FAIL("STAmount fail");
|
||||
if (STAmount(currency,31,-1).getText() != "3.1") BOOST_FAIL("STAmount fail");
|
||||
if (STAmount(currency,31,-2).getText() != "0.31") BOOST_FAIL("STAmount fail");
|
||||
if (STAmount(CURRENCY_ONE, ACCOUNT_ONE).getText() != "0") BOOST_FAIL("STAmount fail");
|
||||
if (STAmount(CURRENCY_ONE, ACCOUNT_ONE, 31).getText() != "31") BOOST_FAIL("STAmount fail");
|
||||
if (STAmount(CURRENCY_ONE, ACCOUNT_ONE, 31,1).getText() != "310") BOOST_FAIL("STAmount fail");
|
||||
if (STAmount(CURRENCY_ONE, ACCOUNT_ONE, 31,-1).getText() != "3.1") BOOST_FAIL("STAmount fail");
|
||||
if (STAmount(CURRENCY_ONE, ACCOUNT_ONE, 31,-2).getText() != "0.31") BOOST_FAIL("STAmount fail");
|
||||
|
||||
if (STAmount::multiply(STAmount(currency, 20), STAmount(3), currency).getText() != "60")
|
||||
if (STAmount::multiply(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 20), STAmount(3), CURRENCY_ONE, ACCOUNT_ONE).getText() != "60")
|
||||
BOOST_FAIL("STAmount multiply fail");
|
||||
if (STAmount::multiply(STAmount(currency, 20), STAmount(3), uint160()).getText() != "60")
|
||||
if (STAmount::multiply(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 20), STAmount(3), uint160(), ACCOUNT_XNS).getText() != "60")
|
||||
BOOST_FAIL("STAmount multiply fail");
|
||||
if (STAmount::multiply(STAmount(20), STAmount(3), currency).getText() != "60")
|
||||
if (STAmount::multiply(STAmount(20), STAmount(3), CURRENCY_ONE, ACCOUNT_ONE).getText() != "60")
|
||||
BOOST_FAIL("STAmount multiply fail");
|
||||
if (STAmount::multiply(STAmount(20), STAmount(3), uint160()).getText() != "60")
|
||||
if (STAmount::multiply(STAmount(20), STAmount(3), uint160(), ACCOUNT_XNS).getText() != "60")
|
||||
BOOST_FAIL("STAmount multiply fail");
|
||||
if (STAmount::divide(STAmount(currency, 60) , STAmount(3), currency).getText() != "20")
|
||||
if (STAmount::divide(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 60), STAmount(3), CURRENCY_ONE, ACCOUNT_ONE).getText() != "20")
|
||||
BOOST_FAIL("STAmount divide fail");
|
||||
if (STAmount::divide(STAmount(currency, 60) , STAmount(3), uint160()).getText() != "20")
|
||||
if (STAmount::divide(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 60), STAmount(3), uint160(), ACCOUNT_XNS).getText() != "20")
|
||||
BOOST_FAIL("STAmount divide fail");
|
||||
if (STAmount::divide(STAmount(currency, 60) , STAmount(currency, 3), currency).getText() != "20")
|
||||
if (STAmount::divide(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 60), STAmount(CURRENCY_ONE, ACCOUNT_ONE, 3), CURRENCY_ONE, ACCOUNT_ONE).getText() != "20")
|
||||
BOOST_FAIL("STAmount divide fail");
|
||||
if (STAmount::divide(STAmount(currency, 60) , STAmount(currency, 3), uint160()).getText() != "20")
|
||||
if (STAmount::divide(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 60), STAmount(CURRENCY_ONE, ACCOUNT_ONE, 3), uint160(), ACCOUNT_XNS).getText() != "20")
|
||||
BOOST_FAIL("STAmount divide fail");
|
||||
|
||||
STAmount a1(currency, 60), a2 (currency, 10, -1);
|
||||
if (STAmount::divide(a2, a1, currency) != STAmount::setRate(STAmount::getRate(a1, a2), currency))
|
||||
STAmount a1(CURRENCY_ONE, ACCOUNT_ONE, 60), a2 (CURRENCY_ONE, ACCOUNT_ONE, 10, -1);
|
||||
if (STAmount::divide(a2, a1, CURRENCY_ONE, ACCOUNT_ONE) != STAmount::setRate(STAmount::getRate(a1, a2)))
|
||||
BOOST_FAIL("STAmount setRate(getRate) fail");
|
||||
if (STAmount::divide(a1, a2, currency) != STAmount::setRate(STAmount::getRate(a2, a1), currency))
|
||||
if (STAmount::divide(a1, a2, CURRENCY_ONE, ACCOUNT_ONE) != STAmount::setRate(STAmount::getRate(a2, a1)))
|
||||
BOOST_FAIL("STAmount setRate(getRate) fail");
|
||||
|
||||
BOOST_TEST_MESSAGE("Amount CC Complete");
|
||||
@@ -1168,22 +1167,21 @@ BOOST_AUTO_TEST_CASE( CurrencyMulDivTests )
|
||||
// Test currency multiplication and division operations such as
|
||||
// convertToDisplayAmount, convertToInternalAmount, getRate, getClaimed, and getNeeded
|
||||
|
||||
uint160 c(1);
|
||||
if (STAmount::getRate(STAmount(1), STAmount(10)) != (((100ul-14)<<(64-8))|1000000000000000ul))
|
||||
BOOST_FAIL("STAmount getRate fail");
|
||||
if (STAmount::getRate(STAmount(10), STAmount(1)) != (((100ul-16)<<(64-8))|1000000000000000ul))
|
||||
BOOST_FAIL("STAmount getRate fail");
|
||||
if (STAmount::getRate(STAmount(c, 1), STAmount(c, 10)) != (((100ul-14)<<(64-8))|1000000000000000ul))
|
||||
if (STAmount::getRate(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 1), STAmount(CURRENCY_ONE, ACCOUNT_ONE, 10)) != (((100ul-14)<<(64-8))|1000000000000000ul))
|
||||
BOOST_FAIL("STAmount getRate fail");
|
||||
if (STAmount::getRate(STAmount(c, 10), STAmount(c, 1)) != (((100ul-16)<<(64-8))|1000000000000000ul))
|
||||
if (STAmount::getRate(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 10), STAmount(CURRENCY_ONE, ACCOUNT_ONE, 1)) != (((100ul-16)<<(64-8))|1000000000000000ul))
|
||||
BOOST_FAIL("STAmount getRate fail");
|
||||
if (STAmount::getRate(STAmount(c, 1), STAmount(10)) != (((100ul-14)<<(64-8))|1000000000000000ul))
|
||||
if (STAmount::getRate(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 1), STAmount(10)) != (((100ul-14)<<(64-8))|1000000000000000ul))
|
||||
BOOST_FAIL("STAmount getRate fail");
|
||||
if (STAmount::getRate(STAmount(c, 10), STAmount(1)) != (((100ul-16)<<(64-8))|1000000000000000ul))
|
||||
if (STAmount::getRate(STAmount(CURRENCY_ONE, ACCOUNT_ONE, 10), STAmount(1)) != (((100ul-16)<<(64-8))|1000000000000000ul))
|
||||
BOOST_FAIL("STAmount getRate fail");
|
||||
if (STAmount::getRate(STAmount(1), STAmount(c, 10)) != (((100ul-14)<<(64-8))|1000000000000000ul))
|
||||
if (STAmount::getRate(STAmount(1), STAmount(CURRENCY_ONE, ACCOUNT_ONE, 10)) != (((100ul-14)<<(64-8))|1000000000000000ul))
|
||||
BOOST_FAIL("STAmount getRate fail");
|
||||
if (STAmount::getRate(STAmount(10), STAmount(c, 1)) != (((100ul-16)<<(64-8))|1000000000000000ul))
|
||||
if (STAmount::getRate(STAmount(10), STAmount(CURRENCY_ONE, ACCOUNT_ONE, 1)) != (((100ul-16)<<(64-8))|1000000000000000ul))
|
||||
BOOST_FAIL("STAmount getRate fail");
|
||||
|
||||
}
|
||||
|
||||
@@ -230,8 +230,77 @@ Json::Value LedgerEntrySet::getJson(int) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
void LedgerEntrySet::addRawMeta(Serializer& s, Ledger::pointer origLedger)
|
||||
SLE::pointer LedgerEntrySet::getForMod(const uint256& node, Ledger::pointer& ledger,
|
||||
boost::unordered_map<uint256, SLE::pointer>& newMods)
|
||||
{
|
||||
boost::unordered_map<uint256, LedgerEntrySetEntry>::iterator it = mEntries.find(node);
|
||||
if (it != mEntries.end())
|
||||
{
|
||||
if (it->second.mAction == taaDELETE)
|
||||
return SLE::pointer();
|
||||
if (it->second.mAction == taaCACHED)
|
||||
it->second.mAction = taaMODIFY;
|
||||
if (it->second.mSeq != mSeq)
|
||||
{
|
||||
it->second.mEntry = boost::make_shared<SerializedLedgerEntry>(*it->second.mEntry);
|
||||
it->second.mSeq = mSeq;
|
||||
}
|
||||
return it->second.mEntry;
|
||||
}
|
||||
|
||||
boost::unordered_map<uint256, SLE::pointer>::iterator me = newMods.find(node);
|
||||
if (me != newMods.end())
|
||||
return me->second;
|
||||
|
||||
SLE::pointer ret = ledger->getSLE(node);
|
||||
if (ret)
|
||||
newMods.insert(std::make_pair(node, ret));
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
bool LedgerEntrySet::threadTx(TransactionMetaNode& metaNode, const NewcoinAddress& threadTo, Ledger::pointer& ledger,
|
||||
boost::unordered_map<uint256, SLE::pointer>& newMods)
|
||||
{
|
||||
SLE::pointer sle = getForMod(Ledger::getAccountRootIndex(threadTo.getAccountID()), ledger, newMods);
|
||||
if (!sle)
|
||||
return false;
|
||||
return threadTx(metaNode, sle, ledger, newMods);
|
||||
}
|
||||
|
||||
bool LedgerEntrySet::threadTx(TransactionMetaNode& metaNode, SLE::pointer& threadTo, Ledger::pointer& ledger,
|
||||
boost::unordered_map<uint256, SLE::pointer>& newMods)
|
||||
{ // node = the node that was modified/deleted/created
|
||||
// threadTo = the node that needs to know
|
||||
uint256 prevTxID;
|
||||
uint32 prevLgrID;
|
||||
if (!threadTo->thread(mSet.getTxID(), mSet.getLgrSeq(), prevTxID, prevLgrID))
|
||||
return false;
|
||||
if (metaNode.thread(prevTxID, prevLgrID))
|
||||
return true;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LedgerEntrySet::threadOwners(TransactionMetaNode& metaNode, SLE::pointer& node, Ledger::pointer& ledger,
|
||||
boost::unordered_map<uint256, SLE::pointer>& newMods)
|
||||
{ // thread new or modified node to owner or owners
|
||||
if (node->hasOneOwner()) // thread to owner's account
|
||||
return threadTx(metaNode, node->getOwner(), ledger, newMods);
|
||||
else if (node->hasTwoOwners()) // thread to owner's accounts
|
||||
return
|
||||
threadTx(metaNode, node->getFirstOwner(), ledger, newMods) ||
|
||||
threadTx(metaNode, node->getSecondOwner(), ledger, newMods);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void LedgerEntrySet::calcRawMeta(Serializer& s, Ledger::pointer& origLedger)
|
||||
{ // calculate the raw meta data and return it. This must be called before the set is committed
|
||||
|
||||
// Entries modified only as a result of building the transaction metadata
|
||||
boost::unordered_map<uint256, SLE::pointer> newMod;
|
||||
|
||||
for (boost::unordered_map<uint256, LedgerEntrySetEntry>::const_iterator it = mEntries.begin(),
|
||||
end = mEntries.end(); it != end; ++it)
|
||||
{
|
||||
@@ -256,11 +325,40 @@ void LedgerEntrySet::addRawMeta(Serializer& s, Ledger::pointer origLedger)
|
||||
{
|
||||
SLE::pointer origNode = origLedger->getSLE(it->first);
|
||||
SLE::pointer curNode = it->second.mEntry;
|
||||
TransactionMetaNode &metaNode = mSet.getAffectedNode(it->first, nType);
|
||||
|
||||
// FINISH
|
||||
if (nType == TMNDeletedNode)
|
||||
{
|
||||
threadOwners(metaNode, origNode, origLedger, newMod);
|
||||
|
||||
if (origNode->getType() == ltOFFER)
|
||||
{ // check for non-zero balances
|
||||
// WRITEME
|
||||
}
|
||||
}
|
||||
|
||||
if ((nType == TMNCreatedNode) || (nType == TMNModifiedNode))
|
||||
{
|
||||
if (nType == TMNCreatedNode) // if created, thread to owner(s)
|
||||
threadOwners(metaNode, curNode, origLedger, newMod);
|
||||
|
||||
if (curNode->isThreadedType()) // always thread to self
|
||||
threadTx(metaNode, curNode, origLedger, newMod);
|
||||
|
||||
if (nType == TMNModifiedNode)
|
||||
{
|
||||
// analyze changes WRITEME
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add any new modified nodes to the modification set
|
||||
for (boost::unordered_map<uint256, SLE::pointer>::iterator it = newMod.begin(), end = newMod.end();
|
||||
it != end; ++it)
|
||||
entryCache(it->second);
|
||||
|
||||
mSet.addRaw(s);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,18 @@ protected:
|
||||
LedgerEntrySet(const boost::unordered_map<uint256, LedgerEntrySetEntry> &e, const TransactionMetaSet& s, int m) :
|
||||
mEntries(e), mSet(s), mSeq(m) { ; }
|
||||
|
||||
SLE::pointer getForMod(const uint256& node, Ledger::pointer& ledger,
|
||||
boost::unordered_map<uint256, SLE::pointer>& newMods);
|
||||
|
||||
bool threadTx(TransactionMetaNode& metaNode, const NewcoinAddress& threadTo, Ledger::pointer& ledger,
|
||||
boost::unordered_map<uint256, SLE::pointer>& newMods);
|
||||
|
||||
bool threadTx(TransactionMetaNode& metaNode, SLE::pointer& threadTo, Ledger::pointer& ledger,
|
||||
boost::unordered_map<uint256, SLE::pointer>& newMods);
|
||||
|
||||
bool threadOwners(TransactionMetaNode& metaNode, SLE::pointer& node, Ledger::pointer& ledger,
|
||||
boost::unordered_map<uint256, SLE::pointer>& newMods);
|
||||
|
||||
public:
|
||||
LedgerEntrySet() : mSeq(0) { ; }
|
||||
|
||||
@@ -60,7 +72,7 @@ public:
|
||||
void entryModify(const SLE::pointer&); // This entry will be modified
|
||||
|
||||
Json::Value getJson(int) const;
|
||||
void addRawMeta(Serializer&, Ledger::pointer originalLedger);
|
||||
void calcRawMeta(Serializer&, Ledger::pointer& originalLedger);
|
||||
|
||||
// iterator functions
|
||||
bool isEmpty() const { return mEntries.empty(); }
|
||||
|
||||
@@ -85,7 +85,7 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans,
|
||||
}
|
||||
|
||||
TransactionEngineResult r = mLedgerMaster->doTransaction(*trans->getSTransaction(), tgtLedger, tepNONE);
|
||||
if (r == tenFAILED) throw Fault(IO_ERROR);
|
||||
if (r == tefFAILURE) throw Fault(IO_ERROR);
|
||||
|
||||
if (r == terPRE_SEQ)
|
||||
{ // transaction should be held
|
||||
@@ -95,14 +95,14 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans,
|
||||
mLedgerMaster->addHeldTransaction(trans);
|
||||
return trans;
|
||||
}
|
||||
if ((r == terPAST_SEQ) || (r == terPAST_LEDGER))
|
||||
if ((r == tefPAST_SEQ))
|
||||
{ // duplicate or conflict
|
||||
Log(lsINFO) << "Transaction is obsolete";
|
||||
trans->setStatus(OBSOLETE);
|
||||
return trans;
|
||||
}
|
||||
|
||||
if (r == terSUCCESS)
|
||||
if (r == tesSUCCESS)
|
||||
{
|
||||
Log(lsINFO) << "Transaction is now included";
|
||||
trans->setStatus(INCLUDED);
|
||||
@@ -875,7 +875,7 @@ void NetworkOPs::pubLedger(const Ledger::pointer& lpAccepted)
|
||||
SerializedTransaction::pointer stTxn = theApp->getMasterTransaction().fetch(item, false, 0);
|
||||
// XXX Need to support other results.
|
||||
// XXX Need to give failures too.
|
||||
TransactionEngineResult terResult = terSUCCESS;
|
||||
TransactionEngineResult terResult = tesSUCCESS;
|
||||
|
||||
if (bAll)
|
||||
{
|
||||
|
||||
@@ -21,9 +21,9 @@ TODO: what is a good way to come up with multiple paths?
|
||||
|
||||
|
||||
OrderDB:
|
||||
getXNSOffers();
|
||||
|
||||
// return list of all orderbooks that want XNS
|
||||
getXNSOffers();
|
||||
|
||||
// return list of all orderbooks that want XNS
|
||||
// return list of all orderbooks that want IssuerID
|
||||
// return list of all orderbooks that want this issuerID and currencyID
|
||||
*/
|
||||
@@ -49,7 +49,7 @@ bool sortPathOptions(PathOption::pointer first, PathOption::pointer second)
|
||||
{
|
||||
if(first->mTotalCost<second->mTotalCost) return(true);
|
||||
if(first->mTotalCost>second->mTotalCost) return(false);
|
||||
|
||||
|
||||
if(first->mCorrectCurrency && !second->mCorrectCurrency) return(true);
|
||||
if(!first->mCorrectCurrency && second->mCorrectCurrency) return(false);
|
||||
|
||||
@@ -57,7 +57,7 @@ bool sortPathOptions(PathOption::pointer first, PathOption::pointer second)
|
||||
if(first->mPath.getElementCount()>second->mPath.getElementCount()) return(false);
|
||||
|
||||
if(first->mMinWidth<second->mMinWidth) return true;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ PathOption::PathOption(PathOption::pointer other)
|
||||
|
||||
|
||||
Pathfinder::Pathfinder(NewcoinAddress& srcAccountID, NewcoinAddress& dstAccountID, uint160& srcCurrencyID, STAmount dstAmount) :
|
||||
mSrcAccountID(srcAccountID.getAccountID()) , mDstAccountID(dstAccountID.getAccountID()), mSrcCurrencyID(srcCurrencyID) , mDstAmount(dstAmount), mOrderBook(theApp->getMasterLedger().getCurrentLedger())
|
||||
mSrcAccountID(srcAccountID.getAccountID()), mDstAccountID(dstAccountID.getAccountID()), mDstAmount(dstAmount), mSrcCurrencyID(srcCurrencyID), mOrderBook(theApp->getMasterLedger().getCurrentLedger())
|
||||
{
|
||||
mLedger=theApp->getMasterLedger().getCurrentLedger();
|
||||
}
|
||||
@@ -99,9 +99,8 @@ bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet
|
||||
}
|
||||
if(checkComplete(retPathSet)) return(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
@@ -125,8 +124,8 @@ bool Pathfinder::checkComplete(STPathSet& retPathSet)
|
||||
// get all the options from this accountID
|
||||
// if source is XNS
|
||||
// every offer that wants XNS
|
||||
// else
|
||||
// every ripple line that starts with the source currency
|
||||
// else
|
||||
// every ripple line that starts with the source currency
|
||||
// every offer that we can take that wants the source currency
|
||||
|
||||
void Pathfinder::addOptions(PathOption::pointer tail)
|
||||
@@ -150,7 +149,7 @@ void Pathfinder::addOptions(PathOption::pointer tail)
|
||||
BOOST_FOREACH(RippleState::pointer line,rippleLines.getLines())
|
||||
{
|
||||
// TODO: make sure we can move in the correct direction
|
||||
STAmount balance=line->getBalance();
|
||||
STAmount balance=line->getBalance();
|
||||
if(balance.getCurrency()==tail->mCurrencyID)
|
||||
{ // we have a ripple line from the tail to somewhere else
|
||||
PathOption::pointer pathOption(new PathOption(tail));
|
||||
@@ -161,7 +160,7 @@ void Pathfinder::addOptions(PathOption::pointer tail)
|
||||
|
||||
pathOption->mCurrentAccount=line->getAccountIDPeer().getAccountID();
|
||||
addPathOption(pathOption);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// every offer that wants the source currency
|
||||
@@ -184,7 +183,7 @@ void Pathfinder::addOptions(PathOption::pointer tail)
|
||||
|
||||
void Pathfinder::addPathOption(PathOption::pointer pathOption)
|
||||
{
|
||||
if(pathOption->mCurrencyID==mDstAmount.getCurrency())
|
||||
if(pathOption->mCurrencyID==mDstAmount.getCurrency())
|
||||
{
|
||||
pathOption->mCorrectCurrency=true;
|
||||
|
||||
@@ -192,11 +191,11 @@ void Pathfinder::addPathOption(PathOption::pointer pathOption)
|
||||
{ // this path is complete
|
||||
mCompletePaths.push_back(pathOption);
|
||||
}else mBuildingPaths.push_back(pathOption);
|
||||
}else
|
||||
}
|
||||
else
|
||||
{
|
||||
pathOption->mCorrectCurrency=false;
|
||||
mBuildingPaths.push_back(pathOption);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -33,7 +33,6 @@ class Pathfinder
|
||||
OrderBookDB mOrderBook;
|
||||
Ledger::pointer mLedger;
|
||||
|
||||
|
||||
std::list<PathOption::pointer> mBuildingPaths;
|
||||
std::list<PathOption::pointer> mCompletePaths;
|
||||
|
||||
@@ -49,4 +48,5 @@ public:
|
||||
|
||||
// returns false if there is no path. otherwise fills out retPath
|
||||
bool findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet);
|
||||
};
|
||||
};
|
||||
// vim:ts=4
|
||||
|
||||
@@ -45,7 +45,7 @@ Json::Value RPCServer::RPCError(int iError)
|
||||
{ rpcBAD_SEED, "badSeed", "Disallowed seed." },
|
||||
{ rpcDST_ACT_MALFORMED, "dstActMalformed", "Destination account is malformed." },
|
||||
{ rpcDST_ACT_MISSING, "dstActMissing", "Destination account does not exists." },
|
||||
{ rpcDST_AMT_MALFORMED, "dstAmtMalformed", "Destination amount/currency is malformed." },
|
||||
{ rpcDST_AMT_MALFORMED, "dstAmtMalformed", "Destination amount/currency/issuer is malformed." },
|
||||
{ rpcFAIL_GEN_DECRPYT, "failGenDecrypt", "Failed to decrypt generator." },
|
||||
{ rpcGETS_ACT_MALFORMED, "getsActMalformed", "Gets account malformed." },
|
||||
{ rpcGETS_AMT_MALFORMED, "getsAmtMalformed", "Gets amount malformed." },
|
||||
@@ -74,7 +74,7 @@ Json::Value RPCServer::RPCError(int iError)
|
||||
{ rpcQUALITY_MALFORMED, "qualityMalformed", "Quality malformed." },
|
||||
{ rpcSRC_ACT_MALFORMED, "srcActMalformed", "Source account is malformed." },
|
||||
{ rpcSRC_ACT_MISSING, "srcActMissing", "Source account does not exist." },
|
||||
{ rpcSRC_AMT_MALFORMED, "srcAmtMalformed", "Source amount/currency is malformed." },
|
||||
{ rpcSRC_AMT_MALFORMED, "srcAmtMalformed", "Source amount/currency/issuer is malformed." },
|
||||
{ rpcSRC_UNCLAIMED, "srcUnclaimed", "Source account is not claimed." },
|
||||
{ rpcSUCCESS, "success", "Success." },
|
||||
{ rpcTXN_NOT_FOUND, "txnNotFound", "Transaction not found." },
|
||||
@@ -1706,7 +1706,7 @@ Json::Value RPCServer::doRippleLinesGet(const Json::Value ¶ms)
|
||||
return ret;
|
||||
}
|
||||
|
||||
// send regular_seed paying_account account_id amount [currency] [send_max] [send_currency]
|
||||
// send regular_seed paying_account account_id amount [currency] [issuer] [send_max] [send_currency] [send_issuer]
|
||||
Json::Value RPCServer::doSend(const Json::Value& params)
|
||||
{
|
||||
NewcoinAddress naSeed;
|
||||
@@ -1716,13 +1716,21 @@ Json::Value RPCServer::doSend(const Json::Value& params)
|
||||
STAmount saDstAmount;
|
||||
std::string sSrcCurrency;
|
||||
std::string sDstCurrency;
|
||||
std::string sSrcIssuer;
|
||||
std::string sDstIssuer;
|
||||
|
||||
if (params.size() >= 5)
|
||||
sDstCurrency = params[4u].asString();
|
||||
|
||||
if (params.size() >= 6)
|
||||
sDstIssuer = params[5u].asString();
|
||||
|
||||
if (params.size() >= 7)
|
||||
sSrcCurrency = params[6u].asString();
|
||||
|
||||
if (params.size() >= 8)
|
||||
sSrcIssuer = params[7u].asString();
|
||||
|
||||
if (!naSeed.setSeedGeneric(params[0u].asString()))
|
||||
{
|
||||
return RPCError(rpcBAD_SEED);
|
||||
@@ -1735,11 +1743,11 @@ Json::Value RPCServer::doSend(const Json::Value& params)
|
||||
{
|
||||
return RPCError(rpcDST_ACT_MALFORMED);
|
||||
}
|
||||
else if (!saDstAmount.setFullValue(params[3u].asString(), sDstCurrency))
|
||||
else if (!saDstAmount.setFullValue(params[3u].asString(), sDstCurrency, sDstIssuer))
|
||||
{
|
||||
return RPCError(rpcDST_AMT_MALFORMED);
|
||||
}
|
||||
else if (params.size() >= 6 && !saSrcAmountMax.setFullValue(params[5u].asString(), sSrcCurrency))
|
||||
else if (params.size() >= 7 && !saSrcAmountMax.setFullValue(params[5u].asString(), sSrcCurrency, sSrcIssuer))
|
||||
{
|
||||
return RPCError(rpcSRC_AMT_MALFORMED);
|
||||
}
|
||||
@@ -1758,10 +1766,16 @@ Json::Value RPCServer::doSend(const Json::Value& params)
|
||||
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, saFee, asSrc, naVerifyGenerator);
|
||||
|
||||
// Log(lsINFO) << boost::str(boost::format("doSend: sSrcIssuer=%s sDstIssuer=%s saSrcAmountMax=%s saDstAmount=%s")
|
||||
// % sSrcIssuer
|
||||
// % sDstIssuer
|
||||
// % saSrcAmountMax.getFullText()
|
||||
// % saDstAmount.getFullText());
|
||||
|
||||
if (!obj.empty())
|
||||
return obj;
|
||||
|
||||
if (params.size() < 6)
|
||||
if (params.size() < 7)
|
||||
saSrcAmountMax = saDstAmount;
|
||||
|
||||
// Do a few simple checks.
|
||||
@@ -2554,7 +2568,7 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params
|
||||
{ "ripple", &RPCServer::doRipple, 8, -1, false, optCurrent|optClosed },
|
||||
{ "ripple_lines_get", &RPCServer::doRippleLinesGet, 1, 2, false, optCurrent },
|
||||
{ "ripple_line_set", &RPCServer::doRippleLineSet, 4, 7, false, optCurrent },
|
||||
{ "send", &RPCServer::doSend, 3, 7, false, optCurrent },
|
||||
{ "send", &RPCServer::doSend, 3, 9, false, optCurrent },
|
||||
{ "server_info", &RPCServer::doServerInfo, 0, 0, true },
|
||||
{ "stop", &RPCServer::doStop, 0, 0, true },
|
||||
{ "tx", &RPCServer::doTx, 1, 1, true },
|
||||
|
||||
@@ -109,6 +109,31 @@ bool SerializedLedgerEntry::thread(const uint256& txID, uint32 ledgerSeq, uint25
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SerializedLedgerEntry::hasOneOwner()
|
||||
{
|
||||
return (mType != ltACCOUNT_ROOT) && (getIFieldIndex(sfAccount) != -1);
|
||||
}
|
||||
|
||||
bool SerializedLedgerEntry::hasTwoOwners()
|
||||
{
|
||||
return mType == ltRIPPLE_STATE;
|
||||
}
|
||||
|
||||
NewcoinAddress SerializedLedgerEntry::getOwner()
|
||||
{
|
||||
return getIValueFieldAccount(sfAccount);
|
||||
}
|
||||
|
||||
NewcoinAddress SerializedLedgerEntry::getFirstOwner()
|
||||
{
|
||||
return getIValueFieldAccount(sfLowID);
|
||||
}
|
||||
|
||||
NewcoinAddress SerializedLedgerEntry::getSecondOwner()
|
||||
{
|
||||
return getIValueFieldAccount(sfHighID);
|
||||
}
|
||||
|
||||
std::vector<uint256> SerializedLedgerEntry::getOwners()
|
||||
{
|
||||
std::vector<uint256> owners;
|
||||
|
||||
@@ -65,6 +65,11 @@ public:
|
||||
|
||||
bool isThreadedType(); // is this a ledger entry that can be threaded
|
||||
bool isThreaded(); // is this ledger entry actually threaded
|
||||
bool hasOneOwner(); // This node has one other node that owns it (like nickname)
|
||||
bool hasTwoOwners(); // This node has two nodes that own it (like ripple balance)
|
||||
NewcoinAddress getOwner();
|
||||
NewcoinAddress getFirstOwner();
|
||||
NewcoinAddress getSecondOwner();
|
||||
uint256 getThreadedTransaction();
|
||||
uint32 getThreadedLedger();
|
||||
bool thread(const uint256& txID, uint32 ledgerSeq, uint256& prevTxID, uint32& prevLedgerID);
|
||||
|
||||
@@ -261,10 +261,11 @@ public:
|
||||
: SerializedType(n), mValue(v), mOffset(0), mIsNative(true), mIsNegative(false)
|
||||
{ ; }
|
||||
|
||||
STAmount(const uint160& uCurrency, uint64 uV=0, int iOff=0, bool bNegative=false)
|
||||
: mCurrency(uCurrency), mValue(uV), mOffset(iOff), mIsNegative(bNegative)
|
||||
STAmount(const uint160& uCurrencyID, const uint160& uIssuerID, uint64 uV=0, int iOff=0, bool bNegative=false)
|
||||
: mCurrency(uCurrencyID), mIssuer(uIssuerID), mValue(uV), mOffset(iOff), mIsNegative(bNegative)
|
||||
{ canonicalize(); }
|
||||
|
||||
// YYY This should probably require issuer too.
|
||||
STAmount(const char* n, const uint160& currency, uint64 v = 0, int off = 0, bool isNeg = false) :
|
||||
SerializedType(n), mCurrency(currency), mValue(v), mOffset(off), mIsNegative(isNeg)
|
||||
{ canonicalize(); }
|
||||
@@ -274,14 +275,14 @@ public:
|
||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char* name)
|
||||
{ return std::auto_ptr<SerializedType>(construct(sit, name)); }
|
||||
|
||||
static STAmount saFromRate(uint64 uV = 0)
|
||||
static STAmount saFromRate(uint64 uRate = 0)
|
||||
{
|
||||
return STAmount(CURRENCY_ONE, uV, -9, false);
|
||||
return STAmount(CURRENCY_ONE, ACCOUNT_ONE, uRate, -9, false);
|
||||
}
|
||||
|
||||
static STAmount saFromSigned(const uint160& uCurrency, int64 iV=0, int iOff=0)
|
||||
static STAmount saFromSigned(const uint160& uCurrencyID, const uint160& uIssuerID, int64 iV=0, int iOff=0)
|
||||
{
|
||||
return STAmount(uCurrency, iV < 0 ? -iV : iV, iOff, iV < 0);
|
||||
return STAmount(uCurrencyID, uIssuerID, iV < 0 ? -iV : iV, iOff, iV < 0);
|
||||
}
|
||||
|
||||
int getLength() const { return mIsNative ? 8 : 28; }
|
||||
@@ -351,13 +352,13 @@ public:
|
||||
friend STAmount operator+(const STAmount& v1, const STAmount& v2);
|
||||
friend STAmount operator-(const STAmount& v1, const STAmount& v2);
|
||||
|
||||
static STAmount divide(const STAmount& v1, const STAmount& v2, const uint160& currencyOut);
|
||||
static STAmount multiply(const STAmount& v1, const STAmount& v2, const uint160& currencyOut);
|
||||
static STAmount divide(const STAmount& v1, const STAmount& v2, const uint160& uCurrencyID, const uint160& uIssuerID);
|
||||
static STAmount multiply(const STAmount& v1, const STAmount& v2, const uint160& uCurrencyID, const uint160& uIssuerID);
|
||||
|
||||
// Someone is offering X for Y, what is the rate?
|
||||
// Rate: smaller is better, the taker wants the most out: in/out
|
||||
static uint64 getRate(const STAmount& offerOut, const STAmount& offerIn);
|
||||
static STAmount setRate(uint64 rate, const uint160& currencyOut);
|
||||
static STAmount setRate(uint64 rate);
|
||||
|
||||
// Someone is offering X for Y, I try to pay Z, how much do I get?
|
||||
// And what's left of the offer? And how much do I actually pay?
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,75 +14,71 @@
|
||||
|
||||
enum TransactionEngineResult
|
||||
{
|
||||
// Note: Numbers are currently unstable. Use tokens.
|
||||
// Note: Range is stable. Exact numbers are currently unstable. Use tokens.
|
||||
|
||||
// tenCAN_NEVER_SUCCEED = <0
|
||||
// -399 .. -300: L Local error (transaction fee inadequate, exceeds local limit)
|
||||
// Not forwarded, no fee. Only valid during non-consensus processing
|
||||
telLOCAL_ERROR = -399,
|
||||
telBAD_PATH_COUNT,
|
||||
telINSUF_FEE_P,
|
||||
|
||||
// Malformed: Fee claimed
|
||||
tenGEN_IN_USE = -300,
|
||||
tenBAD_ADD_AUTH,
|
||||
tenBAD_AMOUNT,
|
||||
tenBAD_CLAIM_ID,
|
||||
tenBAD_EXPIRATION,
|
||||
tenBAD_GEN_AUTH,
|
||||
tenBAD_ISSUER,
|
||||
tenBAD_OFFER,
|
||||
tenBAD_PATH,
|
||||
tenBAD_PATH_COUNT,
|
||||
tenBAD_PUBLISH,
|
||||
tenBAD_SET_ID,
|
||||
tenCREATEXNS,
|
||||
tenDST_IS_SRC,
|
||||
tenDST_NEEDED,
|
||||
tenEXPLICITXNS,
|
||||
tenREDUNDANT,
|
||||
tenRIPPLE_EMPTY,
|
||||
// -299 .. -200: M Malformed (bad signature)
|
||||
// Transaction corrupt, not forwarded, cannot charge fee, reject
|
||||
// Never can succeed in any ledger
|
||||
temMALFORMED = -299,
|
||||
temBAD_AMOUNT,
|
||||
temBAD_AUTH_MASTER,
|
||||
temBAD_EXPIRATION,
|
||||
temBAD_ISSUER,
|
||||
temBAD_OFFER,
|
||||
temBAD_PUBLISH,
|
||||
temBAD_SET_ID,
|
||||
temCREATEXNS,
|
||||
temDST_IS_SRC,
|
||||
temDST_NEEDED,
|
||||
temINSUF_FEE_P,
|
||||
temINVALID,
|
||||
temREDUNDANT,
|
||||
temRIPPLE_EMPTY,
|
||||
temUNKNOWN,
|
||||
|
||||
// Invalid: Ledger won't allow.
|
||||
tenCLAIMED = -200,
|
||||
tenBAD_RIPPLE,
|
||||
tenCREATED,
|
||||
tenEXPIRED,
|
||||
tenMSG_SET,
|
||||
terALREADY,
|
||||
// -199 .. -100: F Failure (sequence number previously used)
|
||||
// Transaction cannot succeed because of ledger state, unexpected ledger state, C++ exception, not forwarded, cannot be
|
||||
// applied, Could succeed in an imaginary ledger.
|
||||
tefFAILURE = -199,
|
||||
tefALREADY,
|
||||
tefBAD_ADD_AUTH,
|
||||
tefBAD_AUTH,
|
||||
tefBAD_CLAIM_ID,
|
||||
tefBAD_GEN_AUTH,
|
||||
tefBAD_LEDGER,
|
||||
tefCLAIMED,
|
||||
tefCREATED,
|
||||
tefGEN_IN_USE,
|
||||
tefPAST_SEQ,
|
||||
|
||||
// Other
|
||||
tenFAILED = -100,
|
||||
tenINSUF_FEE_P,
|
||||
tenINVALID,
|
||||
tenUNKNOWN,
|
||||
|
||||
terSUCCESS = 0,
|
||||
|
||||
// terFAILED_BUT_COULD_SUCCEED = >0
|
||||
// Conflict with ledger database: Fee claimed
|
||||
// Might succeed if not conflict is not caused by transaction ordering.
|
||||
terBAD_AUTH,
|
||||
terBAD_AUTH_MASTER,
|
||||
terBAD_LEDGER,
|
||||
terBAD_RIPPLE,
|
||||
terBAD_SEQ,
|
||||
terCREATED,
|
||||
// -99 .. -1: R Retry (sequence too high, no funds for txn fee, originating account non-existent)
|
||||
// Transaction cannot be applied, cannot charge fee, not forwarded, might succeed later, hold
|
||||
terRETRY = -99,
|
||||
terDIR_FULL,
|
||||
terFUNDS_SPENT,
|
||||
terINSUF_FEE_B,
|
||||
terINSUF_FEE_T,
|
||||
terNODE_NOT_FOUND,
|
||||
terNODE_NOT_MENTIONED,
|
||||
terNODE_NO_ROOT,
|
||||
terNO_ACCOUNT,
|
||||
terNO_DST,
|
||||
terNO_LINE_NO_ZERO,
|
||||
terNO_PATH,
|
||||
terOFFER_NOT_FOUND,
|
||||
terOVER_LIMIT,
|
||||
terPAST_LEDGER,
|
||||
terPAST_SEQ,
|
||||
terOFFER_NOT_FOUND, // XXX If we check sequence first this could be hard failure.
|
||||
terPRE_SEQ,
|
||||
terSET_MISSING_DST,
|
||||
terUNCLAIMED,
|
||||
terUNFUNDED,
|
||||
|
||||
// 0: S Success (success)
|
||||
// Transaction succeeds, can be applied, can charge fee, forwarded
|
||||
tesSUCCESS = 0,
|
||||
|
||||
// 100 .. P Partial success (SR) (ripple transaction with no good paths, pay to non-existent account)
|
||||
// Transaction can be applied, can charge fee, forwarded, but does not achieve optimal result.
|
||||
tesPARITAL = 100,
|
||||
|
||||
// Might succeed in different order.
|
||||
// XXX claim fee and try to delete unfunded.
|
||||
terPATH_EMPTY,
|
||||
@@ -133,9 +129,19 @@ protected:
|
||||
public:
|
||||
typedef boost::shared_ptr<PathState> pointer;
|
||||
|
||||
bool bValid;
|
||||
std::vector<paymentNode> vpnNodes;
|
||||
LedgerEntrySet lesEntries;
|
||||
bool bValid;
|
||||
std::vector<paymentNode> vpnNodes;
|
||||
|
||||
// If the transaction fails to meet some constraint, still need to delete unfunded offers.
|
||||
boost::unordered_set<uint256> usUnfundedFound; // Offers that were found unfunded.
|
||||
|
||||
// When processing, don't want to complicate directory walking with deletion.
|
||||
std::vector<uint256> vUnfundedBecame; // Offers that became unfunded.
|
||||
|
||||
// First time working in reverse a funding source was mentioned. Source may only be used there.
|
||||
boost::unordered_map<std::pair<uint160, uint160>, int> umSource; // Map of currency, issuer to node index.
|
||||
|
||||
LedgerEntrySet lesEntries;
|
||||
|
||||
int mIndex;
|
||||
uint64 uQuality; // 0 = none.
|
||||
@@ -222,14 +228,15 @@ protected:
|
||||
|
||||
SLE::pointer entryCreate(LedgerEntryType letType, const uint256& uIndex);
|
||||
SLE::pointer entryCache(LedgerEntryType letType, const uint256& uIndex);
|
||||
void entryDelete(SLE::pointer sleEntry, bool unfunded = false);
|
||||
void entryDelete(SLE::pointer sleEntry, bool bUnfunded = false);
|
||||
void entryModify(SLE::pointer sleEntry);
|
||||
|
||||
uint32 rippleTransferRate(const uint160& uIssuerID);
|
||||
STAmount rippleBalance(const uint160& uToAccountID, const uint160& uFromAccountID, const uint160& uCurrencyID);
|
||||
STAmount rippleOwed(const uint160& uToAccountID, const uint160& uFromAccountID, const uint160& uCurrencyID);
|
||||
STAmount rippleLimit(const uint160& uToAccountID, const uint160& uFromAccountID, const uint160& uCurrencyID);
|
||||
uint32 rippleQualityIn(const uint160& uToAccountID, const uint160& uFromAccountID, const uint160& uCurrencyID);
|
||||
uint32 rippleQualityOut(const uint160& uToAccountID, const uint160& uFromAccountID, const uint160& uCurrencyID);
|
||||
uint32 rippleQualityIn(const uint160& uToAccountID, const uint160& uFromAccountID, const uint160& uCurrencyID, const SOE_Field sfLow=sfLowQualityIn, const SOE_Field sfHigh=sfHighQualityIn);
|
||||
uint32 rippleQualityOut(const uint160& uToAccountID, const uint160& uFromAccountID, const uint160& uCurrencyID)
|
||||
{ return rippleQualityIn(uToAccountID, uFromAccountID, uCurrencyID, sfLowQualityOut, sfHighQualityOut); }
|
||||
|
||||
STAmount rippleHolds(const uint160& uAccountID, const uint160& uCurrencyID, const uint160& uIssuerID);
|
||||
STAmount rippleTransferFee(const uint160& uSenderID, const uint160& uReceiverID, const uint160& uIssuerID, const STAmount& saAmount);
|
||||
|
||||
@@ -262,6 +262,14 @@ bool TransactionMetaSet::isNodeAffected(const uint256& node) const
|
||||
return mNodes.find(node) != mNodes.end();
|
||||
}
|
||||
|
||||
TransactionMetaNode& TransactionMetaSet::getAffectedNode(const uint256& node, int type)
|
||||
{
|
||||
std::map<uint256, TransactionMetaNode>::iterator it = mNodes.find(node);
|
||||
if (it != mNodes.end())
|
||||
return it->second;
|
||||
return mNodes.insert(std::make_pair(node, TransactionMetaNode(node, type))).first->second;
|
||||
}
|
||||
|
||||
const TransactionMetaNode& TransactionMetaSet::peekAffectedNode(const uint256& node) const
|
||||
{
|
||||
std::map<uint256, TransactionMetaNode>::const_iterator it = mNodes.find(node);
|
||||
@@ -283,28 +291,3 @@ void TransactionMetaSet::swap(TransactionMetaSet& s)
|
||||
mNodes.swap(s.mNodes);
|
||||
}
|
||||
|
||||
TransactionMetaNode& TransactionMetaSet::modifyNode(const uint256& node)
|
||||
{
|
||||
std::map<uint256, TransactionMetaNode>::iterator it = mNodes.find(node);
|
||||
if (it != mNodes.end())
|
||||
return it->second;
|
||||
return mNodes.insert(std::make_pair(node, TransactionMetaNode(node))).first->second;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void TransactionMetaSet::threadNode(const uint256& node, const uint256& prevTx, uint32 prevLgr)
|
||||
{
|
||||
modifyNode(node).thread(prevTx, prevLgr);
|
||||
}
|
||||
|
||||
void TransactionMetaSet::deleteUnfunded(const uint256& nodeID,
|
||||
const STAmount& firstBalance, const STAmount &secondBalance)
|
||||
{
|
||||
TransactionMetaNode& node = modifyNode(nodeID);
|
||||
TMNEUnfunded* entry = dynamic_cast<TMNEUnfunded*>(node.findEntry(TransactionMetaNodeEntry::TMNDeleteUnfunded));
|
||||
if (entry)
|
||||
entry->setBalances(firstBalance, secondBalance);
|
||||
else
|
||||
node.addNode(new TMNEUnfunded(firstBalance, secondBalance));
|
||||
}
|
||||
#endif
|
||||
@@ -133,7 +133,7 @@ protected:
|
||||
boost::ptr_vector<TransactionMetaNodeEntry> mEntries;
|
||||
|
||||
public:
|
||||
TransactionMetaNode(const uint256 &node) : mNode(node) { ; }
|
||||
TransactionMetaNode(const uint256 &node, int type) : mType(type), mNode(node) { ; }
|
||||
|
||||
const uint256& getNode() const { return mNode; }
|
||||
const boost::ptr_vector<TransactionMetaNodeEntry>& peekEntries() const { return mEntries; }
|
||||
@@ -163,8 +163,6 @@ protected:
|
||||
uint32 mLedger;
|
||||
std::map<uint256, TransactionMetaNode> mNodes;
|
||||
|
||||
TransactionMetaNode& modifyNode(const uint256&);
|
||||
|
||||
public:
|
||||
TransactionMetaSet() : mLedger(0) { ; }
|
||||
TransactionMetaSet(const uint256& txID, uint32 ledger) : mTransactionID(txID), mLedger(ledger) { ; }
|
||||
@@ -174,6 +172,9 @@ public:
|
||||
void clear() { mNodes.clear(); }
|
||||
void swap(TransactionMetaSet&);
|
||||
|
||||
const uint256& getTxID() { return mTransactionID; }
|
||||
uint32 getLgrSeq() { return mLedger; }
|
||||
|
||||
bool isNodeAffected(const uint256&) const;
|
||||
TransactionMetaNode& getAffectedNode(const uint256&, int type);
|
||||
const TransactionMetaNode& peekAffectedNode(const uint256&) const;
|
||||
|
||||
Reference in New Issue
Block a user