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 into continuousClose
This commit is contained in:
@@ -737,41 +737,50 @@ uint64 STAmount::getRate(const STAmount& offerOut, const STAmount& offerIn)
|
||||
return (ret << (64 - 8)) | r.getMantissa();
|
||||
}
|
||||
|
||||
STAmount STAmount::getClaimed(STAmount& offerOut, STAmount& offerIn, STAmount& paid)
|
||||
{ // if someone is offering (offerOut) for (offerIn), and I pay (paid), how much do I get?
|
||||
|
||||
offerIn.throwComparable(paid);
|
||||
|
||||
if (offerIn.isZero() || offerOut.isZero())
|
||||
{ // If the offer is invalid or empty, you pay nothing and get nothing and the offer is dead
|
||||
offerIn.zero();
|
||||
offerOut.zero();
|
||||
paid.zero();
|
||||
return STAmount();
|
||||
}
|
||||
|
||||
// If you pay nothing, you get nothing. Offer is untouched
|
||||
if (paid.isZero()) return STAmount();
|
||||
|
||||
if (paid >= offerIn)
|
||||
{ // If you pay equal to or more than the offer amount, you get the whole offer and pay its input
|
||||
STAmount ret(offerOut);
|
||||
paid = offerIn;
|
||||
offerOut.zero();
|
||||
offerIn.zero();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// partial satisfaction of a normal offer
|
||||
STAmount ret = divide(multiply(paid, offerOut, uint160(1)), offerIn, offerOut.getCurrency());
|
||||
offerOut -= ret;
|
||||
offerIn -= paid;
|
||||
if (offerOut.isZero() || offerIn.isZero())
|
||||
// Taker gets all taker can pay for with saTakerFunds, limited by saOfferPays and saOfferFunds.
|
||||
// --> saOfferFunds: Limit for saOfferPays
|
||||
// --> saTakerFunds: Limit for saOfferGets
|
||||
// --> saOfferPays: Request : this should be reduced as the offer is fullfilled.
|
||||
// --> saOfferGets: Request : this should be reduced as the offer is fullfilled.
|
||||
// --> saTakerPays: Total : Used to know the approximate ratio of the exchange.
|
||||
// --> saTakerGets: Total : Used to know the approximate ratio of the exchange.
|
||||
// <-- saTakerPaid: Actual
|
||||
// <-- saTakerGot: Actual
|
||||
// <-- bRemove: remove offer it is either fullfilled or unfunded
|
||||
bool STAmount::applyOffer(
|
||||
const STAmount& saOfferFunds, const STAmount& saTakerFunds,
|
||||
const STAmount& saOfferPays, const STAmount& saOfferGets,
|
||||
const STAmount& saTakerPays, const STAmount& saTakerGets,
|
||||
STAmount& saTakerPaid, STAmount& saTakerGot)
|
||||
{
|
||||
offerIn.zero();
|
||||
offerOut.zero();
|
||||
saOfferGets.throwComparable(saTakerPays);
|
||||
|
||||
assert(!saOfferFunds.isZero() && !saTakerFunds.isZero()); // Must have funds.
|
||||
assert(!saOfferGets.isZero() && !saOfferPays.isZero()); // Must not be a null offer.
|
||||
|
||||
// Amount offer can pay out, limited by offer and funds.
|
||||
STAmount saOfferPaysAvailable = saOfferFunds < saOfferPays ? saOfferFunds : saOfferPays;
|
||||
|
||||
// Amount offer needs to get to be complete, limited by offer funds.
|
||||
STAmount saOfferGetsAvailable =
|
||||
saOfferFunds == saOfferPays
|
||||
? saOfferGets // Offer was fully funded, avoid shenanigans.
|
||||
: divide(multiply(saTakerPays, saOfferPaysAvailable, uint160(1)), saTakerGets, saOfferGets.getCurrency());
|
||||
|
||||
if (saTakerFunds >= saOfferGetsAvailable)
|
||||
{
|
||||
// Taker gets all of offer available.
|
||||
saTakerPaid = saOfferGetsAvailable; // Taker paid what offer could get.
|
||||
saTakerGot = saOfferPaysAvailable; // Taker got what offer could pay.
|
||||
|
||||
return true; // No left over offer.
|
||||
}
|
||||
return ret;
|
||||
|
||||
// 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());
|
||||
|
||||
return saTakerGot >= saOfferPaysAvailable;
|
||||
}
|
||||
|
||||
STAmount STAmount::getPay(const STAmount& offerOut, const STAmount& offerIn, const STAmount& needed)
|
||||
|
||||
@@ -166,10 +166,10 @@ public:
|
||||
static Ledger::pointer loadByHash(const uint256& ledgerHash);
|
||||
|
||||
// next/prev function
|
||||
SLE::pointer getNextSLE(const uint256& hash); // first node >hash
|
||||
SLE::pointer getNextSLE(const uint256& hash, const uint256& max); // first node >hash, <max
|
||||
SLE::pointer getPrevSLE(const uint256& hash); // last node <hash
|
||||
SLE::pointer getPrevSLE(const uint256& hash, const uint256& min); // last node <hash, >min
|
||||
SLE::pointer getNextSLE(const uint256& uHash); // first node >hash
|
||||
SLE::pointer getNextSLE(const uint256& uHash, const uint256& uEnd); // first node >hash, <end
|
||||
SLE::pointer getPrevSLE(const uint256& uHash); // last node <hash
|
||||
SLE::pointer getPrevSLE(const uint256& uHash, const uint256& uBegin); // last node <hash, >begin
|
||||
|
||||
// index calculation functions
|
||||
static uint256 getAccountRootIndex(const uint160& uAccountID);
|
||||
@@ -244,6 +244,7 @@ public:
|
||||
|
||||
static uint256 getQualityIndex(const uint256& uBase, const uint64 uNodeDir=0);
|
||||
static uint256 getQualityNext(const uint256& uBase);
|
||||
static uint64 getQuality(const uint256& uBase);
|
||||
|
||||
//
|
||||
// Ripple functions : credit lines
|
||||
|
||||
@@ -46,11 +46,14 @@ LedgerEntryFormat LedgerFormats[]=
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Sequence), STI_UINT32, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(AmountIn), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(AmountOut), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Expiration), STI_UINT32, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(OwnerNode), STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(TakerPays), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(TakerGets), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Directory), STI_HASH256, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(BookNode), STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(OwnerNode), STI_UINT64, 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(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
|
||||
@@ -15,6 +15,11 @@ uint256 Ledger::getQualityIndex(const uint256& uBase, const uint64 uNodeDir)
|
||||
return uNode;
|
||||
}
|
||||
|
||||
uint64 Ledger::getQuality(const uint256& uBase)
|
||||
{
|
||||
return be64toh(((uint64*) uBase.end())[-1]);
|
||||
}
|
||||
|
||||
uint256 Ledger::getQualityNext(const uint256& uBase)
|
||||
{
|
||||
static uint256 uNext("10000000000000000");
|
||||
@@ -43,8 +48,8 @@ uint256 Ledger::getBookBase(const uint160& uCurrencyIn, const uint160& uAccountI
|
||||
bool bOutNative = uCurrencyOut.isZero();
|
||||
|
||||
assert(!bInNative || !bOutNative); // Stamps to stamps not allowed.
|
||||
assert(bInNative == !uAccountIn.isZero()); // Make sure issuer is specified as needed.
|
||||
assert(bOutNative == !uAccountOut.isZero()); // Make sure issuer is specified as needed.
|
||||
assert(bInNative == uAccountIn.isZero()); // Make sure issuer is specified as needed.
|
||||
assert(bOutNative == uAccountOut.isZero()); // Make sure issuer is specified as needed.
|
||||
assert(uCurrencyIn != uCurrencyOut || uAccountIn != uAccountOut); // Currencies or accounts must differ.
|
||||
|
||||
Serializer s(82);
|
||||
|
||||
@@ -45,34 +45,34 @@ LedgerStateParms Ledger::writeBack(LedgerStateParms parms, SLE::pointer entry)
|
||||
return lepOKAY;
|
||||
}
|
||||
|
||||
SLE::pointer Ledger::getNextSLE(const uint256& hash)
|
||||
SLE::pointer Ledger::getNextSLE(const uint256& uHash)
|
||||
{
|
||||
SHAMapItem::pointer node = mAccountStateMap->peekNextItem(hash);
|
||||
SHAMapItem::pointer node = mAccountStateMap->peekNextItem(uHash);
|
||||
if (!node)
|
||||
return SLE::pointer();
|
||||
return boost::make_shared<SLE>(node->peekSerializer(), node->getTag());
|
||||
}
|
||||
|
||||
SLE::pointer Ledger::getNextSLE(const uint256& hash, const uint256& max)
|
||||
SLE::pointer Ledger::getNextSLE(const uint256& uHash, const uint256& uEnd)
|
||||
{
|
||||
SHAMapItem::pointer node = mAccountStateMap->peekNextItem(hash);
|
||||
if ((!node) || (node->getTag() > max))
|
||||
SHAMapItem::pointer node = mAccountStateMap->peekNextItem(uHash);
|
||||
if ((!node) || (node->getTag() > uEnd))
|
||||
return SLE::pointer();
|
||||
return boost::make_shared<SLE>(node->peekSerializer(), node->getTag());
|
||||
}
|
||||
|
||||
SLE::pointer Ledger::getPrevSLE(const uint256& hash)
|
||||
SLE::pointer Ledger::getPrevSLE(const uint256& uHash)
|
||||
{
|
||||
SHAMapItem::pointer node = mAccountStateMap->peekPrevItem(hash);
|
||||
SHAMapItem::pointer node = mAccountStateMap->peekPrevItem(uHash);
|
||||
if (!node)
|
||||
return SLE::pointer();
|
||||
return boost::make_shared<SLE>(node->peekSerializer(), node->getTag());
|
||||
}
|
||||
|
||||
SLE::pointer Ledger::getPrevSLE(const uint256& hash, const uint256& min)
|
||||
SLE::pointer Ledger::getPrevSLE(const uint256& uHash, const uint256& uBegin)
|
||||
{
|
||||
SHAMapItem::pointer node = mAccountStateMap->peekNextItem(hash);
|
||||
if ((!node) || (node->getTag() < min))
|
||||
SHAMapItem::pointer node = mAccountStateMap->peekNextItem(uHash);
|
||||
if ((!node) || (node->getTag() < uBegin))
|
||||
return SLE::pointer();
|
||||
return boost::make_shared<SLE>(node->peekSerializer(), node->getTag());
|
||||
}
|
||||
|
||||
@@ -353,7 +353,6 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
|
||||
ourVC.highNode = theApp->getWallet().getNodePublic();
|
||||
}
|
||||
|
||||
|
||||
for (std::vector<Peer::pointer>::const_iterator it = peerList.begin(), end = peerList.end(); it != end; ++it)
|
||||
{
|
||||
if (!*it)
|
||||
|
||||
@@ -301,9 +301,18 @@ std::string NewcoinAddress::humanAccountID() const
|
||||
}
|
||||
|
||||
bool NewcoinAddress::setAccountID(const std::string& strAccountID)
|
||||
{
|
||||
if (strAccountID == "none")
|
||||
{
|
||||
SetData(VER_ACCOUNT_ID, std::vector<unsigned char>());
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SetString(strAccountID.c_str(), VER_ACCOUNT_ID);
|
||||
}
|
||||
}
|
||||
|
||||
void NewcoinAddress::setAccountID(const uint160& hash160)
|
||||
{
|
||||
|
||||
@@ -45,6 +45,8 @@ Json::Value RPCServer::RPCError(int iError)
|
||||
{ rpcDST_ACT_MALFORMED, "dstActMalformed", "Destination account is malformed." },
|
||||
{ rpcDST_AMT_MALFORMED, "dstAmtMalformed", "Destination amount/currency is malformed." },
|
||||
{ rpcFAIL_GEN_DECRPYT, "failGenDecrypt", "Failed to decrypt generator." },
|
||||
{ rpcGETS_ACT_MALFORMED, "getsActMalformed", "Gets account malformed." },
|
||||
{ rpcGETS_AMT_MALFORMED, "getsAmtMalformed", "Gets ammount malformed." },
|
||||
{ rpcHOST_IP_MALFORMED, "hostIpMalformed", "Host IP is malformed." },
|
||||
{ rpcINSUF_FUNDS, "insufFunds", "Insufficient funds." },
|
||||
{ rpcINTERNAL, "internal", "Internal error." },
|
||||
@@ -63,6 +65,8 @@ Json::Value RPCServer::RPCError(int iError)
|
||||
{ rpcNO_NETWORK, "noNetwork", "Network not available." },
|
||||
{ rpcNO_PERMISSION, "noPermission", "You don't have permission for this command." },
|
||||
{ rpcPASSWD_CHANGED, "passwdChanged", "Wrong key, password changed." },
|
||||
{ rpcPAYS_ACT_MALFORMED, "paysActMalformed", "Pays account malformed." },
|
||||
{ rpcPAYS_AMT_MALFORMED, "paysAmtMalformed", "Pays amount malformed." },
|
||||
{ rpcPORT_MALFORMED, "portMalformed", "Port is malformed." },
|
||||
{ rpcPUBLIC_MALFORMED, "publicMalformed", "Public key is malformed." },
|
||||
{ rpcSRC_ACT_MALFORMED, "srcActMalformed", "Source account is malformed." },
|
||||
@@ -826,14 +830,122 @@ Json::Value RPCServer::doNicknameSet(const Json::Value& params)
|
||||
return obj;
|
||||
}
|
||||
|
||||
Json::Value RPCServer::doOffer(const Json::Value ¶ms)
|
||||
// offer_create <seed> <paying_account> <taker_pays_amount> <taker_pays_currency> <taker_pays_issuer> <takers_gets_amount> <takers_gets_currency> <takers_gets_issuer> <expires> [passive]
|
||||
Json::Value RPCServer::doOfferCreate(const Json::Value ¶ms)
|
||||
{
|
||||
return RPCError(rpcNOT_IMPL);
|
||||
NewcoinAddress naSeed;
|
||||
NewcoinAddress naSrcAccountID;
|
||||
STAmount saTakerPays;
|
||||
STAmount saTakerGets;
|
||||
NewcoinAddress naTakerPaysID;
|
||||
NewcoinAddress naTakerGetsID;
|
||||
|
||||
if (!naSeed.setSeedGeneric(params[0u].asString()))
|
||||
{
|
||||
return RPCError(rpcBAD_SEED);
|
||||
}
|
||||
else if (!naSrcAccountID.setAccountID(params[1u].asString()))
|
||||
{
|
||||
return RPCError(rpcSRC_ACT_MALFORMED);
|
||||
}
|
||||
else if (!saTakerPays.setValue(params[2u].asString(), params[3u].asString()))
|
||||
{
|
||||
return RPCError(rpcPAYS_AMT_MALFORMED);
|
||||
}
|
||||
else if (!naTakerPaysID.setAccountID(params[4u].asString()))
|
||||
{
|
||||
return RPCError(rpcPAYS_ACT_MALFORMED);
|
||||
}
|
||||
else if (!saTakerGets.setValue(params[5u].asString(), params[6u].asString()))
|
||||
{
|
||||
return RPCError(rpcGETS_AMT_MALFORMED);
|
||||
}
|
||||
else if (!naTakerGetsID.setAccountID(params[7u].asString()))
|
||||
{
|
||||
return RPCError(rpcGETS_ACT_MALFORMED);
|
||||
}
|
||||
else if (params.size() == 10 && params[9u].asString() != "passive")
|
||||
{
|
||||
return RPCError(rpcINVALID_PARAMS);
|
||||
}
|
||||
|
||||
uint32 uExpiration = lexical_cast_s<int>(params[8u].asString());
|
||||
bool bPassive = params.size() == 10;
|
||||
|
||||
saTakerPays.setIssuer(naTakerPaysID.getAccountID());
|
||||
saTakerGets.setIssuer(naTakerGetsID.getAccountID());
|
||||
|
||||
NewcoinAddress naMasterGenerator;
|
||||
NewcoinAddress naAccountPublic;
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(mNetOps->getCurrentLedger(), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, theConfig.FEE_DEFAULT, asSrc, naMasterGenerator);
|
||||
|
||||
if (!obj.empty())
|
||||
return obj;
|
||||
|
||||
Transaction::pointer trans = Transaction::sharedOfferCreate(
|
||||
naAccountPublic, naAccountPrivate,
|
||||
naSrcAccountID,
|
||||
asSrc->getSeq(),
|
||||
theConfig.FEE_DEFAULT,
|
||||
0, // YYY No source tag
|
||||
bPassive,
|
||||
saTakerPays,
|
||||
saTakerGets,
|
||||
uExpiration);
|
||||
|
||||
(void) mNetOps->processTransaction(trans);
|
||||
|
||||
obj["transaction"] = trans->getSTransaction()->getJson(0);
|
||||
obj["status"] = trans->getStatus();
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
// offer_cancel <seed> <paying_account> <sequence>
|
||||
Json::Value RPCServer::doOfferCancel(const Json::Value ¶ms)
|
||||
{
|
||||
return RPCError(rpcNOT_IMPL);
|
||||
NewcoinAddress naSeed;
|
||||
NewcoinAddress naSrcAccountID;
|
||||
uint32 uSequence = lexical_cast_s<int>(params[2u].asString());
|
||||
|
||||
if (!naSeed.setSeedGeneric(params[0u].asString()))
|
||||
{
|
||||
return RPCError(rpcBAD_SEED);
|
||||
}
|
||||
else if (!naSrcAccountID.setAccountID(params[1u].asString()))
|
||||
{
|
||||
return RPCError(rpcSRC_ACT_MALFORMED);
|
||||
}
|
||||
|
||||
NewcoinAddress naMasterGenerator;
|
||||
NewcoinAddress naAccountPublic;
|
||||
NewcoinAddress naAccountPrivate;
|
||||
AccountState::pointer asSrc;
|
||||
STAmount saSrcBalance;
|
||||
Json::Value obj = authorize(mNetOps->getCurrentLedger(), naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
|
||||
saSrcBalance, theConfig.FEE_DEFAULT, asSrc, naMasterGenerator);
|
||||
|
||||
if (!obj.empty())
|
||||
return obj;
|
||||
|
||||
Transaction::pointer trans = Transaction::sharedOfferCancel(
|
||||
naAccountPublic, naAccountPrivate,
|
||||
naSrcAccountID,
|
||||
asSrc->getSeq(),
|
||||
theConfig.FEE_DEFAULT,
|
||||
0, // YYY No source tag
|
||||
uSequence);
|
||||
|
||||
(void) mNetOps->processTransaction(trans);
|
||||
|
||||
obj["transaction"] = trans->getSTransaction()->getJson(0);
|
||||
obj["status"] = trans->getStatus();
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
// password_fund <seed> <paying_account> [<account>]
|
||||
@@ -1990,7 +2102,7 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params
|
||||
{ "ledger", &RPCServer::doLedger, 0, 2, false, optNetwork },
|
||||
{ "nickname_info", &RPCServer::doNicknameInfo, 1, 1, false, optCurrent },
|
||||
{ "nickname_set", &RPCServer::doNicknameSet, 2, 3, false, optCurrent },
|
||||
{ "offer", &RPCServer::doOffer, 7, 8, false, optCurrent },
|
||||
{ "offer_create", &RPCServer::doOfferCreate, 9, 10, false, optCurrent },
|
||||
{ "offer_cancel", &RPCServer::doOfferCancel, 3, 3, false, optCurrent },
|
||||
{ "password_fund", &RPCServer::doPasswordFund, 2, 3, false, optCurrent },
|
||||
{ "password_set", &RPCServer::doPasswordSet, 2, 3, false, optNetwork },
|
||||
|
||||
@@ -51,11 +51,15 @@ public:
|
||||
rpcBAD_SEED,
|
||||
rpcDST_ACT_MALFORMED,
|
||||
rpcDST_AMT_MALFORMED,
|
||||
rpcGETS_ACT_MALFORMED,
|
||||
rpcGETS_AMT_MALFORMED,
|
||||
rpcHOST_IP_MALFORMED,
|
||||
rpcLGR_IDXS_INVALID,
|
||||
rpcLGR_IDX_MALFORMED,
|
||||
rpcNICKNAME_MALFORMED,
|
||||
rpcNICKNAME_PERM,
|
||||
rpcPAYS_ACT_MALFORMED,
|
||||
rpcPAYS_AMT_MALFORMED,
|
||||
rpcPORT_MALFORMED,
|
||||
rpcPUBLIC_MALFORMED,
|
||||
rpcSRC_ACT_MALFORMED,
|
||||
@@ -133,7 +137,7 @@ private:
|
||||
Json::Value doLedger(const Json::Value& params);
|
||||
Json::Value doNicknameInfo(const Json::Value& params);
|
||||
Json::Value doNicknameSet(const Json::Value& params);
|
||||
Json::Value doOffer(const Json::Value& params);
|
||||
Json::Value doOfferCreate(const Json::Value& params);
|
||||
Json::Value doOfferCancel(const Json::Value& params);
|
||||
Json::Value doPasswordFund(const Json::Value& params);
|
||||
Json::Value doPasswordSet(const Json::Value& params);
|
||||
|
||||
@@ -30,8 +30,6 @@ enum SOE_Field
|
||||
sfAccount,
|
||||
sfAccountID,
|
||||
sfAmount,
|
||||
sfAmountIn,
|
||||
sfAmountOut,
|
||||
sfAuthorizedKey,
|
||||
sfBalance,
|
||||
sfBookNode,
|
||||
@@ -44,6 +42,7 @@ enum SOE_Field
|
||||
sfCurrencyIn,
|
||||
sfCurrencyOut,
|
||||
sfDestination,
|
||||
sfDirectory,
|
||||
sfDomain,
|
||||
sfEmailHash,
|
||||
sfExpiration,
|
||||
@@ -52,6 +51,7 @@ enum SOE_Field
|
||||
sfFlags,
|
||||
sfGenerator,
|
||||
sfGeneratorID,
|
||||
sfGetsIssuer,
|
||||
sfHash,
|
||||
sfHighID,
|
||||
sfHighLimit,
|
||||
@@ -60,8 +60,6 @@ enum SOE_Field
|
||||
sfIndexNext,
|
||||
sfIndexPrevious,
|
||||
sfInvoiceID,
|
||||
sfIssuerIn,
|
||||
sfIssuerOut,
|
||||
sfLastNode,
|
||||
sfLastReceive,
|
||||
sfLastTxn,
|
||||
@@ -81,6 +79,7 @@ enum SOE_Field
|
||||
sfOfferSequence,
|
||||
sfOwnerNode,
|
||||
sfPaths,
|
||||
sfPaysIssuer,
|
||||
sfPubKey,
|
||||
sfQualityIn,
|
||||
sfQualityOut,
|
||||
@@ -89,6 +88,8 @@ enum SOE_Field
|
||||
sfSignature,
|
||||
sfSigningKey,
|
||||
sfSourceTag,
|
||||
sfTakerGets,
|
||||
sfTakerPays,
|
||||
sfTarget,
|
||||
sfTargetLedger,
|
||||
sfTransferRate,
|
||||
|
||||
@@ -260,6 +260,7 @@ std::string STTaggedList::getText() const
|
||||
Json::Value STTaggedList::getJson(int) const
|
||||
{
|
||||
Json::Value ret(Json::arrayValue);
|
||||
|
||||
for (std::vector<TaggedListItem>::const_iterator it=value.begin(); it!=value.end(); ++it)
|
||||
{
|
||||
Json::Value elem(Json::arrayValue);
|
||||
@@ -267,6 +268,7 @@ Json::Value STTaggedList::getJson(int) const
|
||||
elem.append(strHex(it->second));
|
||||
ret.append(elem);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -330,7 +330,11 @@ public:
|
||||
|
||||
// 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?
|
||||
static STAmount getClaimed(STAmount& offerOut, STAmount& offerIn, STAmount& paid);
|
||||
static bool applyOffer(
|
||||
const STAmount& saOfferFunds, const STAmount& saTakerFunds,
|
||||
const STAmount& saOfferPays, const STAmount& saOfferGets,
|
||||
const STAmount& saTakerPays, const STAmount& saTakerGets,
|
||||
STAmount& saTakerPaid, STAmount& saTakerGot);
|
||||
|
||||
// Someone is offering X for Y, I need Z, how much do I pay
|
||||
static STAmount getPay(const STAmount& offerOut, const STAmount& offerIn, const STAmount& needed);
|
||||
|
||||
@@ -302,6 +302,81 @@ Transaction::pointer Transaction::sharedNicknameSet(
|
||||
return tResult->setNicknameSet(naPrivateKey, uNickname, bSetOffer, saMinimumOffer, vucSignature);
|
||||
}
|
||||
|
||||
//
|
||||
// OfferCreate
|
||||
//
|
||||
|
||||
Transaction::pointer Transaction::setOfferCreate(
|
||||
const NewcoinAddress& naPrivateKey,
|
||||
bool bPassive,
|
||||
const STAmount& saTakerPays,
|
||||
const STAmount& saTakerGets,
|
||||
uint32 uExpiration)
|
||||
{
|
||||
if (bPassive)
|
||||
mTransaction->setITFieldU32(sfFlags, tfPassive);
|
||||
|
||||
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);
|
||||
|
||||
sign(naPrivateKey);
|
||||
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
Transaction::pointer Transaction::sharedOfferCreate(
|
||||
const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
|
||||
const NewcoinAddress& naSourceAccount,
|
||||
uint32 uSeq,
|
||||
const STAmount& saFee,
|
||||
uint32 uSourceTag,
|
||||
bool bPassive,
|
||||
const STAmount& saTakerPays,
|
||||
const STAmount& saTakerGets,
|
||||
uint32 uExpiration)
|
||||
{
|
||||
pointer tResult = boost::make_shared<Transaction>(ttOFFER_CREATE, naPublicKey, naSourceAccount, uSeq, saFee, uSourceTag);
|
||||
|
||||
return tResult->setOfferCreate(naPrivateKey, bPassive, saTakerPays, saTakerGets, uExpiration);
|
||||
}
|
||||
|
||||
//
|
||||
// OfferCancel
|
||||
//
|
||||
|
||||
Transaction::pointer Transaction::setOfferCancel(
|
||||
const NewcoinAddress& naPrivateKey,
|
||||
uint32 uSequence)
|
||||
{
|
||||
mTransaction->setITFieldU32(sfOfferSequence, uSequence);
|
||||
|
||||
sign(naPrivateKey);
|
||||
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
Transaction::pointer Transaction::sharedOfferCancel(
|
||||
const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
|
||||
const NewcoinAddress& naSourceAccount,
|
||||
uint32 uSeq,
|
||||
const STAmount& saFee,
|
||||
uint32 uSourceTag,
|
||||
uint32 uSequence)
|
||||
{
|
||||
pointer tResult = boost::make_shared<Transaction>(ttOFFER_CANCEL, naPublicKey, naSourceAccount, uSeq, saFee, uSourceTag);
|
||||
|
||||
return tResult->setOfferCancel(naPrivateKey, uSequence);
|
||||
}
|
||||
|
||||
//
|
||||
// PasswordFund
|
||||
//
|
||||
|
||||
@@ -78,6 +78,17 @@ private:
|
||||
const STAmount& saMinimumOffer,
|
||||
const std::vector<unsigned char>& vucSignature);
|
||||
|
||||
Transaction::pointer setOfferCreate(
|
||||
const NewcoinAddress& naPrivateKey,
|
||||
bool bPassive,
|
||||
const STAmount& saTakerPays,
|
||||
const STAmount& saTakerGets,
|
||||
uint32 uExpiration);
|
||||
|
||||
Transaction::pointer setOfferCancel(
|
||||
const NewcoinAddress& naPrivateKey,
|
||||
uint32 uSequence);
|
||||
|
||||
Transaction::pointer setPasswordFund(
|
||||
const NewcoinAddress& naPrivateKey,
|
||||
const NewcoinAddress& naDstAccountID);
|
||||
@@ -200,6 +211,27 @@ public:
|
||||
const STAmount& saSendMax,
|
||||
const STPathSet& saPaths);
|
||||
|
||||
// Place an offer.
|
||||
static Transaction::pointer sharedOfferCreate(
|
||||
const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
|
||||
const NewcoinAddress& naSourceAccount,
|
||||
uint32 uSeq,
|
||||
const STAmount& saFee,
|
||||
uint32 uSourceTag,
|
||||
bool bPassive,
|
||||
const STAmount& saTakerPays,
|
||||
const STAmount& saTakerGets,
|
||||
uint32 uExpiration);
|
||||
|
||||
// Cancel an offer
|
||||
static Transaction::pointer sharedOfferCancel(
|
||||
const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
|
||||
const NewcoinAddress& naSourceAccount,
|
||||
uint32 uSeq,
|
||||
const STAmount& saFee,
|
||||
uint32 uSourceTag,
|
||||
uint32 uSequence);
|
||||
|
||||
// Add an account to a wallet.
|
||||
static Transaction::pointer sharedWalletAdd(
|
||||
const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -89,25 +89,31 @@ enum TransactionEngineParams
|
||||
|
||||
enum TransactionAccountAction
|
||||
{
|
||||
taaACCESS,
|
||||
taaNONE,
|
||||
taaCREATE,
|
||||
taaMODIFY,
|
||||
taaDELETE
|
||||
taaDELETE,
|
||||
taaUNFUNDED,
|
||||
};
|
||||
|
||||
typedef std::pair<TransactionAccountAction, SerializedLedgerEntry::pointer> AffectedAccount;
|
||||
|
||||
// One instance per ledger.
|
||||
// Only one transaction applied at a time.
|
||||
class TransactionEngine
|
||||
{
|
||||
private:
|
||||
typedef boost::unordered_map<SLE::pointer, TransactionAccountAction> entryMap;
|
||||
typedef boost::unordered_map<SLE::pointer, TransactionAccountAction>::iterator entryMap_iterator;
|
||||
typedef boost::unordered_map<SLE::pointer, TransactionAccountAction>::const_iterator entryMap_const_iterator;
|
||||
typedef boost::unordered_map<SLE::pointer, TransactionAccountAction>::iterator::value_type entryMap_value_type;
|
||||
|
||||
TransactionEngineResult dirAdd(
|
||||
std::vector<AffectedAccount>& accounts,
|
||||
uint64& uNodeDir, // Node of entry.
|
||||
const uint256& uRootIndex,
|
||||
const uint256& uLedgerIndex);
|
||||
|
||||
TransactionEngineResult dirDelete(
|
||||
std::vector<AffectedAccount>& accounts,
|
||||
const uint64& uNodeDir, // Node item is mentioned in.
|
||||
const uint256& uRootIndex,
|
||||
const uint256& uLedgerIndex); // Item being deleted
|
||||
@@ -135,33 +141,50 @@ private:
|
||||
} paymentGroup;
|
||||
#endif
|
||||
|
||||
TransactionEngineResult setAuthorized(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts, bool bMustSetGenerator);
|
||||
TransactionEngineResult setAuthorized(const SerializedTransaction& txn, SLE::pointer sleSrc, bool bMustSetGenerator);
|
||||
|
||||
TransactionEngineResult takeOffers(
|
||||
bool bPassive,
|
||||
const uint256& uBookBase,
|
||||
const uint160& uTakerAccountID,
|
||||
const STAmount& saTakerPays,
|
||||
const STAmount& saTakerGets,
|
||||
const STAmount& saTakerFunds,
|
||||
STAmount& saTakerPaid,
|
||||
STAmount& saTakerGot);
|
||||
|
||||
protected:
|
||||
Ledger::pointer mDefaultLedger, mAlternateLedger;
|
||||
Ledger::pointer mLedger;
|
||||
uint64 mLedgerParentCloseTime;
|
||||
|
||||
TransactionEngineResult doAccountSet(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
TransactionEngineResult doClaim(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
TransactionEngineResult doCreditSet(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts,
|
||||
const uint160& uSrcAccountID);
|
||||
TransactionEngineResult doDelete(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
TransactionEngineResult doInvoice(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
TransactionEngineResult doOfferCreate(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts,
|
||||
const uint160& uSrcAccountID);
|
||||
TransactionEngineResult doOfferCancel(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts,
|
||||
const uint160& uSrcAccountID);
|
||||
TransactionEngineResult doNicknameSet(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts,
|
||||
const uint160& uSrcAccountID);
|
||||
TransactionEngineResult doPasswordFund(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts,
|
||||
const uint160& uSrcAccountID);
|
||||
TransactionEngineResult doPasswordSet(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
TransactionEngineResult doPayment(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts,
|
||||
const uint160& uSrcAccountID);
|
||||
TransactionEngineResult doStore(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
TransactionEngineResult doTake(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
TransactionEngineResult doWalletAdd(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
|
||||
entryMap mEntries;
|
||||
|
||||
SLE::pointer entryCreate(LedgerEntryType letType, const uint256& uIndex);
|
||||
void entryDelete(SLE::pointer sleEntry);
|
||||
void entryModify(SLE::pointer sleEntry);
|
||||
void entryUnfunded(SLE::pointer sleEntry);
|
||||
bool entryExists(SLE::pointer sleEntry);
|
||||
|
||||
STAmount rippleBalance(const uint160& uAccountID, const uint160& uIssuerAccountID, const uint160& uCurrency);
|
||||
|
||||
void rippleCredit(const uint160& uAccountID, const uint160& uIssuerAccountID, const uint160& uCurrency, const STAmount& saCredit);
|
||||
void rippleDebit(const uint160& uAccountID, const uint160& uIssuerAccountID, const uint160& uCurrency, const STAmount& saDebit);
|
||||
|
||||
TransactionEngineResult doAccountSet(const SerializedTransaction& txn, SLE::pointer sleSrc);
|
||||
TransactionEngineResult doClaim(const SerializedTransaction& txn, SLE::pointer sleSrc);
|
||||
TransactionEngineResult doCreditSet(const SerializedTransaction& txn, const uint160& uSrcAccountID);
|
||||
TransactionEngineResult doDelete(const SerializedTransaction& txn);
|
||||
TransactionEngineResult doInvoice(const SerializedTransaction& txn);
|
||||
TransactionEngineResult doOfferCreate(const SerializedTransaction& txn, SLE::pointer sleSrc, const uint160& uSrcAccountID);
|
||||
TransactionEngineResult doOfferCancel(const SerializedTransaction& txn, const uint160& uSrcAccountID);
|
||||
TransactionEngineResult doNicknameSet(const SerializedTransaction& txn, SLE::pointer sleSrc, const uint160& uSrcAccountID);
|
||||
TransactionEngineResult doPasswordFund(const SerializedTransaction& txn, SLE::pointer sleSrc, const uint160& uSrcAccountID);
|
||||
TransactionEngineResult doPasswordSet(const SerializedTransaction& txn, SLE::pointer sleSrc);
|
||||
TransactionEngineResult doPayment(const SerializedTransaction& txn, SLE::pointer sleSrc, const uint160& uSrcAccountID);
|
||||
TransactionEngineResult doStore(const SerializedTransaction& txn);
|
||||
TransactionEngineResult doTake(const SerializedTransaction& txn);
|
||||
TransactionEngineResult doWalletAdd(const SerializedTransaction& txn, SLE::pointer sleSrc);
|
||||
|
||||
public:
|
||||
TransactionEngine() { ; }
|
||||
|
||||
@@ -47,20 +47,21 @@ TransactionFormat InnerTxnFormats[]=
|
||||
},
|
||||
{ "NicknameSet", ttNICKNAME_SET, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Nickname), STI_HASH256, SOE_IFFLAG, 8 },
|
||||
{ S_FIELD(Nickname), STI_HASH256, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(MinimumOffer), STI_AMOUNT, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(Signature), STI_VL, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 4 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "OfferCreate", ttOFFER_CREATE, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(AmountIn), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(AmountOut), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ 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(Destination), STI_ACCOUNT, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(Expiration), STI_UINT32, SOE_IFFLAG, 4 },
|
||||
{ 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(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
|
||||
@@ -50,6 +50,8 @@ void printHelp(const po::options_description& desc)
|
||||
cout << " ledger [<id>|current|lastclosed] [full]" << endl;
|
||||
cout << " nickname_info <nickname>" << endl;
|
||||
cout << " nickname_set <seed> <paying_account> <nickname> [<offer_minimum>] [<authorization>]" << endl;
|
||||
cout << " offer_create <seed> <paying_account> <taker_pays_amount> <taker_pays_currency> <taker_pays_issuer> <takers_gets_amount> <takers_gets_currency> <takers_gets_issuer> <expires> [passive]" << endl;
|
||||
cout << " offer_cancel <seed> <paying_account> <sequence>" << endl;
|
||||
cout << " password_fund <seed> <paying_account> [<account>]" << endl;
|
||||
cout << " password_set <master_seed> <regular_seed> [<account>]" << endl;
|
||||
cout << " peers" << endl;
|
||||
|
||||
Reference in New Issue
Block a user