mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Work towards ripple and offers.
This commit is contained in:
@@ -61,12 +61,12 @@ bool transResultInfo(TransactionEngineResult terCode, std::string& strToken, std
|
||||
{ terINSUF_FEE_T, "terINSUF_FEE_T", "fee insufficient now (account doesn't exist, network load)" },
|
||||
{ terNODE_NOT_FOUND, "terNODE_NOT_FOUND", "Can not delete a directory node." },
|
||||
{ terNODE_NOT_MENTIONED, "terNODE_NOT_MENTIONED", "Could not remove node from a directory." },
|
||||
{ terNODE_NO_ROOT, "terNODE_NO_ROOT", "Directory doesn't exist." },
|
||||
{ terNODE_NO_ROOT, "terNODE_NO_ROOT", "Directory doesn't exist." },
|
||||
{ terNO_ACCOUNT, "terNO_ACCOUNT", "The source account does not exist" },
|
||||
{ terNO_DST, "terNO_DST", "The destination does not exist" },
|
||||
{ terNO_LINE_NO_ZERO, "terNO_LINE_NO_ZERO", "Can't zero non-existant line, destination might make it." },
|
||||
{ terNO_PATH, "terNO_PATH", "No path existed or met transaction/balance requirements" },
|
||||
{ terOFFER_NOT_FOUND, "terOFFER_NOT_FOUND", "Can not cancel offer." },
|
||||
{ terOFFER_NOT_FOUND, "terOFFER_NOT_FOUND", "Can not cancel offer." },
|
||||
{ terOVER_LIMIT, "terOVER_LIMIT", "Over limit." },
|
||||
{ terPAST_LEDGER, "terPAST_LEDGER", "The transaction expired and can't be applied" },
|
||||
{ terPAST_SEQ, "terPAST_SEQ", "This sequence number has already past" },
|
||||
@@ -452,7 +452,8 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
TransactionEngineParams params, Ledger::pointer ledger)
|
||||
{
|
||||
Log(lsTRACE) << "applyTransaction>";
|
||||
mLedger = ledger;
|
||||
mLedger = ledger;
|
||||
mLedgerParentCloseTime = mLedger->getParentCloseTimeNC();
|
||||
|
||||
#ifdef DEBUG
|
||||
if (1)
|
||||
@@ -536,10 +537,9 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
case ttACCOUNT_SET:
|
||||
case ttCREDIT_SET:
|
||||
case ttINVOICE:
|
||||
case ttOFFER:
|
||||
case ttOFFER_CREATE:
|
||||
case ttOFFER_CANCEL:
|
||||
case ttPASSWORD_FUND:
|
||||
case ttTRANSIT_SET:
|
||||
case ttWALLET_ADD:
|
||||
nothing();
|
||||
break;
|
||||
@@ -797,8 +797,8 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
result = doInvoice(txn, accounts);
|
||||
break;
|
||||
|
||||
case ttOFFER:
|
||||
result = doOffer(txn, accounts, srcAccountID);
|
||||
case ttOFFER_CREATE:
|
||||
result = doOfferCreate(txn, accounts, srcAccountID);
|
||||
break;
|
||||
|
||||
case ttOFFER_CANCEL:
|
||||
@@ -821,10 +821,6 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
||||
result = doPayment(txn, accounts, srcAccountID);
|
||||
break;
|
||||
|
||||
case ttTRANSIT_SET:
|
||||
result = doTransitSet(txn, accounts);
|
||||
break;
|
||||
|
||||
case ttWALLET_ADD:
|
||||
result = doWalletAdd(txn, accounts);
|
||||
break;
|
||||
@@ -1549,125 +1545,6 @@ TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction
|
||||
return terBAD_RIPPLE;
|
||||
}
|
||||
|
||||
TransactionEngineResult TransactionEngine::doTransitSet(const SerializedTransaction& st, std::vector<AffectedAccount>&)
|
||||
{
|
||||
std::cerr << "doTransitSet>" << std::endl;
|
||||
#if 0
|
||||
SLE::pointer sleSrc = accounts[0].second;
|
||||
|
||||
bool bTxnTransitRate = st->getIFieldPresent(sfTransitRate);
|
||||
bool bTxnTransitStart = st->getIFieldPresent(sfTransitStart);
|
||||
bool bTxnTransitExpire = st->getIFieldPresent(sfTransitExpire);
|
||||
uint32 uTxnTransitRate = bTxnTransitRate ? st->getIFieldU32(sfTransitRate) : 0;
|
||||
uint32 uTxnTransitStart = bTxnTransitStart ? st->getIFieldU32(sfTransitStart) : 0;
|
||||
uint32 uTxnTransitExpire = bTxnTransitExpire ? st->getIFieldU32(sfTransitExpire) : 0;
|
||||
|
||||
bool bActTransitRate = sleSrc->getIFieldPresent(sfTransitRate);
|
||||
bool bActTransitExpire = sleSrc->getIFieldPresent(sfTransitExpire);
|
||||
bool bActNextTransitRate = sleSrc->getIFieldPresent(sfNextTransitRate);
|
||||
bool bActNextTransitStart = sleSrc->getIFieldPresent(sfNextTransitStart);
|
||||
bool bActNextTransitExpire = sleSrc->getIFieldPresent(sfNextTransitExpire);
|
||||
uint32 uActTransitRate = bActTransitRate ? sleSrc->getIFieldU32(sfTransitRate) : 0;
|
||||
uint32 uActTransitExpire = bActTransitExpire ? sleSrc->getIFieldU32(sfTransitExpire) : 0;
|
||||
uint32 uActNextTransitRate = bActNextTransitRate ? sleSrc->getIFieldU32(sfNextTransitRate) : 0;
|
||||
uint32 uActNextTransitStart = bActNextTransitStart ? sleSrc->getIFieldU32(sfNextTransitStart) : 0;
|
||||
uint32 uActNextTransitExpire = bActNextTransitExpire ? sleSrc->getIFieldU32(sfNextTransitExpire) : 0;
|
||||
|
||||
//
|
||||
// Update view
|
||||
//
|
||||
|
||||
bool bNoCurrent = !bActTransitRate;
|
||||
bool bCurrentExpired =
|
||||
bActTransitExpire // Current can expire
|
||||
&& bActNextTransitStart // Have a replacement
|
||||
&& uActTransitExpire <= uLedger; // Current is expired
|
||||
|
||||
// Replace current with next if need.
|
||||
if (bNoCurrent // No current.
|
||||
&& bActNextTransitRate // Have next.
|
||||
&& uActNextTransitStart <= uLedger) // Next has started.
|
||||
{
|
||||
// Make next current.
|
||||
uActTransitRate = uActNextTransitRate;
|
||||
bActTransitExpire = bActNextTransitStart;
|
||||
uActTransitExpire = uActNextTransitExpire;
|
||||
|
||||
// Remove next.
|
||||
uActNextTransitStart = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Determine new transaction deposition.
|
||||
//
|
||||
|
||||
bool bBetterThanCurrent =
|
||||
!no current
|
||||
|| (
|
||||
Expires same or later than current
|
||||
Start before or same as current
|
||||
Fee same or less than current
|
||||
)
|
||||
|
||||
bool bBetterThanNext =
|
||||
!no next
|
||||
|| (
|
||||
Expires same or later than next
|
||||
Start before or same as next
|
||||
Fee same or less than next
|
||||
)
|
||||
|
||||
bool bBetterThanBoth =
|
||||
bBetterThanCurrent && bBetterThanNext
|
||||
|
||||
bool bCurrentBlocks =
|
||||
!bBetterThanCurrent
|
||||
&& overlaps with current
|
||||
|
||||
bool bNextBlocks =
|
||||
!bBetterThanNext
|
||||
&& overlaps with next
|
||||
|
||||
if (bBetterThanBoth)
|
||||
{
|
||||
// Erase both and install.
|
||||
|
||||
// If not starting now, install as next.
|
||||
}
|
||||
else if (bCurrentBlocks || bNextBlocks)
|
||||
{
|
||||
// Invalid ignore
|
||||
}
|
||||
else if (bBetterThanCurrent)
|
||||
{
|
||||
// Install over current
|
||||
}
|
||||
else if (bBetterThanNext)
|
||||
{
|
||||
// Install over next
|
||||
}
|
||||
else
|
||||
{
|
||||
// Error.
|
||||
}
|
||||
|
||||
return tenTRANSIT_WORSE;
|
||||
|
||||
// Set current.
|
||||
uDstTransitRate = uTxnTransitRate;
|
||||
uDstTransitExpire = uTxnTransitExpire; // 0 for never expire.
|
||||
|
||||
// Set future.
|
||||
uDstNextTransitRate = uTxnTransitRate;
|
||||
uDstNextTransitStart = uTxnTransitStart;
|
||||
uDstNextTransitExpire = uTxnTransitExpire; // 0 for never expire.
|
||||
|
||||
if (txn.getITFieldPresent(sfCurrency))
|
||||
#endif
|
||||
std::cerr << "doTransitSet<" << std::endl;
|
||||
return tenINVALID;
|
||||
}
|
||||
|
||||
TransactionEngineResult TransactionEngine::doWalletAdd(const SerializedTransaction& txn,
|
||||
std::vector<AffectedAccount>& accounts)
|
||||
{
|
||||
@@ -1736,10 +1613,168 @@ TransactionEngineResult TransactionEngine::doInvoice(const SerializedTransaction
|
||||
return tenUNKNOWN;
|
||||
}
|
||||
|
||||
// XXX Needs to take offers.
|
||||
// XXX Use bPassive when taking.
|
||||
// XXX Also use quality when rippling a take.
|
||||
TransactionEngineResult TransactionEngine::doOffer(
|
||||
#ifdef WORK_IN_PROGRESS
|
||||
// XXX Disallow loops in ripple paths
|
||||
// XXX Note accounts we visited so as not mark them found unfunded.
|
||||
// Before an offer is place into the ledger, fill as much as possible.
|
||||
// XXX Also use quality fees when rippling a take.
|
||||
// XXX Also be careful of taking own offer: delete old offer.
|
||||
// --> uBookBase: the opposite order book.
|
||||
TransactionEngineResult TransactionEngine::offerTake(
|
||||
bool bPassive,
|
||||
uint64 uTakeQuality,
|
||||
const uint256& uBookBase,
|
||||
const uint160& uTakerAccountID,
|
||||
STAmount& saTakerGets, // With issuer.
|
||||
STAmount& saTakerPays, // With issuer.
|
||||
std::vector<SLE::pointer> vspUnfundedFound)
|
||||
{
|
||||
uint256 uTipIndex = uBookIndex;
|
||||
bool bDone = true;
|
||||
STAmount saSold = 0; // XXX Add in currency
|
||||
STAmount saOffered = XXX amount to fill.
|
||||
TransactionEngineResult terResult = tenUNKNOWN;
|
||||
|
||||
while (tenUNKNOWN == terResult)
|
||||
{
|
||||
uTipIndex = Ledger::indexNext(uTipIndex);
|
||||
|
||||
uint256 uTipBase;
|
||||
uint64 uTipQuality = Ledger::indexQuality(uTipIndex, uTipBase);
|
||||
|
||||
if (saSold == saAmount)
|
||||
{
|
||||
// Filled order.
|
||||
terResult = terSUCCESS;
|
||||
}
|
||||
else if (uTipBase != uBookBase
|
||||
|| uTakeQuality < uTipQuality
|
||||
|| (bPassive && uTakeQuality == uTipQuality))
|
||||
{
|
||||
// No qualifying offer.
|
||||
|
||||
terResult = terSUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Have an offer to consider.
|
||||
LedgerStateParms qry = lepNONE;
|
||||
SLE::pointer sleOffer = mLedger->getOffer(qry, uTipIndex);
|
||||
|
||||
assert(sleOffer);
|
||||
if (!sleOffer)
|
||||
{
|
||||
// Missing ledger entry.
|
||||
Log(lsINFO) << "offerTake: Missing offer node: " << uTipIndex.ToString();
|
||||
|
||||
terResult = terBAD_LEDGER;
|
||||
}
|
||||
else
|
||||
{
|
||||
NewcoinAddress naOfferAccountID = sleOffer->getIValueFieldAccount(sfAccount);
|
||||
STAmount saOfferTakerGets = sleOffer->getIValueFieldAmount(sfAmountOut);
|
||||
|
||||
if (naOfferAccountID == uTakerAccountID)
|
||||
{
|
||||
// Would take own offer. Consider it unfunded. Delete it.
|
||||
|
||||
vspUnfundedFound.push_back(sleOffer);
|
||||
}
|
||||
else if (sleOffer->getIFieldPresent(sfExpiration) && sleOffer->getIFieldU32(sfExpiration) <= prevLedgerClose)
|
||||
{
|
||||
// Offer is expired. Delete it.
|
||||
|
||||
vspUnfundedFound.push_back(sleOffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
SLE::pointer sleOfferAccount;
|
||||
SLE::pointer sleOfferRipplePays;
|
||||
STAmount saOfferBalance;
|
||||
|
||||
if (saTakerGets.isNative())
|
||||
{
|
||||
// Handle getting stamps.
|
||||
LedgerStateParms qry = lepNONE;
|
||||
SLE::pointer sleOfferAccount = mLedger->getAccountRoot(qry, naOfferAccountID);
|
||||
if (!sleOfferAccount)
|
||||
{
|
||||
Log(lsWARNING) << "offerTake: delay: can't receive stamps from non-existant account";
|
||||
|
||||
terResult = terNO_ACCOUNT;
|
||||
}
|
||||
else
|
||||
{
|
||||
saOfferBalance = sleOfferAccount->getIValueFieldAmount(sfBalance);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handling getting ripple.
|
||||
|
||||
if (saTakerGets.getIssuer() == naOfferAccountID)
|
||||
{
|
||||
// Taker gets offer's IOUs from offerer. Always works
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sleOfferRipplePays = getRippleState(getRippleStateIndex(uSrcAccountID, saTakerGets.getIssuer(), saTakerGets.getCurrency()));
|
||||
|
||||
bool bSltD = uSrcAccountID < uIssuerOutID;
|
||||
|
||||
STAmount saSrcBalance = sleRippleState->getIValueFieldAmount(sfBalance);
|
||||
if (bSltD)
|
||||
saSrcBalance.negate(); // Put balance in low terms.
|
||||
}
|
||||
STAmount saSrcBalance = sleOfferAccount->getIValueFieldAmount(sfBalance);
|
||||
|
||||
if (saSrcBalance.isZero())
|
||||
{
|
||||
terResult = terUNFUNDED;
|
||||
}
|
||||
else
|
||||
{
|
||||
STAmount saTakerPaysCur = STAmount::getPay(saOfferTakerGets, saOfferTakerPays, saTakerWants);
|
||||
STAmount saTakerGetsCur = STAmount::getClaimed(saOfferTakerGets, saOfferTakerPays, saTakerPays);
|
||||
|
||||
saTakerWants -= saTakerGetsCur;
|
||||
|
||||
sleOfferAccount->setIFieldAmount(sfBalance, saSrcBalance - saPaid);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Handle getting IOUs.
|
||||
else
|
||||
|
||||
if (saSrcBalance.isPositive())
|
||||
{
|
||||
|
||||
}
|
||||
== saOoffer is unfunded
|
||||
else
|
||||
figure out how much to convert
|
||||
|
||||
note to counter party how much taken
|
||||
|
||||
if took it all
|
||||
deleteIt
|
||||
else
|
||||
makeChanges
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
return tenUNKNOWN == terResult ? terSUCCESS : terResult;
|
||||
}
|
||||
#endif
|
||||
|
||||
TransactionEngineResult TransactionEngine::doOfferCreate(
|
||||
const SerializedTransaction& txn,
|
||||
std::vector<AffectedAccount>& accounts,
|
||||
const uint160& uSrcAccountID)
|
||||
@@ -1748,8 +1783,8 @@ TransactionEngineResult TransactionEngine::doOffer(
|
||||
bool bPassive = !!(txFlags & tfPassive);
|
||||
STAmount saAmountIn = txn.getITFieldAmount(sfAmountIn);
|
||||
STAmount saAmountOut = txn.getITFieldAmount(sfAmountOut);
|
||||
uint160 uIssuerIn = txn.getITFieldAccount(sfIssuerIn);
|
||||
uint160 uIssuerOut = txn.getITFieldAccount(sfIssuerOut);
|
||||
uint160 uIssuerInID = txn.getITFieldAccount(sfIssuerIn);
|
||||
uint160 uIssuerOutID = txn.getITFieldAccount(sfIssuerOut);
|
||||
uint32 uExpiration = txn.getITFieldU32(sfExpiration);
|
||||
bool bHaveExpiration = txn.getITFieldPresent(sfExpiration);
|
||||
uint32 uSequence = txn.getSequence();
|
||||
@@ -1758,72 +1793,133 @@ TransactionEngineResult TransactionEngine::doOffer(
|
||||
SLE::pointer sleOffer = boost::make_shared<SerializedLedgerEntry>(ltOFFER);
|
||||
|
||||
uint256 uLedgerIndex = Ledger::getOfferIndex(uSrcAccountID, uSequence);
|
||||
Log(lsINFO) << "doOffer: Creating offer node: " << uLedgerIndex.ToString();
|
||||
Log(lsINFO) << "doOfferCreate: Creating offer node: " << uLedgerIndex.ToString();
|
||||
|
||||
uint160 uCurrencyIn = saAmountIn.getCurrency();
|
||||
uint160 uCurrencyOut = saAmountOut.getCurrency();
|
||||
|
||||
TransactionEngineResult terResult;
|
||||
TransactionEngineResult terResult = terSUCCESS;
|
||||
uint64 uOwnerNode; // Delete hint.
|
||||
uint64 uOfferNode; // Delete hint.
|
||||
// uint64 uBookNode; // Delete hint.
|
||||
uint64 uBookNode; // Delete hint.
|
||||
|
||||
uint32 uPrevLedgerTime = 0; // XXX Need previous
|
||||
|
||||
if (!bHaveExpiration || !uExpiration)
|
||||
{
|
||||
Log(lsWARNING) << "doOffer: Malformed offer: bad expiration";
|
||||
Log(lsWARNING) << "doOfferCreate: Malformed offer: bad expiration";
|
||||
|
||||
terResult = tenBAD_EXPIRATION;
|
||||
}
|
||||
else if (!bHaveExpiration || uPrevLedgerTime >= uExpiration)
|
||||
{
|
||||
Log(lsWARNING) << "doOffer: Expired transaction: offer expired";
|
||||
Log(lsWARNING) << "doOfferCreate: Expired transaction: offer expired";
|
||||
|
||||
terResult = tenEXPIRED;
|
||||
}
|
||||
else if (saAmountIn.isNative() && saAmountOut.isNative())
|
||||
{
|
||||
Log(lsWARNING) << "doOffer: Malformed offer: stamps for stamps";
|
||||
Log(lsWARNING) << "doOfferCreate: Malformed offer: stamps for stamps";
|
||||
|
||||
terResult = tenBAD_OFFER;
|
||||
}
|
||||
else if (saAmountIn.isZero() || saAmountOut.isZero())
|
||||
{
|
||||
Log(lsWARNING) << "doOffer: Malformed offer: bad amount";
|
||||
Log(lsWARNING) << "doOfferCreate: Malformed offer: bad amount";
|
||||
|
||||
terResult = tenBAD_OFFER;
|
||||
}
|
||||
else if (uCurrencyIn == uCurrencyOut && uIssuerIn == uIssuerOut)
|
||||
else if (uCurrencyIn == uCurrencyOut && uIssuerInID == uIssuerOutID)
|
||||
{
|
||||
Log(lsWARNING) << "doOffer: Malformed offer: no conversion";
|
||||
Log(lsWARNING) << "doOfferCreate: Malformed offer: no conversion";
|
||||
|
||||
terResult = tenREDUNDANT;
|
||||
}
|
||||
else if (uCurrencyIn.isZero() == uIssuerIn.isZero() && uCurrencyOut.isZero() == uIssuerOut.isZero())
|
||||
else if (saAmountIn.isNative() != uIssuerInID.isZero() || saAmountOut.isNative() != uIssuerOutID.isZero())
|
||||
{
|
||||
Log(lsWARNING) << "doOffer: Malformed offer: bad issuer";
|
||||
Log(lsWARNING) << "doOfferCreate: Malformed offer: bad issuer";
|
||||
|
||||
terResult = tenBAD_ISSUER;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure signer has funds.
|
||||
SLE::pointer sleSrc = accounts[0].second;
|
||||
STAmount saSrcBalance = sleSrc->getIValueFieldAmount(sfBalance);
|
||||
|
||||
// XXX check currencies and accounts
|
||||
// XXX check funded
|
||||
// XXX check output credit line exists
|
||||
// XXX when deleting a credit line, delete outstanding offers
|
||||
if (saAmountOut.isNative() && !saSrcBalance.isZero())
|
||||
{
|
||||
// Delivering stamps and has stamps.
|
||||
nothing();
|
||||
}
|
||||
else if (uIssuerOutID == uSrcAccountID)
|
||||
{
|
||||
// Delivering self issued IOUs.
|
||||
nothing();
|
||||
}
|
||||
else
|
||||
{
|
||||
LedgerStateParms qry = lepNONE;
|
||||
SLE::pointer sleRippleOut = mLedger->getRippleState(qry, Ledger::getRippleStateIndex(uSrcAccountID, uIssuerOutID, uCurrencyOut));
|
||||
bool bSltD = uSrcAccountID < uIssuerOutID;
|
||||
|
||||
// XXX Only place the offer if a portion is not filled.
|
||||
STAmount saSrcBalance = sleRippleOut->getIValueFieldAmount(sfBalance);
|
||||
if (bSltD)
|
||||
saSrcBalance.negate(); // Put balance in low terms.
|
||||
|
||||
if (terSUCCESS == terResult)
|
||||
terResult = dirAdd(accounts, uOwnerNode, Ledger::getOfferDirIndex(uSrcAccountID), uLedgerIndex);
|
||||
if (saSrcBalance.isPositive())
|
||||
{
|
||||
// Funded.
|
||||
nothing();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(lsWARNING) << "doOfferCreate: delay: offers must be funded";
|
||||
|
||||
terResult = terUNFUNDED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (terSUCCESS == terResult)
|
||||
{
|
||||
terResult = dirAdd(accounts, uOfferNode,
|
||||
Ledger::getQualityIndex(
|
||||
Ledger::getBookBase(uCurrencyIn, uIssuerIn, uCurrencyOut, uIssuerOut),
|
||||
STAmount::getRate(saAmountOut, saAmountIn)),
|
||||
uLedgerIndex);
|
||||
LedgerStateParms qry = lepNONE;
|
||||
SLE::pointer sleRippleIn = mLedger->getAccountRoot(qry, uIssuerInID);
|
||||
if (!sleRippleIn)
|
||||
{
|
||||
Log(lsWARNING) << "doOfferCreate: delay: can't receive IOUs from non-existant issuer";
|
||||
|
||||
terResult = terNO_ACCOUNT;
|
||||
}
|
||||
}
|
||||
|
||||
if (terSUCCESS == terResult)
|
||||
{
|
||||
#ifdef WORK_IN_PROGRESS
|
||||
terResult = offerTake(
|
||||
bPassive,
|
||||
STAmount::getRate(saAmountIn, saAmountOut),
|
||||
Ledger::getBookBase(uCurrencyOut, uIssuerOutID, uCurrencyIn, uIssuerInID)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
// XXX Check if some portion of order was not complete.
|
||||
|
||||
if (terSUCCESS == terResult)
|
||||
{
|
||||
// Add offer to owner's directory.
|
||||
terResult = dirAdd(accounts, uOwnerNode, Ledger::getOwnerDirIndex(uSrcAccountID), uLedgerIndex);
|
||||
}
|
||||
|
||||
if (terSUCCESS == terResult)
|
||||
{
|
||||
// Add offer to order book.
|
||||
terResult = dirAdd(
|
||||
accounts,
|
||||
uBookNode,
|
||||
Ledger::getQualityIndex(
|
||||
Ledger::getBookBase(uCurrencyIn, uIssuerInID, uCurrencyOut, uIssuerOutID),
|
||||
STAmount::getRate(saAmountOut, saAmountIn)),
|
||||
uLedgerIndex);
|
||||
}
|
||||
|
||||
if (terSUCCESS == terResult)
|
||||
@@ -1835,7 +1931,7 @@ TransactionEngineResult TransactionEngine::doOffer(
|
||||
sleOffer->setIFieldAmount(sfAmountIn, saAmountIn);
|
||||
sleOffer->setIFieldAmount(sfAmountOut, saAmountOut);
|
||||
sleOffer->setIFieldU64(sfOwnerNode, uOwnerNode);
|
||||
sleOffer->setIFieldU64(sfOfferNode, uOfferNode);
|
||||
sleOffer->setIFieldU64(sfBookNode, uBookNode);
|
||||
sleOffer->setIFieldU32(sfExpiration, uExpiration);
|
||||
|
||||
if (bPassive)
|
||||
|
||||
Reference in New Issue
Block a user