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

This commit is contained in:
Arthur Britto
2012-11-28 19:19:57 -08:00
19 changed files with 81 additions and 48 deletions

View File

@@ -35,7 +35,7 @@ public:
DatabaseCon(const std::string& name, const char *initString[], int countInit); DatabaseCon(const std::string& name, const char *initString[], int countInit);
~DatabaseCon(); ~DatabaseCon();
Database* getDB() { return mDatabase; } Database* getDB() { return mDatabase; }
ScopedLock getDBLock() { return ScopedLock(mLock); } boost::recursive_mutex& getDBLock() { return mLock; }
}; };
class Application class Application

View File

@@ -12,7 +12,7 @@ SETUP_LOG();
DECLARE_INSTANCE(HashedObject); DECLARE_INSTANCE(HashedObject);
HashedObjectStore::HashedObjectStore(int cacheSize, int cacheAge) : HashedObjectStore::HashedObjectStore(int cacheSize, int cacheAge) :
mCache("HashedObjectStore", cacheSize, cacheAge), mWritePending(false) mCache("HashedObjectStore", cacheSize, cacheAge), mWritePending(false), mWriteGeneration(0)
{ {
mWriteSet.reserve(128); mWriteSet.reserve(128);
} }
@@ -53,27 +53,29 @@ bool HashedObjectStore::store(HashedObjectType type, uint32 index,
void HashedObjectStore::waitWrite() void HashedObjectStore::waitWrite()
{ {
boost::unique_lock<boost::mutex> sl(mWriteMutex); boost::mutex::scoped_lock sl(mWriteMutex);
while (mWritePending) int gen = mWriteGeneration;
while (mWritePending && (mWriteGeneration == gen))
mWriteCondition.wait(sl); mWriteCondition.wait(sl);
} }
void HashedObjectStore::bulkWrite() void HashedObjectStore::bulkWrite()
{ {
LoadEvent::pointer event = theApp->getJobQueue().getLoadEvent(jtDISK); LoadEvent::autoptr event(theApp->getJobQueue().getLoadEventAP(jtDISK));
while (1) while (1)
{ {
std::vector< boost::shared_ptr<HashedObject> > set; std::vector< boost::shared_ptr<HashedObject> > set;
set.reserve(128); set.reserve(128);
{ {
boost::unique_lock<boost::mutex> sl(mWriteMutex); boost::mutex::scoped_lock sl(mWriteMutex);
mWriteSet.swap(set); mWriteSet.swap(set);
assert(mWriteSet.empty()); assert(mWriteSet.empty());
++mWriteGeneration;
mWriteCondition.notify_all();
if (set.empty()) if (set.empty())
{ {
mWritePending = false; mWritePending = false;
mWriteCondition.notify_all();
return; return;
} }
} }
@@ -85,7 +87,7 @@ void HashedObjectStore::bulkWrite()
Database* db = theApp->getHashNodeDB()->getDB(); Database* db = theApp->getHashNodeDB()->getDB();
{ {
ScopedLock sl = theApp->getHashNodeDB()->getDBLock(); ScopedLock sl( theApp->getHashNodeDB()->getDBLock());
db->executeSQL("BEGIN TRANSACTION;"); db->executeSQL("BEGIN TRANSACTION;");

View File

@@ -49,6 +49,7 @@ protected:
boost::mutex mWriteMutex; boost::mutex mWriteMutex;
boost::condition_variable mWriteCondition; boost::condition_variable mWriteCondition;
int mWriteGeneration;
std::vector< boost::shared_ptr<HashedObject> > mWriteSet; std::vector< boost::shared_ptr<HashedObject> > mWriteSet;
bool mWritePending; bool mWritePending;

View File

@@ -104,6 +104,8 @@ public:
LoadEvent::pointer getLoadEvent(JobType t) LoadEvent::pointer getLoadEvent(JobType t)
{ return boost::make_shared<LoadEvent>(boost::ref(mJobLoads[t]), true, 1); } { return boost::make_shared<LoadEvent>(boost::ref(mJobLoads[t]), true, 1); }
LoadEvent::autoptr getLoadEventAP(JobType t)
{ return LoadEvent::autoptr(new LoadEvent(mJobLoads[t], true, 1)); }
Json::Value getJson(int c = 0); Json::Value getJson(int c = 0);
}; };

View File

@@ -339,9 +339,8 @@ uint256 Ledger::getHash()
return mHash; return mHash;
} }
void Ledger::saveAcceptedLedger(bool fromConsensus) void Ledger::saveAcceptedLedger(bool fromConsensus, LoadEvent::pointer event)
{ // can be called in a different thread { // can be called in a different thread
LoadEvent::pointer event = theApp->getJobQueue().getLoadEvent(jtDISK);
cLog(lsTRACE) << "saveAcceptedLedger " << (fromConsensus ? "fromConsensus " : "fromAcquire ") << getLedgerSeq(); cLog(lsTRACE) << "saveAcceptedLedger " << (fromConsensus ? "fromConsensus " : "fromAcquire ") << getLedgerSeq();
static boost::format ledgerExists("SELECT LedgerSeq FROM Ledgers where LedgerSeq = %d;"); static boost::format ledgerExists("SELECT LedgerSeq FROM Ledgers where LedgerSeq = %d;");
static boost::format deleteLedger("DELETE FROM Ledgers WHERE LedgerSeq = %d;"); static boost::format deleteLedger("DELETE FROM Ledgers WHERE LedgerSeq = %d;");
@@ -369,7 +368,7 @@ void Ledger::saveAcceptedLedger(bool fromConsensus)
SHAMap& txSet = *peekTransactionMap(); SHAMap& txSet = *peekTransactionMap();
Database *db = theApp->getTxnDB()->getDB(); Database *db = theApp->getTxnDB()->getDB();
ScopedLock dbLock = theApp->getTxnDB()->getDBLock(); ScopedLock dbLock(theApp->getTxnDB()->getDBLock());
db->executeSQL("BEGIN TRANSACTION;"); db->executeSQL("BEGIN TRANSACTION;");
SHAMapTreeNode::TNType type; SHAMapTreeNode::TNType type;
for (SHAMapItem::pointer item = txSet.peekFirstItem(type); !!item; for (SHAMapItem::pointer item = txSet.peekFirstItem(type); !!item;
@@ -439,7 +438,7 @@ void Ledger::saveAcceptedLedger(bool fromConsensus)
} }
theApp->getLedgerMaster().setFullLedger(shared_from_this()); theApp->getLedgerMaster().setFullLedger(shared_from_this());
event = LoadEvent::pointer(); event->stop();
theApp->getOPs().pubLedger(shared_from_this()); theApp->getOPs().pubLedger(shared_from_this());
@@ -1136,7 +1135,8 @@ void Ledger::pendSave(bool fromConsensus)
if (!fromConsensus && !theApp->isNewFlag(getHash(), SF_SAVED)) if (!fromConsensus && !theApp->isNewFlag(getHash(), SF_SAVED))
return; return;
boost::thread thread(boost::bind(&Ledger::saveAcceptedLedger, shared_from_this(), fromConsensus)); boost::thread thread(boost::bind(&Ledger::saveAcceptedLedger, shared_from_this(),
fromConsensus, theApp->getJobQueue().getLoadEvent(jtDISK)));
thread.detach(); thread.detach();
boost::recursive_mutex::scoped_lock sl(sPendingSaveLock); boost::recursive_mutex::scoped_lock sl(sPendingSaveLock);

View File

@@ -19,6 +19,7 @@
#include "BitcoinUtil.h" #include "BitcoinUtil.h"
#include "SHAMap.h" #include "SHAMap.h"
#include "InstanceCounter.h" #include "InstanceCounter.h"
#include "LoadMonitor.h"
enum LedgerStateParms enum LedgerStateParms
{ {
@@ -93,7 +94,7 @@ protected:
static void incPendingSaves(); static void incPendingSaves();
static void decPendingSaves(); static void decPendingSaves();
void saveAcceptedLedger(bool fromConsensus); void saveAcceptedLedger(bool fromConsensus, LoadEvent::pointer);
public: public:
Ledger(const RippleAddress& masterID, uint64 startAmount); // used for the starting bootstrap ledger Ledger(const RippleAddress& masterID, uint64 startAmount); // used for the starting bootstrap ledger

View File

@@ -1251,7 +1251,7 @@ void LedgerConsensus::accept(SHAMap::ref set, LoadEvent::pointer)
cLog(lsINFO) << "CNF newLCL " << newLCLHash; cLog(lsINFO) << "CNF newLCL " << newLCLHash;
Ledger::pointer newOL = boost::make_shared<Ledger>(true, boost::ref(*newLCL)); Ledger::pointer newOL = boost::make_shared<Ledger>(true, boost::ref(*newLCL));
ScopedLock sl = theApp->getLedgerMaster().getLock(); ScopedLock sl( theApp->getLedgerMaster().getLock());
// Apply disputed transactions that didn't get in // Apply disputed transactions that didn't get in
TransactionEngine engine(newOL); TransactionEngine engine(newOL);

View File

@@ -37,6 +37,7 @@ class LoadEvent
{ {
public: public:
typedef boost::shared_ptr<LoadEvent> pointer; typedef boost::shared_ptr<LoadEvent> pointer;
typedef std::auto_ptr<LoadEvent> autoptr;
protected: protected:
LoadMonitor& mMonitor; LoadMonitor& mMonitor;

View File

@@ -888,7 +888,7 @@ std::vector< std::pair<uint32, uint256> >
{ {
Database* db = theApp->getTxnDB()->getDB(); Database* db = theApp->getTxnDB()->getDB();
ScopedLock dbLock = theApp->getTxnDB()->getDBLock(); ScopedLock sl(theApp->getTxnDB()->getDBLock());
SQL_FOREACH(db, sql) SQL_FOREACH(db, sql)
{ {
@@ -909,7 +909,7 @@ std::vector<RippleAddress>
RippleAddress acct; RippleAddress acct;
{ {
Database* db = theApp->getTxnDB()->getDB(); Database* db = theApp->getTxnDB()->getDB();
ScopedLock dblock = theApp->getTxnDB()->getDBLock(); ScopedLock sl(theApp->getTxnDB()->getDBLock());
SQL_FOREACH(db, sql) SQL_FOREACH(db, sql)
{ {
if (acct.setAccountID(db->getStrBinary("Account"))) if (acct.setAccountID(db->getStrBinary("Account")))
@@ -1002,7 +1002,7 @@ void NetworkOPs::pubLedger(Ledger::ref lpAccepted)
if (NetworkOPs::omDISCONNECTED == getOperatingMode()) if (NetworkOPs::omDISCONNECTED == getOperatingMode())
return; return;
LoadEvent::pointer event = theApp->getJobQueue().getLoadEvent(jtPUBLEDGER); LoadEvent::autoptr event(theApp->getJobQueue().getLoadEventAP(jtPUBLEDGER));
{ {
boost::recursive_mutex::scoped_lock sl(mMonitorLock); boost::recursive_mutex::scoped_lock sl(mMonitorLock);

View File

@@ -373,7 +373,7 @@ void Peer::processReadBuffer()
// std::cerr << "Peer::processReadBuffer: " << mIpPort.first << " " << mIpPort.second << std::endl; // std::cerr << "Peer::processReadBuffer: " << mIpPort.first << " " << mIpPort.second << std::endl;
LoadEvent::pointer event = theApp->getJobQueue().getLoadEvent(jtPEER); LoadEvent::autoptr event(theApp->getJobQueue().getLoadEventAP(jtPEER));
boost::recursive_mutex::scoped_lock sl(theApp->getMasterLock()); boost::recursive_mutex::scoped_lock sl(theApp->getMasterLock());

View File

@@ -1169,7 +1169,7 @@ Json::Value RPCHandler::doTxHistory(const Json::Value& params)
{ {
Database* db = theApp->getTxnDB()->getDB(); Database* db = theApp->getTxnDB()->getDB();
ScopedLock dbLock = theApp->getTxnDB()->getDBLock(); ScopedLock sl (theApp->getTxnDB()->getDBLock());
SQL_FOREACH(db, sql) SQL_FOREACH(db, sql)
{ {
@@ -1493,7 +1493,7 @@ Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& param
cLog(lsTRACE) << "RPC:" << command; cLog(lsTRACE) << "RPC:" << command;
cLog(lsTRACE) << "RPC params:" << params; cLog(lsTRACE) << "RPC params:" << params;
LoadEvent::pointer le = theApp->getJobQueue().getLoadEvent(jtRPC); LoadEvent::autoptr le(theApp->getJobQueue().getLoadEventAP(jtRPC));
mRole = role; mRole = role;

View File

@@ -6,16 +6,18 @@
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
#include <boost/ref.hpp> #include <boost/ref.hpp>
typedef boost::recursive_mutex::scoped_lock ScopedLock;
// A lock holder that can be returned and copied by value // A lock holder that can be returned and copied by value
// When the last reference goes away, the lock is released // When the last reference goes away, the lock is released
class ScopedLock class SharedScopedLock
{ {
protected: protected:
mutable boost::shared_ptr<boost::recursive_mutex::scoped_lock> mHolder; mutable boost::shared_ptr<boost::recursive_mutex::scoped_lock> mHolder;
public: public:
ScopedLock(boost::recursive_mutex& mutex) : SharedScopedLock(boost::recursive_mutex& mutex) :
mHolder(boost::make_shared<boost::recursive_mutex::scoped_lock>(boost::ref(mutex))) { ; } mHolder(boost::make_shared<boost::recursive_mutex::scoped_lock>(boost::ref(mutex))) { ; }
void lock() const { mHolder->lock(); } void lock() const { mHolder->lock(); }

View File

@@ -146,12 +146,13 @@ bool Transaction::save()
default: status = TXN_SQL_UNKNOWN; default: status = TXN_SQL_UNKNOWN;
} }
std::string exists = boost::str(boost::format("SELECT Status FROM Transactions WHERE TransID = '%s';") static boost::format selStat("SELECT Status FROM Transactions WHERE TransID = '%s';");
% mTransaction->getTransactionID().GetHex()); std::string exists = boost::str(selStat % mTransaction->getTransactionID().GetHex());
Database *db = theApp->getTxnDB()->getDB(); Database *db = theApp->getTxnDB()->getDB();
ScopedLock dbLock = theApp->getTxnDB()->getDBLock(); ScopedLock dbLock(theApp->getTxnDB()->getDBLock());
if (SQL_EXISTS(db, exists)) return false; if (SQL_EXISTS(db, exists))
return false;
return return
db->executeSQL(mTransaction->getSQLInsertHeader() + mTransaction->getSQL(getLedger(), status) + ";"); db->executeSQL(mTransaction->getSQLInsertHeader() + mTransaction->getSQL(getLedger(), status) + ";");
} }

View File

@@ -289,7 +289,7 @@ void ValidationCollection::condWrite()
void ValidationCollection::doWrite() void ValidationCollection::doWrite()
{ {
LoadEvent::pointer event = theApp->getJobQueue().getLoadEvent(jtDISK); LoadEvent::autoptr event(theApp->getJobQueue().getLoadEventAP(jtDISK));
static boost::format insVal("INSERT INTO LedgerValidations " static boost::format insVal("INSERT INTO LedgerValidations "
"(LedgerHash,NodePubKey,Flags,SignTime,Signature) VALUES ('%s','%s','%u','%u',%s);"); "(LedgerHash,NodePubKey,Flags,SignTime,Signature) VALUES ('%s','%s','%u','%u',%s);");

View File

@@ -78,7 +78,7 @@ bool Wallet::nodeIdentityCreate() {
#ifdef CREATE_NEW_DH_PARAMS #ifdef CREATE_NEW_DH_PARAMS
std::string strDh512 = DH_der_gen(512); std::string strDh512 = DH_der_gen(512);
#else #else
static char dh512Param[] = { static const unsigned char dh512Param[] = {
0x30, 0x46, 0x02, 0x41, 0x00, 0x98, 0x15, 0xd2, 0xd0, 0x08, 0x32, 0xda, 0x30, 0x46, 0x02, 0x41, 0x00, 0x98, 0x15, 0xd2, 0xd0, 0x08, 0x32, 0xda,
0xaa, 0xac, 0xc4, 0x71, 0xa3, 0x1b, 0x11, 0xf0, 0x6c, 0x62, 0xb2, 0x35, 0xaa, 0xac, 0xc4, 0x71, 0xa3, 0x1b, 0x11, 0xf0, 0x6c, 0x62, 0xb2, 0x35,
0x8a, 0x10, 0x92, 0xc6, 0x0a, 0xa3, 0x84, 0x7e, 0xaf, 0x17, 0x29, 0x0b, 0x8a, 0x10, 0x92, 0xc6, 0x0a, 0xa3, 0x84, 0x7e, 0xaf, 0x17, 0x29, 0x0b,
@@ -86,7 +86,7 @@ bool Wallet::nodeIdentityCreate() {
0x6e, 0xdb, 0x57, 0x72, 0x4a, 0x7e, 0xcd, 0xaf, 0xbd, 0x3a, 0x97, 0x55, 0x6e, 0xdb, 0x57, 0x72, 0x4a, 0x7e, 0xcd, 0xaf, 0xbd, 0x3a, 0x97, 0x55,
0x51, 0x77, 0x5a, 0x34, 0x7c, 0xe8, 0xc5, 0x71, 0x63, 0x02, 0x01, 0x02 0x51, 0x77, 0x5a, 0x34, 0x7c, 0xe8, 0xc5, 0x71, 0x63, 0x02, 0x01, 0x02
}; };
std::string strDh512(dh512Param, sizeof(dh512Param)); std::string strDh512(reinterpret_cast<const char *>(dh512Param), sizeof(dh512Param));
#endif #endif

View File

@@ -154,7 +154,8 @@ inline std::string strHex(const uint64 uiHost)
inline static std::string sqlEscape(const std::string& strSrc) inline static std::string sqlEscape(const std::string& strSrc)
{ {
return str(boost::format("X'%s'") % strHex(strSrc)); static boost::format f("X'%s'");
return str(f % strHex(strSrc));
} }
template<class Iterator> template<class Iterator>

View File

@@ -478,8 +478,15 @@ Amount.prototype.to_human = function (opts)
{ {
opts = opts || {}; opts = opts || {};
var int_part = this._value.divide(consts.bi_xns_unit).toString(10); // Default options
var fraction_part = this._value.mod(consts.bi_xns_unit).toString(10); if ("undefined" === typeof opts.group_sep) opts.group_sep = true;
opts.group_width = opts.group_width || 3;
var denominator = this._is_native ?
consts.bi_xns_unit :
consts.bi_10.clone().pow(-this._offset);
var int_part = this._value.divide(denominator).toString(10);
var fraction_part = this._value.mod(denominator).toString(10);
int_part = int_part.replace(/^0*/, ''); int_part = int_part.replace(/^0*/, '');
fraction_part = fraction_part.replace(/0*$/, ''); fraction_part = fraction_part.replace(/0*$/, '');
@@ -488,6 +495,13 @@ Amount.prototype.to_human = function (opts)
fraction_part = fraction_part.slice(0, opts.precision); fraction_part = fraction_part.slice(0, opts.precision);
} }
if (opts.group_sep) {
if ("string" !== typeof opts.group_sep) {
opts.group_sep = ',';
}
int_part = utils.chunkString(int_part, opts.group_width, true).join(opts.group_sep);
}
var formatted = ''; var formatted = '';
formatted += int_part.length ? int_part : '0'; formatted += int_part.length ? int_part : '0';
formatted += fraction_part.length ? '.'+fraction_part : ''; formatted += fraction_part.length ? '.'+fraction_part : '';
@@ -597,7 +611,7 @@ Amount.prototype.parse_human = function(j) {
this._is_native = false; this._is_native = false;
var multiplier = consts.bi_10.clone().pow(precision); var multiplier = consts.bi_10.clone().pow(precision);
this._value = this._value.multiply(multiplier).add(fraction); this._value = this._value.multiply(multiplier).add(new BigInteger(fraction));
this._offset = -precision; this._offset = -precision;
this.canonicalize(); this.canonicalize();

View File

@@ -39,23 +39,16 @@ var Request = function (remote, command) {
}; };
this.remote = remote; this.remote = remote;
this.requested = false; this.requested = false;
this.on('request', function () {
self.request_default();
});
}; };
Request.prototype = new EventEmitter; Request.prototype = new EventEmitter;
// Send the request to a remote. // Send the request to a remote.
Request.prototype.request = function (remote) { Request.prototype.request = function (remote) {
this.emit('request', remote);
};
Request.prototype.request_default = function () {
if (!this.requested) { if (!this.requested) {
this.requested = true; this.requested = true;
this.remote.request(this); this.remote.request(this);
this.emit('request', remote);
} }
}; };
@@ -595,7 +588,8 @@ Remote.prototype.request_ledger_entry = function (type) {
this.type = type; this.type = type;
// Transparent caching: // Transparent caching:
request.on('request', function (remote) { // Intercept default request. this.request_default = this.request;
this.request = function () { // Intercept default request.
if (self._ledger_hash) { if (self._ledger_hash) {
// XXX Add caching. // XXX Add caching.
} }
@@ -613,7 +607,7 @@ Remote.prototype.request_ledger_entry = function (type) {
if (node) { if (node) {
// Emulate fetch of ledger entry. // Emulate fetch of ledger entry.
this.request.emit('success', { self.emit('success', {
// YYY Missing lots of fields. // YYY Missing lots of fields.
'node' : node, 'node' : node,
}); });
@@ -637,7 +631,7 @@ Remote.prototype.request_ledger_entry = function (type) {
this.request_default(); this.request_default();
} }
} }
}); };
return request; return request;
}; };

View File

@@ -70,6 +70,19 @@ var stringToArray = function (s) {
return a; return a;
}; };
var chunkString = function (str, n, leftAlign) {
var ret = [];
var i=0, len=str.length;
if (leftAlign) {
i = str.length % n;
if (i) ret.push(str.slice(0, i));
}
for(; i < len; i += n) {
ret.push(str.slice(i, n+i));
}
return ret;
};
var logObject = function (msg, obj) { var logObject = function (msg, obj) {
console.log(msg, JSON.stringify(obj, undefined, 2)); console.log(msg, JSON.stringify(obj, undefined, 2));
}; };
@@ -81,5 +94,6 @@ exports.hexToString = hexToString;
exports.stringToArray = stringToArray; exports.stringToArray = stringToArray;
exports.stringToHex = stringToHex; exports.stringToHex = stringToHex;
exports.logObject = logObject; exports.logObject = logObject;
exports.chunkString = chunkString;
// vim:sw=2:sts=2:ts=8:et // vim:sw=2:sts=2:ts=8:et