Merge branch 'ripple'

This commit is contained in:
Arthur Britto
2012-08-23 14:55:21 -07:00
9 changed files with 174 additions and 134 deletions

View File

@@ -288,6 +288,7 @@ void STAmount::add(Serializer& s) const
s.add64(mValue | (static_cast<uint64>(mOffset + 512 + 256 + 97) << (64 - 10)));
s.add160(mCurrency);
s.add160(mIssuer);
}
}
@@ -334,25 +335,38 @@ STAmount* STAmount::construct(SerializerIterator& sit, const char *name)
return new STAmount(name, value, true); // negative
}
uint160 currency = sit.get160();
if (!currency)
uint160 uCurrencyID = sit.get160();
if (!uCurrencyID)
throw std::runtime_error("invalid native currency");
uint160 uIssuerID = sit.get160();
int offset = static_cast<int>(value >> (64 - 10)); // 10 bits for the offset, sign and "not native" flag
value &= ~(1023ull << (64-10));
if (value == 0)
STAmount* sapResult;
if (value)
{
bool isNegative = (offset & 256) == 0;
offset = (offset & 255) - 97; // center the range
if ((value < cMinValue) || (value > cMaxValue) || (offset < cMinOffset) || (offset > cMaxOffset))
throw std::runtime_error("invalid currency value");
sapResult = new STAmount(name, uCurrencyID, value, offset, isNegative);
}
else
{
if (offset != 512)
throw std::runtime_error("invalid currency value");
return new STAmount(name, currency);
sapResult = new STAmount(name, uCurrencyID);
}
bool isNegative = (offset & 256) == 0;
offset = (offset & 255) - 97; // center the range
if ((value < cMinValue) || (value > cMaxValue) || (offset < cMinOffset) || (offset > cMaxOffset))
throw std::runtime_error("invalid currency value");
return new STAmount(name, currency, value, offset, isNegative);
if (sapResult)
sapResult->setIssuer(uIssuerID);
return sapResult;
}
int64 STAmount::getSNValue() const

View File

@@ -754,7 +754,16 @@ uint256 Ledger::getBookBase(const uint160& uTakerPaysCurrency, const uint160& uT
s.add160(uTakerPaysIssuerID); // 20
s.add160(uTakerGetsIssuerID); // 20
return getQualityIndex(s.getSHA512Half()); // Return with quality 0.
uint256 uBaseIndex = getQualityIndex(s.getSHA512Half()); // Return with quality 0.
Log(lsINFO) << str(boost::format("getBookBase(%s,%s,%s,%s) = %s")
% STAmount::createHumanCurrency(uTakerPaysCurrency)
% NewcoinAddress::createHumanAccountID(uTakerPaysIssuerID)
% STAmount::createHumanCurrency(uTakerGetsCurrency)
% NewcoinAddress::createHumanAccountID(uTakerGetsIssuerID)
% uBaseIndex.ToString());
return uBaseIndex;
}
uint256 Ledger::getDirNodeIndex(const uint256& uDirRoot, const uint64 uNodeIndex)

View File

@@ -57,9 +57,7 @@ LedgerEntryFormat LedgerFormats[]=
{ S_FIELD(OwnerNode), STI_UINT64, SOE_REQUIRED, 0 },
{ S_FIELD(LastTxnID), STI_HASH256, SOE_REQUIRED, 0 },
{ S_FIELD(LastTxnSeq), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(PaysIssuer), STI_ACCOUNT, SOE_IFFLAG, 1 },
{ S_FIELD(GetsIssuer), STI_ACCOUNT, SOE_IFFLAG, 2 },
{ S_FIELD(Expiration), STI_UINT32, SOE_IFFLAG, 4 },
{ S_FIELD(Expiration), STI_UINT32, SOE_IFFLAG, 1 },
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},

View File

@@ -50,7 +50,6 @@ enum SOE_Field
sfFlags,
sfGenerator,
sfGeneratorID,
sfGetsIssuer,
sfHash,
sfHighID,
sfHighLimit,
@@ -84,7 +83,6 @@ enum SOE_Field
sfOfferSequence,
sfOwnerNode,
sfPaths,
sfPaysIssuer,
sfPubKey,
sfPublishHash,
sfPublishSize,

View File

@@ -261,8 +261,8 @@ public:
: SerializedType(n), mValue(v), mOffset(0), mIsNative(true), mIsNegative(false)
{ ; }
STAmount(const uint160& currency, uint64 v = 0, int off = 0)
: mCurrency(currency), mValue(v), mOffset(off), mIsNegative(false)
STAmount(const uint160& uCurrency, uint64 uV=0, int iOff=0, bool bNegative=false)
: mCurrency(uCurrency), mValue(uV), mOffset(iOff), mIsNegative(bNegative)
{ canonicalize(); }
STAmount(const char* n, const uint160& currency, uint64 v = 0, int off = 0, bool isNeg = false) :
@@ -274,6 +274,16 @@ 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)
{
return STAmount(CURRENCY_ONE, uV, -9, false);
}
static STAmount saFromSigned(const uint160& uCurrency, int64 iV=0, int iOff=0)
{
return STAmount(uCurrency, iV < 0 ? -iV : iV, iOff, iV < 0);
}
int getLength() const { return mIsNative ? 8 : 28; }
SerializedTypeID getSType() const { return STI_AMOUNT; }
std::string getText() const;

View File

@@ -362,12 +362,6 @@ Transaction::pointer Transaction::setOfferCreate(
mTransaction->setITFieldAmount(sfTakerPays, saTakerPays);
mTransaction->setITFieldAmount(sfTakerGets, saTakerGets);
if (!saTakerPays.isNative())
mTransaction->setITFieldAccount(sfPaysIssuer, saTakerPays.getIssuer());
if (!saTakerGets.isNative())
mTransaction->setITFieldAccount(sfGetsIssuer, saTakerGets.getIssuer());
if (uExpiration)
mTransaction->setITFieldU32(sfExpiration, uExpiration);

View File

@@ -149,15 +149,25 @@ uint32 TransactionEngine::rippleTransferRate(const uint160& uIssuerID)
{
SLE::pointer sleAccount = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uIssuerID));
return sleAccount->getIFieldPresent(sfTransferRate)
? sleAccount->getIFieldU32(sfTransferRate)
: QUALITY_ONE;
uint32 uQuality = sleAccount && sleAccount->getIFieldPresent(sfTransferRate)
? sleAccount->getIFieldU32(sfTransferRate)
: QUALITY_ONE;
Log(lsINFO) << str(boost::format("rippleTransferRate: uIssuerID=%s account_exists=%d transfer_rate=%f")
% NewcoinAddress::createHumanAccountID(uIssuerID)
% !!sleAccount
% (uQuality/1000000000.0));
assert(sleAccount);
return uQuality;
}
// XXX Might not need this, might store in nodes on calc reverse.
uint32 TransactionEngine::rippleQualityIn(const uint160& uToAccountID, const uint160& uFromAccountID, const uint160& uCurrencyID)
{
uint32 uQualityIn = QUALITY_ONE;
uint32 uQualityIn = QUALITY_ONE;
SLE::pointer sleRippleState;
if (uToAccountID == uFromAccountID)
{
@@ -165,7 +175,7 @@ uint32 TransactionEngine::rippleQualityIn(const uint160& uToAccountID, const uin
}
else
{
SLE::pointer sleRippleState = entryCache(ltRIPPLE_STATE, Ledger::getRippleStateIndex(uToAccountID, uFromAccountID, uCurrencyID));
sleRippleState = entryCache(ltRIPPLE_STATE, Ledger::getRippleStateIndex(uToAccountID, uFromAccountID, uCurrencyID));
if (sleRippleState)
{
@@ -177,12 +187,17 @@ uint32 TransactionEngine::rippleQualityIn(const uint160& uToAccountID, const uin
if (!uQualityIn)
uQualityIn = 1;
}
else
{
assert(false);
}
}
Log(lsINFO) << str(boost::format("rippleQualityIn: uToAccountID=%s uFromAccountID=%s uCurrencyID=%s bLine=%d uQualityIn=%f")
% NewcoinAddress::createHumanAccountID(uToAccountID)
% NewcoinAddress::createHumanAccountID(uFromAccountID)
% STAmount::createHumanCurrency(uCurrencyID)
% !!sleRippleState
% (uQualityIn/1000000000.0));
assert(uToAccountID == uFromAccountID || !!sleRippleState);
return uQualityIn;
}
@@ -236,7 +251,7 @@ STAmount TransactionEngine::accountHolds(const uint160& uAccountID, const uint16
{
STAmount saAmount;
if (uCurrencyID.isZero())
if (!uCurrencyID)
{
SLE::pointer sleAccount = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uAccountID));
@@ -382,7 +397,7 @@ STAmount TransactionEngine::rippleSend(const uint160& uSenderID, const uint160&
STAmount saTransitFee = rippleTransferFee(uSenderID, uReceiverID, uIssuerID, saAmount);
saActual = saTransitFee.isZero() ? saAmount : saAmount+saTransitFee;
saActual = !saTransitFee ? saAmount : saAmount+saTransitFee;
saActual.setIssuer(uIssuerID); // XXX Make sure this done in + above.
@@ -818,7 +833,7 @@ SLE::pointer TransactionEngine::entryCache(LedgerEntryType letType, const uint25
{
SLE::pointer sleEntry;
if (!uIndex.isZero())
if (!!uIndex)
{
LedgerEntryAction action;
sleEntry = mNodes.getEntry(uIndex, action);
@@ -837,7 +852,7 @@ SLE::pointer TransactionEngine::entryCache(LedgerEntryType letType, const uint25
SLE::pointer TransactionEngine::entryCreate(LedgerEntryType letType, const uint256& uIndex)
{
assert(!uIndex.isZero());
assert(!!uIndex);
SLE::pointer sleNew = boost::make_shared<SerializedLedgerEntry>(letType);
sleNew->setIndex(uIndex);
@@ -1015,7 +1030,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
if (terSUCCESS == terResult && (params & tepNO_CHECK_FEE) == tepNONE)
{
if (!saCost.isZero())
if (!!saCost)
{
if (saPaid < saCost)
{
@@ -1026,7 +1041,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
}
else
{
if (!saPaid.isZero())
if (!!saPaid)
{
// Transaction is malformed.
Log(lsWARNING) << "applyTransaction: fee not allowed";
@@ -1153,7 +1168,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
// Deduct the fee, so it's not available during the transaction.
// Will only write the account back, if the transaction succeeds.
if (terSUCCESS != terResult || saCost.isZero())
if (terSUCCESS != terResult || !saCost)
{
nothing();
}
@@ -1176,7 +1191,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
{
nothing();
}
else if (!saCost.isZero())
else if (!!saCost)
{
uint32 a_seq = mTxnAccount->getIFieldU32(sfSequence);
@@ -1325,7 +1340,7 @@ TransactionEngineResult TransactionEngine::doAccountSet(const SerializedTransact
{
uint128 uHash = txn.getITFieldH128(sfEmailHash);
if (uHash.isZero())
if (!uHash)
{
Log(lsINFO) << "doAccountSet: unset email hash";
@@ -1347,7 +1362,7 @@ TransactionEngineResult TransactionEngine::doAccountSet(const SerializedTransact
{
uint256 uHash = txn.getITFieldH256(sfWalletLocator);
if (uHash.isZero())
if (!uHash)
{
Log(lsINFO) << "doAccountSet: unset wallet locator";
@@ -1444,7 +1459,7 @@ TransactionEngineResult TransactionEngine::doAccountSet(const SerializedTransact
uint256 uHash = txn.getITFieldH256(sfPublishHash);
uint32 uSize = txn.getITFieldU32(sfPublishSize);
if (uHash.isZero())
if (!uHash)
{
Log(lsINFO) << "doAccountSet: unset publish";
@@ -1520,16 +1535,16 @@ TransactionEngineResult TransactionEngine::doCreditSet(const SerializedTransacti
{
// A line exists in one or more directions.
#if 0
if (saLimitAmount.isZero())
if (!saLimitAmount)
{
// Zeroing line.
uint160 uLowID = sleRippleState->getIValueFieldAccount(sfLowID).getAccountID();
uint160 uHighID = sleRippleState->getIValueFieldAccount(sfHighID).getAccountID();
bool bLow = uLowID == uSrcAccountID;
bool bHigh = uLowID == uDstAccountID;
bool bBalanceZero = sleRippleState->getIValueFieldAmount(sfBalance).isZero();
bool bBalanceZero = !sleRippleState->getIValueFieldAmount(sfBalance);
STAmount saDstLimit = sleRippleState->getIValueFieldAmount(bSendLow ? sfLowLimit : sfHighLimit);
bool bDstLimitZero = saDstLimit.isZero();
bool bDstLimitZero = !saDstLimit;
assert(bLow || bHigh);
@@ -1580,7 +1595,7 @@ TransactionEngineResult TransactionEngine::doCreditSet(const SerializedTransacti
Log(lsINFO) << "doCreditSet: Modifying ripple line: bDelIndex=" << bDelIndex;
}
// Line does not exist.
else if (saLimitAmount.isZero())
else if (!saLimitAmount)
{
Log(lsINFO) << "doCreditSet: Redundant: Setting non-existant ripple line to 0.";
@@ -1814,12 +1829,6 @@ void TransactionEngine::calcOfferBridgeNext(
STAmount saOfferPays = sleOffer->getIValueFieldAmount(sfTakerGets);
STAmount saOfferGets = sleOffer->getIValueFieldAmount(sfTakerPays);
if (sleOffer->getIFieldPresent(sfGetsIssuer))
saOfferPays.setIssuer(sleOffer->getIValueFieldAccount(sfGetsIssuer).getAccountID());
if (sleOffer->getIFieldPresent(sfPaysIssuer))
saOfferGets.setIssuer(sleOffer->getIValueFieldAccount(sfPaysIssuer).getAccountID());
if (sleOffer->getIFieldPresent(sfExpiration) && sleOffer->getIFieldU32(sfExpiration) <= mLedger->getParentCloseTimeNC())
{
// Offer is expired.
@@ -1915,18 +1924,30 @@ bool TransactionEngine::calcNodeOfferRev(
const uint160& uNxtIssuerID = pnNxt.uIssuerID;
const uint160& uNxtAccountID = pnNxt.uAccountID;
const STAmount saTransferRate = STAmount(CURRENCY_ONE, rippleTransferRate(uCurIssuerID), -9);
const STAmount saTransferRate = STAmount::saFromRate(rippleTransferRate(uCurIssuerID));
uint256 uDirectTip = Ledger::getBookBase(uPrvCurrencyID, uPrvIssuerID, uCurCurrencyID, uCurIssuerID);
const uint256 uDirectEnd = Ledger::getQualityNext(uDirectTip);
bool bAdvance = !entryCache(ltDIR_NODE, uDirectTip);
Log(lsINFO) << str(boost::format("calcNodeOfferRev> uIndex=%d prv=%s/%s cur=%s/%s nxt=%s/%s saTransferRate=%s")
% uIndex
% STAmount::createHumanCurrency(uPrvCurrencyID)
% NewcoinAddress::createHumanAccountID(uPrvIssuerID)
% STAmount::createHumanCurrency(uCurCurrencyID)
% NewcoinAddress::createHumanAccountID(uCurIssuerID)
% STAmount::createHumanCurrency(uNxtCurrencyID)
% NewcoinAddress::createHumanAccountID(uNxtIssuerID)
% saTransferRate.getText());
STAmount& saPrvDlvReq = pnPrv.saRevDeliver; // To be adjusted.
STAmount saPrvDlvAct;
const STAmount& saCurDlvReq = pnCur.saRevDeliver; // Reverse driver.
STAmount saCurDlvAct;
Log(lsINFO) << str(boost::format("calcNodeOfferRev: uDirectTip=%s") % uDirectTip.ToString());
while (!!uDirectTip // Have a quality.
&& saCurDlvAct != saCurDlvReq)
{
@@ -1934,6 +1955,8 @@ bool TransactionEngine::calcNodeOfferRev(
if (bAdvance)
{
uDirectTip = mLedger->getNextLedgerIndex(uDirectTip, uDirectEnd);
Log(lsINFO) << str(boost::format("calcNodeOfferRev: uDirectTip=%s") % uDirectTip.ToString());
}
else
{
@@ -1953,16 +1976,12 @@ bool TransactionEngine::calcNodeOfferRev(
while (saCurDlvReq != saCurDlvAct // Have not met request.
&& dirNext(uDirectTip, sleDirectDir, uEntry, uCurIndex))
{
Log(lsINFO) << str(boost::format("calcNodeOfferRev: uCurIndex=%s") % uCurIndex.ToString());
SLE::pointer sleCurOfr = entryCache(ltOFFER, uCurIndex);
uint160 uCurOfrAccountID = sleCurOfr->getIValueFieldAccount(sfAccount).getAccountID();
STAmount saCurOfrOutReq = sleCurOfr->getIValueFieldAmount(sfTakerGets);
STAmount saCurOfrIn = sleCurOfr->getIValueFieldAmount(sfTakerPays);
// XXX Move issuer into STAmount
if (sleCurOfr->getIFieldPresent(sfGetsIssuer))
saCurOfrOutReq.setIssuer(sleCurOfr->getIValueFieldAccount(sfGetsIssuer).getAccountID());
if (sleCurOfr->getIFieldPresent(sfPaysIssuer))
saCurOfrIn.setIssuer(sleCurOfr->getIValueFieldAccount(sfPaysIssuer).getAccountID());
const STAmount& saCurOfrOutReq = sleCurOfr->getIValueFieldAmount(sfTakerGets);
// UNUSED? const STAmount& saCurOfrIn = sleCurOfr->getIValueFieldAmount(sfTakerPays);
STAmount saCurOfrFunds = accountFunds(uCurOfrAccountID, saCurOfrOutReq); // Funds left.
@@ -2039,10 +2058,7 @@ bool TransactionEngine::calcNodeOfferRev(
// YYY This could combine offers with the same fee before doing math.
SLE::pointer sleNxtOfr = entryCache(ltOFFER, uNxtIndex);
uint160 uNxtOfrAccountID = sleNxtOfr->getIValueFieldAccount(sfAccount).getAccountID();
STAmount saNxtOfrIn = sleNxtOfr->getIValueFieldAmount(sfTakerPays);
// XXX Move issuer into STAmount
if (sleNxtOfr->getIFieldPresent(sfPaysIssuer))
saNxtOfrIn.setIssuer(sleCurOfr->getIValueFieldAccount(sfPaysIssuer).getAccountID());
const STAmount& saNxtOfrIn = sleNxtOfr->getIValueFieldAmount(sfTakerPays);
STAmount saFeeRate = uCurOfrAccountID == uCurIssuerID || uNxtOfrAccountID == uCurIssuerID
? saOne
@@ -2085,6 +2101,11 @@ bool TransactionEngine::calcNodeOfferRev(
bSuccess = true;
}
Log(lsINFO) << str(boost::format("calcNodeOfferRev< uIndex=%d saPrvDlvReq=%s bSuccess=%d")
% uIndex
% saPrvDlvReq.getText()
% bSuccess);
return bSuccess;
}
@@ -2108,7 +2129,7 @@ bool TransactionEngine::calcNodeOfferFwd(
const uint160& uNxtIssuerID = pnNxt.uIssuerID;
const uint160& uNxtAccountID = pnNxt.uAccountID;
const STAmount saTransferRate = STAmount(CURRENCY_ONE, rippleTransferRate(uCurIssuerID), -9);
const STAmount saTransferRate = STAmount::saFromRate(rippleTransferRate(uCurIssuerID));
uint256 uDirectTip = Ledger::getBookBase(uPrvCurrencyID, uPrvIssuerID, uCurCurrencyID, uCurIssuerID);
const uint256 uDirectEnd = Ledger::getQualityNext(uDirectTip);
@@ -2147,18 +2168,11 @@ bool TransactionEngine::calcNodeOfferFwd(
{
SLE::pointer sleCurOfr = entryCache(ltOFFER, uCurIndex);
uint160 uCurOfrAccountID = sleCurOfr->getIValueFieldAccount(sfAccount).getAccountID();
STAmount saCurOfrOutReq = sleCurOfr->getIValueFieldAmount(sfTakerGets);
STAmount saCurOfrInReq = sleCurOfr->getIValueFieldAmount(sfTakerPays);
// XXX Move issuer into STAmount
if (sleCurOfr->getIFieldPresent(sfGetsIssuer))
saCurOfrOutReq.setIssuer(sleCurOfr->getIValueFieldAccount(sfGetsIssuer).getAccountID());
if (sleCurOfr->getIFieldPresent(sfPaysIssuer))
saCurOfrInReq.setIssuer(sleCurOfr->getIValueFieldAccount(sfPaysIssuer).getAccountID());
const STAmount& saCurOfrOutReq = sleCurOfr->getIValueFieldAmount(sfTakerGets);
const STAmount& saCurOfrInReq = sleCurOfr->getIValueFieldAmount(sfTakerPays);
STAmount saCurOfrInAct;
STAmount saCurOfrFunds = accountFunds(uCurOfrAccountID, saCurOfrOutReq); // Funds left.
saCurOfrInReq = MIN(saCurOfrInReq, saPrvDlvReq-saPrvDlvAct);
STAmount saCurOfrInMax = MIN(saCurOfrInReq, saPrvDlvReq-saPrvDlvAct);
if (!!uNxtAccountID)
{
@@ -2166,10 +2180,10 @@ bool TransactionEngine::calcNodeOfferFwd(
const STAmount saFeeRate = uCurOfrAccountID == uCurIssuerID || uNxtAccountID == uCurIssuerID
? saOne
: saTransferRate;
: saTransferRate;
const bool bFee = saFeeRate != saOne;
const STAmount saOutPass = STAmount::divide(saCurOfrInReq, saOfrRate, uCurCurrencyID);
const STAmount saOutPass = STAmount::divide(saCurOfrInMax, saOfrRate, uCurCurrencyID);
const STAmount saOutBase = MIN(saCurOfrOutReq, saOutPass); // Limit offer out by needed.
const STAmount saOutCost = MIN(
bFee
@@ -2219,17 +2233,14 @@ bool TransactionEngine::calcNodeOfferFwd(
// YYY This could combine offers with the same fee before doing math.
SLE::pointer sleNxtOfr = entryCache(ltOFFER, uNxtIndex);
const uint160 uNxtOfrAccountID = sleNxtOfr->getIValueFieldAccount(sfAccount).getAccountID();
STAmount saNxtOfrIn = sleNxtOfr->getIValueFieldAmount(sfTakerPays);
// XXX Move issuer into STAmount
if (sleNxtOfr->getIFieldPresent(sfPaysIssuer))
saNxtOfrIn.setIssuer(sleCurOfr->getIValueFieldAccount(sfPaysIssuer).getAccountID());
const STAmount& saNxtOfrIn = sleNxtOfr->getIValueFieldAmount(sfTakerPays);
const STAmount saFeeRate = uCurOfrAccountID == uCurIssuerID || uNxtOfrAccountID == uCurIssuerID
? saOne
: saTransferRate;
const bool bFee = saFeeRate != saOne;
const STAmount saInBase = saCurOfrInReq-saCurOfrInAct;
const STAmount saInBase = saCurOfrInMax-saCurOfrInAct;
const STAmount saOutPass = STAmount::divide(saInBase, saOfrRate, uCurCurrencyID);
STAmount saOutBase = MIN(saCurOfrOutReq, saOutPass); // Limit offer out by needed.
saOutBase = MIN(saOutBase, saNxtOfrIn); // Limit offer out by supplying offer.
@@ -2601,8 +2612,8 @@ bool TransactionEngine::calcNodeAccountRev(unsigned int uIndex, PathState::point
const bool bPrvAccount = !uIndex || !!(pnPrv.uFlags & STPathElement::typeAccount);
const bool bNxtAccount = uIndex == uLast || !!(pnNxt.uFlags & STPathElement::typeAccount);
const uint160& uPrvAccountID = pnPrv.uAccountID;
const uint160& uCurAccountID = pnCur.uAccountID;
const uint160& uPrvAccountID = bPrvAccount ? pnPrv.uAccountID : uCurAccountID;
const uint160& uNxtAccountID = bNxtAccount ? pnNxt.uAccountID : uCurAccountID; // Offers are always issue.
const uint160& uCurrencyID = pnCur.uCurrencyID;
@@ -2614,6 +2625,18 @@ bool TransactionEngine::calcNodeAccountRev(unsigned int uIndex, PathState::point
const STAmount saPrvBalance = uIndex && bPrvAccount ? rippleBalance(uCurAccountID, uPrvAccountID, uCurrencyID) : STAmount(uCurrencyID);
const STAmount saPrvLimit = uIndex && bPrvAccount ? rippleLimit(uCurAccountID, uPrvAccountID, uCurrencyID) : STAmount(uCurrencyID);
Log(lsINFO) << str(boost::format("calcNodeAccountRev> uIndex=%d/%d uPrvAccountID=%s uCurAccountID=%s uNxtAccountID=%s uCurrencyID=%s uQualityIn=%d uQualityOut=%d saPrvBalance=%s saPrvLimit=%s")
% uIndex
% uLast
% NewcoinAddress::createHumanAccountID(uPrvAccountID)
% NewcoinAddress::createHumanAccountID(uCurAccountID)
% NewcoinAddress::createHumanAccountID(uNxtAccountID)
% STAmount::createHumanCurrency(uCurrencyID)
% uQualityIn
% uQualityOut
% saPrvBalance.getText()
% saPrvLimit.getText());
const STAmount saPrvRedeemReq = bPrvRedeem && saPrvBalance.isNegative() ? -saPrvBalance : STAmount(uCurrencyID, 0);
STAmount& saPrvRedeemAct = pnPrv.saRevRedeem;
@@ -2621,7 +2644,7 @@ bool TransactionEngine::calcNodeAccountRev(unsigned int uIndex, PathState::point
STAmount& saPrvIssueAct = pnPrv.saRevIssue;
// For !bPrvAccount
const STAmount saPrvDeliverReq = STAmount(uCurrencyID, -1); // Unlimited.
const STAmount saPrvDeliverReq = STAmount::saFromSigned(uCurrencyID, -1); // Unlimited.
STAmount& saPrvDeliverAct = pnPrv.saRevDeliver;
// For bNxtAccount
@@ -2629,20 +2652,18 @@ bool TransactionEngine::calcNodeAccountRev(unsigned int uIndex, PathState::point
STAmount saCurRedeemAct(saCurRedeemReq.getCurrency());
const STAmount& saCurIssueReq = pnCur.saRevIssue;
STAmount saCurIssueAct(saCurIssueReq.getCurrency()); // Track progress.
STAmount saCurIssueAct(saCurIssueReq.getCurrency()); // Track progress.
// For !bNxtAccount
const STAmount& saCurDeliverReq = pnCur.saRevDeliver;
STAmount saCurDeliverAct(saCurDeliverReq.getCurrency());
// For uIndex == uLast
const STAmount& saCurWantedReq = pspCur->saOutReq; // XXX Credit limits?
const STAmount& saCurWantedReq = pspCur->saOutReq; // XXX Credit limits?
// STAmount saPrvDeliverReq = saPrvBalance.isPositive() ? saPrvLimit - saPrvBalance : saPrvLimit;
STAmount saCurWantedAct(saCurWantedReq.getCurrency());
Log(lsINFO) << str(boost::format("calcNodeAccountRev> uIndex=%d/%d saPrvRedeemReq=%s/%s saPrvIssueReq=%s/%s saCurWantedReq=%s/%s")
% uIndex
% uLast
Log(lsINFO) << str(boost::format("calcNodeAccountRev: saPrvRedeemReq=%s/%s saPrvIssueReq=%s/%s saCurWantedReq=%s/%s")
% saPrvRedeemReq.getText()
% saPrvRedeemReq.getHumanCurrency()
% saPrvIssueReq.getText()
@@ -3188,7 +3209,8 @@ bool PathState::pushImply(uint160 uAccountID, uint160 uCurrencyID, uint160 uIssu
#endif
bValid = pushNode(
0, // Offer
STPathElement::typeCurrency // Offer.
| STPathElement::typeIssuer,
ACCOUNT_ONE, // Placeholder for offers.
uCurrencyID, // The offer's output is what is now wanted.
uIssuerID);
@@ -3417,14 +3439,21 @@ PathState::PathState(
bValid = pushNode(
STPathElement::typeAccount // Last node is always an account.
| STPathElement::typeRedeem // Does not matter just pass error check.
| STPathElement::typeIssue, // Does not matter just pass error check.
| STPathElement::typeIssue // Does not matter just pass error check.
| STPathElement::typeCurrency
| STPathElement::typeIssuer,
uReceiverID, // Receive to output
uOutCurrencyID, // Desired currency
uOutIssuerID);
}
}
Log(lsINFO) << "PathState: " << getJson();
Log(lsINFO) << str(boost::format("PathState: in=%s/%s out=%s/%s %s")
% STAmount::createHumanCurrency(uInCurrencyID)
% NewcoinAddress::createHumanAccountID(uInIssuerID)
% STAmount::createHumanCurrency(uOutCurrencyID)
% NewcoinAddress::createHumanAccountID(uOutIssuerID)
% getJson());
}
Json::Value PathState::getJson() const
@@ -3517,6 +3546,8 @@ bool TransactionEngine::calcNode(unsigned int uIndex, PathState::pointer pspCur,
const bool bCurAccount = !!(pnCur.uFlags & STPathElement::typeAccount);
bool bValid;
Log(lsINFO) << str(boost::format("calcNode> uIndex=%d") % uIndex);
// Do current node reverse.
bValid = bCurAccount
? calcNodeAccountRev(uIndex, pspCur, bMultiQuality)
@@ -3536,6 +3567,8 @@ bool TransactionEngine::calcNode(unsigned int uIndex, PathState::pointer pspCur,
: calcNodeOfferFwd(uIndex, pspCur, bMultiQuality);
}
Log(lsINFO) << str(boost::format("calcNode< uIndex=%d bValid=%d") % uIndex % bValid);
return bValid;
}
@@ -3553,14 +3586,14 @@ void TransactionEngine::pathNext(PathState::pointer pspCur, int iPaths)
assert(pspCur->vpnNodes.size() >= 2);
bool bValid = calcNode(uLast, pspCur, iPaths == 1);
pspCur->bValid = calcNode(uLast, pspCur, iPaths == 1);
Log(lsINFO) << "pathNext: bValid="
<< bValid
<< pspCur->bValid
<< " saOutAct=" << pspCur->saOutAct.getText()
<< " saInAct=" << pspCur->saInAct.getText();
pspCur->uQuality = bValid
pspCur->uQuality = pspCur->bValid
? STAmount::getRate(pspCur->saOutAct, pspCur->saInAct) // Calculate relative quality.
: 0; // Mark path as inactive.
@@ -3614,7 +3647,7 @@ TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction
return tenINVALID;
}
SLE::pointer sleDst = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uDstAccountID));
SLE::pointer sleDst = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uDstAccountID));
if (!sleDst)
{
// Destination account does not exist.
@@ -3644,7 +3677,7 @@ TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction
}
// XXX Should bMax be sufficient to imply ripple?
bool bRipple = bPaths || bMax || !saDstAmount.isNative();
bool bRipple = bPaths || bMax || !saDstAmount.isNative();
if (!bRipple)
{
@@ -3714,7 +3747,7 @@ TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction
return terOVER_LIMIT;
}
if (saDstBalance.isZero())
if (!saDstBalance)
{
// XXX May be able to delete indexes for credit limits which are zero.
nothing();
@@ -3858,7 +3891,7 @@ TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction
// Partial payment not allowed.
terResult = terPATH_PARTIAL; // XXX No effect, except unfunded and charge fee.
}
else if (saPaid.isZero())
else if (!saPaid)
{
// Nothing claimed.
terResult = terPATH_EMPTY; // XXX No effect except unfundeds and charge fee.
@@ -3964,7 +3997,7 @@ TransactionEngineResult TransactionEngine::takeOffers(
STAmount& saTakerPaid,
STAmount& saTakerGot)
{
assert(!saTakerPays.isZero() && !saTakerGets.isZero());
assert(!!saTakerPays && !!saTakerGets);
Log(lsINFO) << "takeOffers: against book: " << uBookBase.ToString();
@@ -4033,12 +4066,6 @@ TransactionEngineResult TransactionEngine::takeOffers(
STAmount saOfferPays = sleOffer->getIValueFieldAmount(sfTakerGets);
STAmount saOfferGets = sleOffer->getIValueFieldAmount(sfTakerPays);
if (sleOffer->getIFieldPresent(sfGetsIssuer))
saOfferPays.setIssuer(sleOffer->getIValueFieldAccount(sfGetsIssuer).getAccountID());
if (sleOffer->getIFieldPresent(sfPaysIssuer))
saOfferGets.setIssuer(sleOffer->getIValueFieldAccount(sfPaysIssuer).getAccountID());
if (sleOffer->getIFieldPresent(sfExpiration) && sleOffer->getIFieldU32(sfExpiration) <= mLedger->getParentCloseTimeNC())
{
// Offer is expired. Delete it.
@@ -4152,14 +4179,12 @@ TransactionEngineResult TransactionEngine::doOfferCreate(const SerializedTransac
Log(lsWARNING) << "doOfferCreate> " << txn.getJson(0);
const uint32 txFlags = txn.getFlags();
const bool bPassive = !!(txFlags & tfPassive);
const uint160 uPaysIssuerID = txn.getITFieldAccount(sfPaysIssuer);
const uint160 uGetsIssuerID = txn.getITFieldAccount(sfGetsIssuer);
STAmount saTakerPays = txn.getITFieldAmount(sfTakerPays);
saTakerPays.setIssuer(uPaysIssuerID);
Log(lsWARNING) << "doOfferCreate: saTakerPays=" << saTakerPays.getFullText();
STAmount saTakerPays = txn.getITFieldAmount(sfTakerPays);
STAmount saTakerGets = txn.getITFieldAmount(sfTakerGets);
saTakerGets.setIssuer(uGetsIssuerID);
Log(lsWARNING) << "doOfferCreate: saTakerPays=" << saTakerPays.getFullText();
Log(lsWARNING) << "doOfferCreate: saTakerGets=" << saTakerGets.getFullText();
const uint160 uPaysIssuerID = saTakerPays.getIssuer();
const uint160 uGetsIssuerID = saTakerGets.getIssuer();
const uint32 uExpiration = txn.getITFieldU32(sfExpiration);
const bool bHaveExpiration = txn.getITFieldPresent(sfExpiration);
const uint32 uSequence = txn.getSequence();
@@ -4196,7 +4221,7 @@ Log(lsWARNING) << "doOfferCreate: saTakerGets=" << saTakerGets.getFullText();
terResult = tenBAD_OFFER;
}
else if (saTakerPays.isZero() || saTakerGets.isZero())
else if (!saTakerPays || !saTakerGets)
{
Log(lsWARNING) << "doOfferCreate: Malformed offer: bad amount";
@@ -4208,7 +4233,7 @@ Log(lsWARNING) << "doOfferCreate: saTakerGets=" << saTakerGets.getFullText();
terResult = tenREDUNDANT;
}
else if (saTakerPays.isNative() != uPaysIssuerID.isZero() || saTakerGets.isNative() != uGetsIssuerID.isZero())
else if (saTakerPays.isNative() != !uPaysIssuerID || saTakerGets.isNative() != !uGetsIssuerID)
{
Log(lsWARNING) << "doOfferCreate: Malformed offer: bad issuer";
@@ -4281,8 +4306,8 @@ Log(lsWARNING) << "doOfferCreate: saTakerGets=" << saTakerGets.getFullText();
// Log(lsWARNING) << "doOfferCreate: takeOffers: uGetsIssuerID=" << NewcoinAddress::createHumanAccountID(uGetsIssuerID);
if (terSUCCESS == terResult
&& !saTakerPays.isZero() // Still wanting something.
&& !saTakerGets.isZero() // Still offering something.
&& !!saTakerPays // Still wanting something.
&& !!saTakerGets // Still offering something.
&& accountFunds(mTxnAccountID, saTakerGets).isPositive()) // Still funded.
{
// We need to place the remainder of the offer into its order book.
@@ -4324,12 +4349,6 @@ Log(lsWARNING) << "doOfferCreate: saTakerGets=" << saTakerGets.getFullText();
sleOffer->setIFieldU64(sfOwnerNode, uOwnerNode);
sleOffer->setIFieldU64(sfBookNode, uBookNode);
if (!saTakerPays.isNative())
sleOffer->setIFieldAccount(sfPaysIssuer, uPaysIssuerID);
if (!saTakerGets.isNative())
sleOffer->setIFieldAccount(sfGetsIssuer, uGetsIssuerID);
if (uExpiration)
sleOffer->setIFieldU32(sfExpiration, uExpiration);

View File

@@ -61,9 +61,7 @@ TransactionFormat InnerTxnFormats[]=
{ S_FIELD(TakerPays), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(TakerGets), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
{ S_FIELD(PaysIssuer), STI_ACCOUNT, SOE_IFFLAG, 2 },
{ S_FIELD(GetsIssuer), STI_ACCOUNT, SOE_IFFLAG, 4 },
{ S_FIELD(Expiration), STI_UINT32, SOE_IFFLAG, 8 },
{ S_FIELD(Expiration), STI_UINT32, SOE_IFFLAG, 2 },
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},

View File

@@ -4,10 +4,10 @@
// Versions
//
#define SERVER_VERSION_MAJOR 0
#define SERVER_VERSION_MINOR 4
#define SERVER_VERSION_SUB "-a"
#define SERVER_NAME "NewCoin"
#define SERVER_VERSION_MAJOR 0
#define SERVER_VERSION_MINOR 4
#define SERVER_VERSION_SUB "-a"
#define SERVER_NAME "NewCoin"
#define SV_STRINGIZE(x) SV_STRINGIZE2(x)
#define SV_STRINGIZE2(x) #x
@@ -16,11 +16,11 @@
// Version we prefer to speak:
#define PROTO_VERSION_MAJOR 0
#define PROTO_VERSION_MINOR 5
#define PROTO_VERSION_MINOR 6
// Version we wil speak to:
// Version we will speak to:
#define MIN_PROTO_MAJOR 0
#define MIN_PROTO_MINOR 5
#define MIN_PROTO_MINOR 6
#define MAKE_VERSION_INT(maj,min) ((maj << 16) | min)
#define GET_VERSION_MAJOR(ver) (ver >> 16)