Merge branch 'master' of github.com:jedmccaleb/NewCoin into continuousClose

This commit is contained in:
JoelKatz
2012-07-13 23:55:27 -07:00
18 changed files with 1122 additions and 568 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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 } }
},

View File

@@ -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);

View File

@@ -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());
}

View File

@@ -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)

View File

@@ -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)
{

View File

@@ -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 &params)
// 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 &params)
{
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 &params)
{
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 },

View File

@@ -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);

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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
//

View File

@@ -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

View File

@@ -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() { ; }

View File

@@ -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 } }
},

View File

@@ -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;