add account_offers and refactor

This commit is contained in:
jed
2012-12-04 12:12:11 -08:00
parent 4ef15c5536
commit 50953ff6d5
19 changed files with 257 additions and 138 deletions

View File

@@ -0,0 +1,57 @@
#include "AccountItems.h"
#include <boost/foreach.hpp>
#include "Application.h"
#include "Log.h"
SETUP_LOG();
AccountItem::AccountItem(SerializedLedgerEntry::pointer ledger) : mLedgerEntry(ledger)
{
}
AccountItems::AccountItems(uint160& accountID, Ledger::ref ledger, AccountItem::pointer ofType)
{
mOfType=ofType;
fillItems(accountID, ledger);
}
// looks in the current ledger
AccountItems::AccountItems(uint160& accountID, AccountItem::pointer ofType )
{
mOfType=ofType;
fillItems(accountID,theApp->getLedgerMaster().getClosedLedger());
}
void AccountItems::fillItems(uint160& accountID, Ledger::ref ledger)
{
uint256 rootIndex = Ledger::getOwnerDirIndex(accountID);
uint256 currentIndex = rootIndex;
LedgerStateParms lspNode = lepNONE;
while (1)
{
SLE::pointer ownerDir=ledger->getDirNode(lspNode, currentIndex);
if (!ownerDir) return;
STVector256 svOwnerNodes = ownerDir->getFieldV256(sfIndexes);
BOOST_FOREACH(uint256& uNode, svOwnerNodes.peekValue())
{
SLE::pointer sleCur = ledger->getSLE(uNode);
AccountItem::pointer item=mOfType->makeItem(accountID, sleCur);
if(item)
{
mItems.push_back(item);
}
}
uint64 uNodeNext = ownerDir->getFieldU64(sfIndexNext);
if (!uNodeNext) return;
currentIndex = Ledger::getDirNodeIndex(rootIndex, uNodeNext);
}
}

View File

@@ -0,0 +1,42 @@
#ifndef __ACCOUNT_ITEMS__
#define __ACCOUNT_ITEMS__
#include "Ledger.h"
#include "SerializedLedger.h"
/*
Way to fetch ledger entries from an account's owner dir
*/
class AccountItem
{
protected:
SerializedLedgerEntry::pointer mLedgerEntry;
public:
typedef boost::shared_ptr<AccountItem> pointer;
AccountItem(){ }
AccountItem(SerializedLedgerEntry::pointer ledger);
virtual AccountItem::pointer makeItem(uint160& accountID, SerializedLedgerEntry::pointer ledgerEntry)=0;
virtual LedgerEntryType getType()=0;
SerializedLedgerEntry::pointer getSLE() { return mLedgerEntry; }
const SerializedLedgerEntry& peekSLE() const { return *mLedgerEntry; }
SerializedLedgerEntry& peekSLE() { return *mLedgerEntry; }
std::vector<unsigned char> getRaw() const;
};
class AccountItems
{
AccountItem::pointer mOfType;
std::vector<AccountItem::pointer> mItems;
void fillItems(uint160& accountID, Ledger::ref ledger);
public:
AccountItems(uint160& accountID, Ledger::ref ledger, AccountItem::pointer ofType);
AccountItems(uint160& accountID, AccountItem::pointer ofType ); // looks in the current ledger
std::vector<AccountItem::pointer>& getItems() { return(mItems); }
};
#endif

View File

@@ -217,8 +217,9 @@ Json::Value RPCParser::parseOwnerInfo(const Json::Value& jvParams)
return parseAccountInfo(jvParams);
}
// ripple_lines_get <account>|<nickname>|<account_public_key> [<index>]
Json::Value RPCParser::parseRippleLinesGet(const Json::Value& jvParams)
// account_lines <account>|<nickname>|<account_public_key> [<index>]
// account_offers <account>|<nickname>|<account_public_key> [<index>]
Json::Value RPCParser::parseAccountItems(const Json::Value& jvParams)
{
std::string strIdent = jvParams[0u].asString();
bool bIndex = 2 == jvParams.size();
@@ -237,6 +238,7 @@ Json::Value RPCParser::parseRippleLinesGet(const Json::Value& jvParams)
return jvRequest;
}
// submit any transaction to the network
// submit private_key json
Json::Value RPCParser::parseSubmit(const Json::Value& jvParams)
@@ -407,7 +409,8 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams)
{ "owner_info", &RPCParser::parseOwnerInfo, 1, 2 },
{ "peers", &RPCParser::parseAsIs, 0, 0 },
// { "profile", &RPCParser::parseProfile, 1, 9 },
{ "ripple_lines_get", &RPCParser::parseRippleLinesGet, 1, 2 },
{ "account_lines", &RPCParser::parseAccountItems, 1, 2 },
{ "account_offers", &RPCParser::parseAccountItems, 1, 2 },
// { "ripple_path_find", &RPCParser::parseRipplePathFind, -1, -1 },
{ "submit", &RPCParser::parseSubmit, 2, 2 },
{ "server_info", &RPCParser::parseAsIs, 0, 0 },

View File

@@ -23,7 +23,7 @@ protected:
Json::Value parseLedger(const Json::Value& jvParams);
Json::Value parseLogin(const Json::Value& jvParams);
Json::Value parseOwnerInfo(const Json::Value& jvParams);
Json::Value parseRippleLinesGet(const Json::Value& jvParams);
Json::Value parseAccountItems(const Json::Value& jvParams);
Json::Value parseSubmit(const Json::Value& jvParams);
Json::Value parseTx(const Json::Value& jvParams);
Json::Value parseTxHistory(const Json::Value& jvParams);

View File

@@ -210,21 +210,6 @@ NicknameState::pointer Ledger::getNicknameState(const uint256& uNickname)
return boost::make_shared<NicknameState>(sle);
}
RippleState::pointer Ledger::accessRippleState(const uint256& uNode)
{
ScopedLock l(mAccountStateMap->Lock());
SHAMapItem::pointer item = mAccountStateMap->peekItem(uNode);
if (!item)
{
return RippleState::pointer();
}
SerializedLedgerEntry::pointer sle =
boost::make_shared<SerializedLedgerEntry>(item->peekSerializer(), item->getTag());
if (sle->getType() != ltRIPPLE_STATE) return RippleState::pointer();
return boost::make_shared<RippleState>(sle);
}
bool Ledger::addTransaction(const uint256& txID, const Serializer& txn)
{ // low-level - just add to table
SHAMapItem::pointer item = boost::make_shared<SHAMapItem>(txID, txn.peekData());

View File

@@ -13,7 +13,6 @@
#include "Transaction.h"
#include "TransactionMeta.h"
#include "AccountState.h"
#include "RippleState.h"
#include "NicknameState.h"
#include "types.h"
#include "BitcoinUtil.h"
@@ -291,8 +290,6 @@ public:
static uint256 getRippleStateIndex(const uint160& uiA, const uint160& uiB, const uint160& uCurrency)
{ return getRippleStateIndex(RippleAddress::createAccountID(uiA), RippleAddress::createAccountID(uiB), uCurrency); }
RippleState::pointer accessRippleState(const uint256& uNode);
SLE::pointer getRippleState(LedgerStateParms& parms, const uint256& uNode);
SLE::pointer getRippleState(const uint256& uNode)

15
src/cpp/ripple/Offer.cpp Normal file
View File

@@ -0,0 +1,15 @@
#include "Offer.h"
AccountItem::pointer Offer::makeItem(uint160& ,SerializedLedgerEntry::pointer ledgerEntry)
{
if (!mLedgerEntry || mLedgerEntry->getType() != ltOFFER) return(AccountItem::pointer());
Offer* offer=new Offer(ledgerEntry);
return(AccountItem::pointer(offer));
}
Offer::Offer(SerializedLedgerEntry::pointer ledgerEntry) : AccountItem(ledgerEntry)
{
mAccount=mLedgerEntry->getFieldAccount(sfAccount);
mTakerGets = mLedgerEntry->getFieldAmount(sfTakerGets);
mTakerPays = mLedgerEntry->getFieldAmount(sfTakerPays);
}

21
src/cpp/ripple/Offer.h Normal file
View File

@@ -0,0 +1,21 @@
#include "AccountItems.h"
class Offer : public AccountItem
{
RippleAddress mAccount;
STAmount mTakerGets;
STAmount mTakerPays;
Offer(SerializedLedgerEntry::pointer ledgerEntry); // For accounts in a ledger
public:
Offer(){}
AccountItem::pointer makeItem(uint160&, SerializedLedgerEntry::pointer ledgerEntry);
LedgerEntryType getType(){ return(ltOFFER); }
STAmount getTakerPays(){ return(mTakerPays); }
STAmount getTakerGets(){ return(mTakerGets); }
RippleAddress getAccount(){ return(mAccount); }
};

View File

@@ -1,6 +1,6 @@
#include "Pathfinder.h"
#include "Application.h"
#include "RippleLines.h"
#include "AccountItems.h"
#include "Log.h"
#include <boost/foreach.hpp>
@@ -221,10 +221,12 @@ bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet
// Last element is for non-XRP continue by adding ripple lines and order books.
// Create new paths for each outbound account not already in the path.
RippleLines rippleLines(ele.mAccountID);
AccountItems rippleLines(ele.mAccountID, AccountItem::pointer(new RippleState()));
BOOST_FOREACH(RippleState::pointer line, rippleLines.getLines())
BOOST_FOREACH(AccountItem::pointer item, rippleLines.getItems())
{
RippleState* line=(RippleState*)item.get();
if (!path.hasSeen(line->getAccountIDPeer().getAccountID()))
{
STPath new_path(path);

View File

@@ -6,7 +6,7 @@
#include "NetworkOPs.h"
#include "RPCHandler.h"
#include "Application.h"
#include "RippleLines.h"
#include "AccountItems.h"
#include "Wallet.h"
#include "RippleAddress.h"
#include "RippleCalc.h"
@@ -14,6 +14,7 @@
#include "AccountState.h"
#include "NicknameState.h"
#include "InstanceCounter.h"
#include "Offer.h"
#include "Pathfinder.h"
#include <boost/foreach.hpp>
@@ -566,7 +567,7 @@ Json::Value RPCHandler::doProfile(Json::Value params)
// account: <account>|<nickname>|<account_public_key> [<index>]
// index: <number> // optional, defaults to 0.
// }
Json::Value RPCHandler::doRippleLinesGet(Json::Value jvRequest)
Json::Value RPCHandler::doAccountLines(Json::Value jvRequest)
{
std::string strIdent = jvRequest["account"].asString();
bool bIndex = jvRequest.isMember("index");
@@ -597,17 +598,18 @@ Json::Value RPCHandler::doRippleLinesGet(Json::Value jvRequest)
// XXX This is wrong, we do access the current ledger and do need to worry about changes.
// We access a committed ledger and need not worry about changes.
RippleLines rippleLines(raAccount.getAccountID());
BOOST_FOREACH(RippleState::pointer line, rippleLines.getLines())
AccountItems rippleLines(raAccount.getAccountID(), AccountItem::pointer(new RippleState()));
BOOST_FOREACH(AccountItem::pointer item, rippleLines.getItems())
{
RippleState* line=(RippleState*)item.get();
STAmount saBalance = line->getBalance();
STAmount saLimit = line->getLimit();
STAmount saLimitPeer = line->getLimitPeer();
Json::Value jPeer = Json::Value(Json::objectValue);
//jPeer["node"] = uNode.ToString();
jPeer["account"] = line->getAccountIDPeer().humanAccountID();
// Amount reported is positive if current account holds other account's IOUs.
// Amount reported is negative if other account holds current account's IOUs.
@@ -630,6 +632,63 @@ Json::Value RPCHandler::doRippleLinesGet(Json::Value jvRequest)
return jvResult;
}
// {
// account: <account>|<nickname>|<account_public_key> [<index>]
// index: <number> // optional, defaults to 0.
// }
Json::Value RPCHandler::doAccountOffers(Json::Value jvRequest)
{
std::string strIdent = jvRequest["account"].asString();
bool bIndex = jvRequest.isMember("index");
int iIndex = bIndex ? jvRequest["index"].asUInt() : 0;
RippleAddress raAccount;
Json::Value jvResult;
jvResult = accountFromString(uint256(0), raAccount, bIndex, strIdent, iIndex);
if (!jvResult.empty())
return jvResult;
// Get info on account.
jvResult["account"] = raAccount.humanAccountID();
if (bIndex)
jvResult["index"] = iIndex;
AccountState::pointer as = mNetOps->getAccountState(uint256(0), raAccount);
if (as)
{
Json::Value jsonLines(Json::arrayValue);
AccountItems offers(raAccount.getAccountID(), AccountItem::pointer(new Offer()));
BOOST_FOREACH(AccountItem::pointer item, offers.getItems())
{
Offer* offer=(Offer*)item.get();
STAmount takerPays = offer->getTakerPays();
STAmount takerGets = offer->getTakerGets();
//RippleAddress account = offer->getAccount();
Json::Value obj = Json::Value(Json::objectValue);
//obj["account"] = account.humanAccountID();
obj["taker_pays"] = takerPays.getJson(0);
obj["taker_gets"] = takerGets.getJson(0);
jsonLines.append(obj);
}
jvResult["offers"] = jsonLines;
}
else
{
jvResult = rpcError(rpcACT_NOT_FOUND);
}
return jvResult;
}
// TODO:
// - Add support for specifying non-endpoint issuer.
// - Return fully expanded path with proof.
@@ -2218,7 +2277,8 @@ Json::Value RPCHandler::doCommand(Json::Value& jvRequest, int iRole)
{ "owner_info", &RPCHandler::doOwnerInfo, false, false, optCurrent },
{ "peers", &RPCHandler::doPeers, true, false, optNone },
// { "profile", &RPCHandler::doProfile, false, false, optCurrent },
{ "ripple_lines_get", &RPCHandler::doRippleLinesGet, false, false, optCurrent },
{ "account_lines", &RPCHandler::doAccountLines, false, false, optCurrent },
{ "account_offers", &RPCHandler::doAccountOffers, false, false, optCurrent },
{ "ripple_path_find", &RPCHandler::doRipplePathFind, false, false, optCurrent },
{ "submit", &RPCHandler::doSubmit, false, false, optCurrent },
{ "server_info", &RPCHandler::doServerInfo, true, false, optNone },

View File

@@ -53,7 +53,8 @@ class RPCHandler
Json::Value doProfile(Json::Value params);
Json::Value doPeers(Json::Value params);
Json::Value doRippleLinesGet(Json::Value params);
Json::Value doAccountLines(Json::Value params);
Json::Value doAccountOffers(Json::Value params);
Json::Value doRipplePathFind(Json::Value jvRequest);
Json::Value doServerInfo(Json::Value params);
Json::Value doSessionClose(Json::Value params);

View File

@@ -1,66 +0,0 @@
#include "RippleLines.h"
#include <boost/foreach.hpp>
#include "Application.h"
#include "Log.h"
SETUP_LOG();
RippleLines::RippleLines(const uint160& accountID, Ledger::ref ledger)
{
fillLines(accountID, ledger);
}
void RippleLines::printRippleLines()
{
for (unsigned int i =0; i < mLines.size(); i++) {
std::cerr << i << ": " << mLines[i]->getAccountID().humanAccountID() << std::endl;
}
std::cerr << std::endl;
}
RippleLines::RippleLines(const uint160& accountID )
{
fillLines(accountID,theApp->getLedgerMaster().getCurrentLedger());
}
void RippleLines::fillLines(const uint160& accountID, Ledger::ref ledger)
{
uint256 rootIndex = Ledger::getOwnerDirIndex(accountID);
uint256 currentIndex = rootIndex;
LedgerStateParms lspNode = lepNONE;
while (1)
{
SLE::pointer rippleDir=ledger->getDirNode(lspNode, currentIndex);
if (!rippleDir) return;
STVector256 svOwnerNodes = rippleDir->getFieldV256(sfIndexes);
BOOST_FOREACH(uint256& uNode, svOwnerNodes.peekValue())
{
SLE::pointer sleCur = ledger->getSLE(uNode);
if (ltRIPPLE_STATE == sleCur->getType())
{
RippleState::pointer rsLine = ledger->accessRippleState(uNode);
if (rsLine)
{
rsLine->setViewAccount(accountID);
mLines.push_back(rsLine);
}
else
{
cLog(lsWARNING) << "doRippleLinesGet: Bad index: " << uNode.ToString();
}
}
}
uint64 uNodeNext = rippleDir->getFieldU64(sfIndexNext);
if (!uNodeNext) return;
currentIndex = Ledger::getDirNodeIndex(rootIndex, uNodeNext);
}
}
// vim:ts=4

View File

@@ -1,20 +0,0 @@
#include "Ledger.h"
#include "RippleState.h"
/*
This pulls all the ripple lines of a given account out of the ledger.
It provides a vector so you to easily iterate through them
*/
class RippleLines
{
std::vector<RippleState::pointer> mLines;
void fillLines(const uint160& accountID, Ledger::ref ledger);
public:
RippleLines(const uint160& accountID, Ledger::ref ledger);
RippleLines(const uint160& accountID ); // looks in the current ledger
std::vector<RippleState::pointer>& getLines() { return(mLines); }
void printRippleLines();
};

View File

@@ -1,12 +1,19 @@
#include "RippleState.h"
RippleState::RippleState(SerializedLedgerEntry::pointer ledgerEntry) :
mLedgerEntry(ledgerEntry),
AccountItem::pointer RippleState::makeItem(uint160& accountID, SerializedLedgerEntry::pointer ledgerEntry)
{
if (!mLedgerEntry || mLedgerEntry->getType() != ltRIPPLE_STATE) return(AccountItem::pointer());
RippleState* rs=new RippleState(ledgerEntry);
rs->setViewAccount(accountID);
return(AccountItem::pointer(rs));
}
RippleState::RippleState(SerializedLedgerEntry::pointer ledgerEntry) : AccountItem(ledgerEntry),
mValid(false),
mViewLowest(true)
{
if (!mLedgerEntry || mLedgerEntry->getType() != ltRIPPLE_STATE) return;
mLowLimit = mLedgerEntry->getFieldAmount(sfLowLimit);
mHighLimit = mLedgerEntry->getFieldAmount(sfHighLimit);

View File

@@ -7,17 +7,16 @@
//
#include "SerializedLedger.h"
#include "AccountItems.h"
#include <boost/shared_ptr.hpp>
class RippleState
class RippleState : public AccountItem
{
public:
typedef boost::shared_ptr<RippleState> pointer;
private:
SerializedLedgerEntry::pointer mLedgerEntry;
RippleAddress mLowID;
RippleAddress mHighID;
@@ -34,8 +33,11 @@ private:
bool mValid;
bool mViewLowest;
public:
RippleState(SerializedLedgerEntry::pointer ledgerEntry); // For accounts in a ledger
public:
RippleState(){ }
AccountItem::pointer makeItem(uint160& accountID, SerializedLedgerEntry::pointer ledgerEntry);
LedgerEntryType getType(){ return(ltRIPPLE_STATE); }
void setViewAccount(const uint160& accountID);

View File

@@ -40,6 +40,8 @@ void printHelp(const po::options_description& desc)
cerr << "Commands: " << endl;
cerr << " account_domain_set <seed> <paying_account> [<domain>]" << endl;
cerr << " account_email_set <seed> <paying_account> [<email_address>]" << endl;
cerr << " account_lines <account>|<nickname>|<account_public_key> [<index>]" << endl;
cerr << " account_offers <account>|<nickname>|<account_public_key> [<index>]" << endl;
cerr << " account_info <account>|<nickname>" << endl;
cerr << " account_info <seed>|<pass_phrase>|<key> [<index>]" << endl;
cerr << " account_message_set <seed> <paying_account> <pub_key>" << endl;
@@ -60,7 +62,6 @@ void printHelp(const po::options_description& desc)
cerr << " password_set <master_seed> <regular_seed> [<account>]" << endl;
cerr << " peers" << endl;
cerr << " ripple ..." << endl;
cerr << " ripple_lines_get <account>|<nickname>|<account_public_key> [<index>]" << endl;
cerr << " ripple_line_set <seed> <paying_account> <destination_account> <limit_amount> <currency> [<quality_in>] [<quality_out>]" << endl;
cerr << " send <seed> <paying_account> <account_id> <amount> [<currency>] [<send_max>] [<send_currency>]" << endl;
cerr << " stop" << endl;