mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
@@ -35,16 +35,15 @@ DatabaseCon::~DatabaseCon()
|
||||
Application::Application() :
|
||||
mUNL(mIOService),
|
||||
mNetOps(mIOService, &mMasterLedger), mNodeCache(16384, 600),
|
||||
mTxnDB(NULL), mAcctTxnDB(NULL), mLedgerDB(NULL), mWalletDB(NULL), mHashNodeDB(NULL), mNetNodeDB(NULL),
|
||||
mTxnDB(NULL), mLedgerDB(NULL), mWalletDB(NULL), mHashNodeDB(NULL), mNetNodeDB(NULL),
|
||||
mConnectionPool(mIOService), mPeerDoor(NULL), mRPCDoor(NULL)
|
||||
{
|
||||
RAND_bytes(mNonce256.begin(), mNonce256.size());
|
||||
RAND_bytes(reinterpret_cast<unsigned char *>(&mNonceST), sizeof(mNonceST));
|
||||
}
|
||||
|
||||
extern const char *AcctTxnDBInit[], *TxnDBInit[], *LedgerDBInit[], *WalletDBInit[],
|
||||
*HashNodeDBInit[], *NetNodeDBInit[];
|
||||
extern int TxnDBCount, AcctTxnDBCount, LedgerDBCount, WalletDBCount, HashNodeDBCount, NetNodeDBCount;
|
||||
extern const char *TxnDBInit[], *LedgerDBInit[], *WalletDBInit[], *HashNodeDBInit[], *NetNodeDBInit[];
|
||||
extern int TxnDBCount, LedgerDBCount, WalletDBCount, HashNodeDBCount, NetNodeDBCount;
|
||||
|
||||
void Application::stop()
|
||||
{
|
||||
@@ -61,7 +60,6 @@ void Application::run()
|
||||
// Construct databases.
|
||||
//
|
||||
mTxnDB = new DatabaseCon("transaction.db", TxnDBInit, TxnDBCount);
|
||||
mAcctTxnDB = new DatabaseCon("transacct.db", AcctTxnDBInit, AcctTxnDBCount);
|
||||
mLedgerDB = new DatabaseCon("ledger.db", LedgerDBInit, LedgerDBCount);
|
||||
mWalletDB = new DatabaseCon("wallet.db", WalletDBInit, WalletDBCount);
|
||||
mHashNodeDB = new DatabaseCon("hashnode.db", HashNodeDBInit, HashNodeDBCount);
|
||||
@@ -140,7 +138,6 @@ void Application::run()
|
||||
Application::~Application()
|
||||
{
|
||||
delete mTxnDB;
|
||||
delete mAcctTxnDB;
|
||||
delete mLedgerDB;
|
||||
delete mWalletDB;
|
||||
delete mHashNodeDB;
|
||||
|
||||
@@ -45,7 +45,7 @@ class Application
|
||||
NetworkOPs mNetOps;
|
||||
NodeCache mNodeCache;
|
||||
|
||||
DatabaseCon *mTxnDB, *mAcctTxnDB, *mLedgerDB, *mWalletDB, *mHashNodeDB, *mNetNodeDB;
|
||||
DatabaseCon *mTxnDB, *mLedgerDB, *mWalletDB, *mHashNodeDB, *mNetNodeDB;
|
||||
|
||||
ConnectionPool mConnectionPool;
|
||||
PeerDoor* mPeerDoor;
|
||||
@@ -76,7 +76,6 @@ public:
|
||||
NodeCache& getNodeCache() { return mNodeCache; }
|
||||
|
||||
DatabaseCon* getTxnDB() { return mTxnDB; }
|
||||
DatabaseCon* getAcctTxnDB() { return mAcctTxnDB; }
|
||||
DatabaseCon* getLedgerDB() { return mLedgerDB; }
|
||||
DatabaseCon* getWalletDB() { return mWalletDB; }
|
||||
DatabaseCon* getHashNodeDB() { return mHashNodeDB; }
|
||||
|
||||
@@ -7,35 +7,25 @@ const char *TxnDBInit[] = {
|
||||
TransType CHARACTER(24) \
|
||||
FromAcct CHARACTER(35), \
|
||||
FromSeq BIGINT UNSIGNED, \
|
||||
OtherAcct CHARACTER(40), \
|
||||
Amount BIGINT UNSIGNED, \
|
||||
FirstSeen TEXT, \
|
||||
CommitSeq BIGINT UNSIGNED, \
|
||||
LedgerSeq BIGINT UNSIGNED, \
|
||||
Status CHARACTER(1), \
|
||||
RawTxn BLOB \
|
||||
);",
|
||||
"CREATE TABLE PubKeys ( \
|
||||
ID CHARACTER(35) PRIMARY KEY, \
|
||||
PubKey BLOB \
|
||||
);"
|
||||
);",
|
||||
"CREATE TABLE AccountTransactions ( \
|
||||
TransID CHARACTER(64), \
|
||||
Account CHARACTER(64), \
|
||||
LedgerSeq BIGINT UNSIGNED \
|
||||
);",
|
||||
"CREATE INDEX AcctTxindex ON \
|
||||
AccountTransactions(Account, LedgerSeq, TransID);"
|
||||
};
|
||||
|
||||
int TxnDBCount = sizeof(TxnDBInit) / sizeof(const char *);
|
||||
|
||||
const char *AcctTxnDBInit[] = {
|
||||
"CREATE TABLE AccountTransactions ( \
|
||||
TransID CHARACTER964) PRIMARY KEY \
|
||||
Account CHARACTER(64), \
|
||||
LedgerSeq BIGINT UNSIGNED, \
|
||||
);",
|
||||
"CREATE INDEX AcctTxindex ON \
|
||||
AccountTransactions(Account), \
|
||||
AccountTransactions(LedgerSeq), \
|
||||
AccountTransactions(TransID);"
|
||||
};
|
||||
|
||||
int AcctTxnDBCount = sizeof(AcctTxnDBInit) / sizeof(const char *);
|
||||
|
||||
// Ledger database holds ledgers and ledger confirmations
|
||||
const char *LedgerDBInit[] = {
|
||||
"CREATE TABLE Ledgers ( \
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "Wallet.h"
|
||||
#include "BinaryFormats.h"
|
||||
#include "LedgerTiming.h"
|
||||
#include "Log.h"
|
||||
|
||||
Ledger::Ledger(const NewcoinAddress& masterID, uint64 startAmount) : mTotCoins(startAmount),
|
||||
mCloseTime(0), mLedgerSeq(0), mLedgerInterval(LEDGER_INTERVAL), mClosed(false), mValidHash(false),
|
||||
@@ -261,6 +262,41 @@ void Ledger::saveAcceptedLedger(Ledger::pointer ledger)
|
||||
while(ledger->mAccountStateMap->flushDirty(64, ACCOUNT_NODE, ledger->mLedgerSeq))
|
||||
{ ; }
|
||||
|
||||
SHAMap& txSet = *ledger->peekTransactionMap();
|
||||
Database *db = theApp->getTxnDB()->getDB();
|
||||
ScopedLock dbLock = theApp->getTxnDB()->getDBLock();
|
||||
db->executeSQL("BEGIN TRANSACTION;");
|
||||
for (SHAMapItem::pointer item = txSet.peekFirstItem(); !!item; item = txSet.peekNextItem(item->getTag()))
|
||||
{
|
||||
SerializerIterator sit(item->peekSerializer());
|
||||
SerializedTransaction txn(sit);
|
||||
std::vector<NewcoinAddress> accts = txn.getAffectedAccounts();
|
||||
|
||||
std::string sql = "INSERT INTO AccountTransactions (TransID, Account, LedgerSeq) VALUES ";
|
||||
bool first = true;
|
||||
for (std::vector<NewcoinAddress>::iterator it = accts.begin(), end = accts.end(); it != end; ++it)
|
||||
{
|
||||
if (!first)
|
||||
sql += ", ('";
|
||||
else
|
||||
{
|
||||
sql += "('";
|
||||
first = false;
|
||||
}
|
||||
sql += txn.getTransactionID().GetHex();
|
||||
sql += "','";
|
||||
sql += it->humanAccountID();
|
||||
sql += "',";
|
||||
sql += boost::lexical_cast<std::string>(ledger->getLedgerSeq());
|
||||
sql += ")";
|
||||
}
|
||||
sql += ";";
|
||||
Log(lsTRACE) << "ActTx: " << sql;
|
||||
db->executeSQL(sql);
|
||||
db->executeSQL(txn.getSQLInsertHeader() + txn.getSQL(ledger->getLedgerSeq(), TXN_SQL_VALIDATED) + ";");
|
||||
// FIXME: If above updates no rows, modify seq/status
|
||||
}
|
||||
db->executeSQL("COMMIT TRANSACTION;");
|
||||
}
|
||||
|
||||
Ledger::pointer Ledger::getSQL(const std::string& sql)
|
||||
@@ -365,7 +401,8 @@ void Ledger::addJson(Json::Value& ret, int options)
|
||||
SerializedLedgerEntry sle(sit, item->getTag());
|
||||
state.append(sle.getJson(0));
|
||||
}
|
||||
else state.append(item->getTag().GetHex());
|
||||
else
|
||||
state.append(item->getTag().GetHex());
|
||||
}
|
||||
ledger["AccountState"] = state;
|
||||
}
|
||||
|
||||
@@ -654,7 +654,6 @@ void LedgerConsensus::accept(SHAMap::pointer set)
|
||||
Log(lsDEBUG) << "Previous LCL " << mPreviousLedger->getHash().GetHex();
|
||||
|
||||
Ledger::pointer newLCL = boost::make_shared<Ledger>(false, boost::ref(*mPreviousLedger));
|
||||
uint32 newLedgerSeq = newLCL->getLedgerSeq();
|
||||
|
||||
#ifdef DEBUG
|
||||
Json::StyledStreamWriter ssw;
|
||||
@@ -727,34 +726,6 @@ void LedgerConsensus::accept(SHAMap::pointer set)
|
||||
theApp->getConnectionPool().relayMessage(NULL, boost::make_shared<PackedMessage>(val, newcoin::mtVALIDATION));
|
||||
Log(lsINFO) << "Validation sent " << newLCL->getHash().GetHex();
|
||||
statusChange(newcoin::neACCEPTED_LEDGER, newOL);
|
||||
|
||||
// Insert the transactions in set into the AcctTxn database
|
||||
Database *db = theApp->getAcctTxnDB()->getDB();
|
||||
ScopedLock dbLock = theApp->getAcctTxnDB()->getDBLock();
|
||||
db->executeSQL("BEGIN TRANSACTION");
|
||||
for (SHAMapItem::pointer item = set->peekFirstItem(); !!item; item = set->peekNextItem(item->getTag()))
|
||||
{
|
||||
SerializerIterator sit(item->peekSerializer());
|
||||
SerializedTransaction txn(sit);
|
||||
std::vector<NewcoinAddress> accts = txn.getAffectedAccounts();
|
||||
|
||||
std::string sql = "INSERT INTO AccountTransactions (TransID,Account,LedgerSeq) VALUES ";
|
||||
bool first = true;
|
||||
for (std::vector<NewcoinAddress>::iterator it = accts.begin(), end = accts.end(); it != end; ++it)
|
||||
{
|
||||
if (!first) sql += ", (";
|
||||
else sql += "(";
|
||||
sql += txn.getTransactionID().GetHex();
|
||||
sql += ",";
|
||||
sql += it->humanAccountID();
|
||||
sql += ",";
|
||||
sql += boost::lexical_cast<std::string>(newLedgerSeq);
|
||||
sql += ")";
|
||||
}
|
||||
sql += ";";
|
||||
db->executeSQL(sql);
|
||||
}
|
||||
db->executeSQL("COMMIT TRANSACTION");
|
||||
}
|
||||
|
||||
void LedgerConsensus::endConsensus()
|
||||
|
||||
@@ -18,16 +18,16 @@ enum LedgerEntryType
|
||||
// Used as a prefix for computing ledger indexes (keys).
|
||||
enum LedgerNameSpace
|
||||
{
|
||||
spaceAccount,
|
||||
spaceGenerator,
|
||||
spaceNickname,
|
||||
spaceRipple,
|
||||
spaceRippleDir,
|
||||
spaceOffer,
|
||||
spaceOfferDir,
|
||||
spaceBond,
|
||||
spaceInvoice,
|
||||
spaceMultiSig,
|
||||
spaceAccount = 0,
|
||||
spaceGenerator = 1,
|
||||
spaceNickname = 2,
|
||||
spaceRipple = 3,
|
||||
spaceRippleDir = 4,
|
||||
spaceOffer = 5,
|
||||
spaceOfferDir = 6,
|
||||
spaceBond = 7,
|
||||
spaceInvoice = 8,
|
||||
spaceMultiSig = 9,
|
||||
};
|
||||
|
||||
enum LedgerSpecificFlags
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <string>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
#include "LedgerHistory.h"
|
||||
#include "Config.h"
|
||||
@@ -32,7 +33,8 @@ void LedgerHistory::addAcceptedLedger(Ledger::pointer ledger)
|
||||
boost::recursive_mutex::scoped_lock sl(mLedgersByHash.peekMutex());
|
||||
mLedgersByHash.canonicalize(h, ledger);
|
||||
mLedgersByIndex.insert(std::make_pair(ledger->getLedgerSeq(), ledger));
|
||||
theApp->getIOService().post(boost::bind(&Ledger::saveAcceptedLedger, ledger));
|
||||
boost::thread thread(boost::bind(&Ledger::saveAcceptedLedger, ledger));
|
||||
thread.detach();
|
||||
}
|
||||
|
||||
Ledger::pointer LedgerHistory::getLedgerBySeq(uint32 index)
|
||||
|
||||
@@ -528,4 +528,31 @@ void NetworkOPs::setMode(OperatingMode om)
|
||||
mMode = om;
|
||||
}
|
||||
|
||||
#define SQL_FOREACH(_db, _strQuery) \
|
||||
if ((_db)->executeSQL(_strQuery)) \
|
||||
for (bool _bMore = (db)->startIterRows(); _bMore; _bMore = (_db)->getNextRow())
|
||||
|
||||
std::vector< std::pair<uint32, uint256> >
|
||||
NetworkOPs::getAffectedAccounts(const NewcoinAddress& account, uint32 minLedger, uint32 maxLedger)
|
||||
{
|
||||
std::vector< std::pair<uint32, uint256> > affectedAccounts;
|
||||
|
||||
std::string sql =
|
||||
str(boost::format("SELECT LedgerSeq,TransID FROM AccountTransactions INDEXED BY AcctTxIndex "
|
||||
" WHERE Account = '%s' AND LedgerSeq <= '%d' AND LedgerSeq >= '%d' ORDER BY LedgerSeq LIMIT 1000")
|
||||
% account.humanAccountID() % maxLedger % minLedger);
|
||||
|
||||
Database *db = theApp->getTxnDB()->getDB();
|
||||
ScopedLock dbLock = theApp->getTxnDB()->getDBLock();
|
||||
|
||||
SQL_FOREACH(db, sql)
|
||||
{
|
||||
std::string txID;
|
||||
db->getStr("TransID", txID);
|
||||
affectedAccounts.push_back(std::make_pair<uint32, uint256>(db->getInt("LedgerSeq"), uint256(txID)));
|
||||
}
|
||||
|
||||
return affectedAccounts;
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -125,6 +125,10 @@ public:
|
||||
int beginConsensus(Ledger::pointer closingLedger);
|
||||
void endConsensus();
|
||||
void setStateTimer(int seconds);
|
||||
|
||||
// client information retrieval functions
|
||||
std::vector< std::pair<uint32, uint256> >
|
||||
getAffectedAccounts(const NewcoinAddress& account, uint32 minLedger, uint32 maxLedger);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
1043
src/RPCServer.cpp
1043
src/RPCServer.cpp
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,65 @@
|
||||
|
||||
class RPCServer : public boost::enable_shared_from_this<RPCServer>
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
rpcSUCCESS,
|
||||
|
||||
// Networking
|
||||
rpcNO_CLOSED,
|
||||
rpcNO_CURRENT,
|
||||
rpcNO_NETWORK,
|
||||
|
||||
// Ledger state
|
||||
rpcACT_EXISTS,
|
||||
rpcACT_NOT_FOUND,
|
||||
rpcINSUF_FUNDS,
|
||||
rpcLGR_NOT_FOUND,
|
||||
rpcMUST_SEND_XNS,
|
||||
rpcNICKNAME_MISSING,
|
||||
rpcPASSWD_CHANGED,
|
||||
rpcSRC_MISSING,
|
||||
rpcSRC_UNCLAIMED,
|
||||
rpcTXN_NOT_FOUND,
|
||||
rpcWRONG_PASSWORD,
|
||||
rpcWRONG_SEED,
|
||||
|
||||
// Malformed command
|
||||
rpcINVALID_PARAMS,
|
||||
rpcUNKNOWN_COMMAND,
|
||||
|
||||
// Bad paramater
|
||||
rpcACT_MALFORMED,
|
||||
rpcBAD_SEED,
|
||||
rpcDST_ACT_MALFORMED,
|
||||
rpcDST_AMT_MALFORMED,
|
||||
rpcHOST_IP_MALFORMED,
|
||||
rpcLGR_IDXS_INVALID,
|
||||
rpcLGR_IDX_MALFORMED,
|
||||
rpcNICKNAME_MALFORMED,
|
||||
rpcNICKNAME_PERM,
|
||||
rpcPORT_MALFORMED,
|
||||
rpcPUBLIC_MALFORMED,
|
||||
rpcSRC_ACT_MALFORMED,
|
||||
rpcSRC_AMT_MALFORMED,
|
||||
|
||||
// Internal error (should never happen)
|
||||
rpcINTERNAL, // Generic internal error.
|
||||
rpcFAIL_GEN_DECRPYT,
|
||||
rpcNOT_IMPL,
|
||||
rpcNO_GEN_DECRPYT,
|
||||
};
|
||||
|
||||
Json::Value RPCError(int iError);
|
||||
|
||||
private:
|
||||
typedef Json::Value (RPCServer::*doFuncPtr)(Json::Value ¶ms);
|
||||
enum {
|
||||
optNetwork = 1, // Need network
|
||||
optCurrent = 2+optNetwork, // Need current ledger
|
||||
optClosed = 4+optNetwork, // Need closed ledger
|
||||
};
|
||||
|
||||
NetworkOPs* mNetOps;
|
||||
|
||||
boost::asio::ip::tcp::socket mSocket;
|
||||
@@ -52,6 +110,7 @@ private:
|
||||
Json::Value doAccountInfo(Json::Value& params);
|
||||
Json::Value doAccountLines(Json::Value ¶ms);
|
||||
Json::Value doAccountMessageSet(Json::Value ¶ms);
|
||||
Json::Value doAccountTransactions(Json::Value& params);
|
||||
Json::Value doAccountWalletSet(Json::Value ¶ms);
|
||||
Json::Value doConnect(Json::Value& params);
|
||||
Json::Value doCreditSet(Json::Value& params);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
#include "SerializedTransaction.h"
|
||||
#include "Application.h"
|
||||
|
||||
#include "Log.h"
|
||||
|
||||
@@ -85,8 +86,22 @@ std::vector<NewcoinAddress> SerializedTransaction::getAffectedAccounts() const
|
||||
end = mInnerTxn.peekData().end(); it != end ; ++it)
|
||||
{
|
||||
const STAccount* sa = dynamic_cast<const STAccount*>(&*it);
|
||||
if (sa != NULL) // FIXME: Should we check for duplicates?
|
||||
accounts.push_back(sa->getValueNCA());
|
||||
if (sa != NULL)
|
||||
{
|
||||
bool found = false;
|
||||
NewcoinAddress na = sa->getValueNCA();
|
||||
for (std::vector<NewcoinAddress>::iterator it = accounts.begin(), end = accounts.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
if (*it == na)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
accounts.push_back(na);
|
||||
}
|
||||
}
|
||||
return accounts;
|
||||
}
|
||||
@@ -283,4 +298,33 @@ Json::Value SerializedTransaction::getJson(int options) const
|
||||
ret["Inner"] = mInnerTxn.getJson(options);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string SerializedTransaction::getSQLValueHeader()
|
||||
{
|
||||
return "(TransID, TransType, FromAcct, FromSeq, CommitSeq, Status, RawTxn)";
|
||||
}
|
||||
|
||||
std::string SerializedTransaction::getSQLInsertHeader()
|
||||
{
|
||||
return "INSERT INTO Transactions " + getSQLValueHeader() + " VALUES ";
|
||||
}
|
||||
|
||||
std::string SerializedTransaction::getSQL(uint32 inLedger, char status) const
|
||||
{
|
||||
Serializer s;
|
||||
add(s);
|
||||
return getSQL(s, inLedger, status);
|
||||
}
|
||||
|
||||
std::string SerializedTransaction::getSQL(Serializer rawTxn, uint32 inLedger, char status) const
|
||||
{
|
||||
std::string rTxn;
|
||||
theApp->getTxnDB()->getDB()->escape(
|
||||
reinterpret_cast<const unsigned char *>(rawTxn.getDataPtr()), rawTxn.getLength(), rTxn);
|
||||
return str(boost::format("('%s', '%s', '%s', %d, %d, %c, '%s')")
|
||||
% getTransactionID().GetHex() % getTransactionType() % getSourceAccount().humanAccountID()
|
||||
% getSequence() % inLedger % status % rTxn);
|
||||
}
|
||||
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
#include "TransactionFormats.h"
|
||||
#include "NewcoinAddress.h"
|
||||
|
||||
#define TXN_SQL_NEW 'N'
|
||||
#define TXN_SQL_CONFLICT 'C'
|
||||
#define TXN_SQL_HELD 'H'
|
||||
#define TXN_SQL_VALIDATED 'V'
|
||||
|
||||
class SerializedTransaction : public SerializedType
|
||||
{
|
||||
public:
|
||||
@@ -116,6 +121,14 @@ public:
|
||||
|
||||
bool sign(const NewcoinAddress& naAccountPrivate);
|
||||
bool checkSign(const NewcoinAddress& naAccountPublic) const;
|
||||
|
||||
// SQL Functions
|
||||
static std::string getSQLValueHeader();
|
||||
static std::string getSQLInsertHeader();
|
||||
std::string getSQL(std::string& sql, uint32 inLedger, char status) const;
|
||||
std::string getSQL(uint32 inLedger, char status) const;
|
||||
std::string getSQL(Serializer rawTxn, uint32 inLedger, char status) const;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -510,6 +510,7 @@ void Transaction::saveTransaction(Transaction::pointer txn)
|
||||
|
||||
bool Transaction::save() const
|
||||
{ // This code needs to be fixed to support new-style transactions - FIXME
|
||||
// This code is going away. It will be handled from SerializedTransaction
|
||||
#if 0
|
||||
// Identify minimums fields to write for now.
|
||||
// Also maybe write effected accounts for use later.
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
#include "types.h"
|
||||
|
||||
#define nothing() do {} while (0)
|
||||
#define fallthru() do {} while (0)
|
||||
#define fallthru() do {} while (0)
|
||||
#define NUMBER(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(x,y) ((x) < (y) ? (y) : (x))
|
||||
|
||||
Reference in New Issue
Block a user