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

This commit is contained in:
Arthur Britto
2012-06-22 01:46:21 -07:00
8 changed files with 82 additions and 35 deletions

View File

@@ -57,8 +57,13 @@ bool HashedObject::store(HashedObjectType type, uint32 index, const std::vector<
sql.append(obj);
sql.append(");");
std::string exists =
boost::str(boost::format("SELECT ObjType FROM CommittedObject WHERE Hash = '%s';") % hash.GetHex());
ScopedLock sl(theApp->getHashNodeDB()->getDBLock());
Database* db = theApp->getHashNodeDB()->getDB();
if (SQL_EXISTS(db, exists))
return false;
return db->executeSQL(sql);
}
@@ -73,7 +78,7 @@ bool HashedObject::store() const
HashedObject::pointer HashedObject::retrieve(const uint256& hash)
{
if (!theApp || !theApp->getHashNodeDB()) return HashedObject::pointer();
std::string sql = "SELECT * from CommittedObjects WHERE Hash='";
std::string sql = "SELECT * FROM CommittedObjects WHERE Hash='";
sql.append(hash.GetHex());
sql.append("';");
@@ -119,4 +124,14 @@ HashedObject::pointer HashedObject::retrieve(const uint256& hash)
return obj;
}
HashedObjectBulkWriter::HashedObjectBulkWriter() : sl(theApp->getHashNodeDB()->getDBLock())
{
theApp->getHashNodeDB()->getDB()->executeSQL("BEGIN TRANSACTION;");
}
HashedObjectBulkWriter::~HashedObjectBulkWriter()
{
theApp->getHashNodeDB()->getDB()->executeSQL("END TRANSACTION;");
}
// vim:ts=4

View File

@@ -3,18 +3,17 @@
#include <vector>
#include <boost/shared_ptr.hpp>
#include "types.h"
#include "uint256.h"
#include "ScopedLock.h"
enum HashedObjectType
{
UNKNOWN=0,
LEDGER=1,
TRANSACTION=2,
ACCOUNT_NODE=3,
TRANSACTION_NODE=4
UNKNOWN = 0,
LEDGER = 1,
TRANSACTION = 2,
ACCOUNT_NODE = 3,
TRANSACTION_NODE = 4
};
class HashedObject
@@ -37,10 +36,27 @@ public:
const std::vector<unsigned char>& getData() { return mData; }
bool store() const;
static bool store(HashedObjectType type, uint32 index, const std::vector<unsigned char>& data,
const uint256& hash);
static HashedObject::pointer retrieve(const uint256& hash);
};
class HashedObjectBulkWriter
{
protected:
ScopedLock sl;
public:
HashedObjectBulkWriter();
~HashedObjectBulkWriter();
bool store(HashedObjectType type, uint32 index, const std::vector<unsigned char>& data, const uint256& hash)
{ return HashedObject::store(type, index, data, hash); }
HashedObject::pointer retrieve(const uint256& hash)
{ return HashedObject::retrieve(hash); }
};
#endif

View File

@@ -20,11 +20,8 @@
Ledger::Ledger(const NewcoinAddress& masterID, uint64 startAmount) : mTotCoins(startAmount),
mCloseTime(0), mLedgerSeq(0), mLedgerInterval(LEDGER_INTERVAL), mClosed(false), mValidHash(false),
mAccepted(false), mImmutable(false)
mAccepted(false), mImmutable(false), mTransactionMap(new SHAMap()), mAccountStateMap(new SHAMap())
{
mTransactionMap = boost::make_shared<SHAMap>();
mAccountStateMap = boost::make_shared<SHAMap>();
// special case: put coins in root account
AccountState::pointer startAccount = boost::make_shared<AccountState>(masterID);
startAccount->peekSLE().setIFieldAmount(sfBalance, startAmount);
@@ -263,10 +260,11 @@ void Ledger::saveAcceptedLedger(Ledger::pointer ledger)
theApp->getLedgerDB()->getDB()->executeSQL(sql);
// write out dirty nodes
while(ledger->mTransactionMap->flushDirty(64, TRANSACTION_NODE, ledger->mLedgerSeq))
while(ledger->mTransactionMap->flushDirty(256, TRANSACTION_NODE, ledger->mLedgerSeq))
{ ; }
while(ledger->mAccountStateMap->flushDirty(64, ACCOUNT_NODE, ledger->mLedgerSeq))
while(ledger->mAccountStateMap->flushDirty(256, ACCOUNT_NODE, ledger->mLedgerSeq))
{ ; }
ledger->disarmDirty();
SHAMap& txSet = *ledger->peekTransactionMap();
Database *db = theApp->getTxnDB()->getDB();

View File

@@ -60,6 +60,8 @@ public:
private:
static uint64 sGenesisClose;
uint256 mHash, mParentHash, mTransHash, mAccountHash;
uint64 mTotCoins;
uint64 mCloseTime; // when this ledger closes
@@ -67,8 +69,6 @@ private:
uint16 mLedgerInterval;
bool mClosed, mValidHash, mAccepted, mImmutable;
static uint64 sGenesisClose;
SHAMap::pointer mTransactionMap, mAccountStateMap;
mutable boost::recursive_mutex mLock;
@@ -102,6 +102,8 @@ public:
bool isClosed() { return mClosed; }
bool isAccepted() { return mAccepted; }
bool isImmutable() { return mImmutable; }
void armDirty() { mTransactionMap->armDirty(); mAccountStateMap->armDirty(); }
void disarmDirty() { mTransactionMap->disarmDirty(); mAccountStateMap->disarmDirty(); }
// This ledger has closed, will never be accepted, and is accepting
// new transactions to be re-repocessed when do accept a new last-closed ledger

View File

@@ -752,6 +752,7 @@ void LedgerConsensus::accept(SHAMap::pointer set)
Log(lsDEBUG) << "Previous LCL " << mPrevLedgerHash.GetHex();
Ledger::pointer newLCL = boost::make_shared<Ledger>(false, boost::ref(*mPreviousLedger));
newLCL->armDirty();
#ifdef DEBUG
Json::StyledStreamWriter ssw;

View File

@@ -629,6 +629,12 @@ bool SHAMap::fetchNode(const uint256& hash, std::vector<unsigned char>& data)
return true;
}
void SHAMap::armDirty()
{ // begin saving dirty nodes
++mSeq;
mDirtyNodes = boost::make_shared< boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer> >();
}
int SHAMap::flushDirty(int maxNodes, HashedObjectType t, uint32 seq)
{
int flushed = 0;
@@ -636,37 +642,45 @@ int SHAMap::flushDirty(int maxNodes, HashedObjectType t, uint32 seq)
if(mDirtyNodes)
{
while (!mDirtyNodes->empty())
HashedObjectBulkWriter bw;
boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer>& dirtyNodes = *mDirtyNodes;
boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer>::iterator it = dirtyNodes.begin();
while (it != dirtyNodes.end())
{
SHAMapTreeNode::pointer& din = mDirtyNodes->begin()->second;
s.erase();
din->addRaw(s);
HashedObject::store(t, seq, s.peekData(), s.getSHA512Half());
mDirtyNodes->erase(mDirtyNodes->begin());
if(flushed++>=maxNodes) return flushed;
it->second->addRaw(s);
bw.store(t, seq, s.peekData(), s.getSHA512Half());
if (flushed++ >= maxNodes)
return flushed;
it = dirtyNodes.erase(it);
}
}
return flushed;
}
void SHAMap::disarmDirty()
{ // stop saving dirty nodes
mDirtyNodes = boost::shared_ptr< boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer> >();
}
SHAMapTreeNode::pointer SHAMap::getNode(const SHAMapNode& nodeID)
{
boost::recursive_mutex::scoped_lock sl(mLock);
SHAMapTreeNode::pointer node=checkCacheNode(nodeID);
if(node) return node;
SHAMapTreeNode::pointer node = checkCacheNode(nodeID);
if (node) return node;
node=root;
while(nodeID!=*node)
node = root;
while (nodeID != *node)
{
int branch=node->selectBranch(nodeID.getNodeID());
assert(branch>=0);
if( (branch<0) || (node->isEmptyBranch(branch)) )
int branch = node->selectBranch(nodeID.getNodeID());
assert(branch >= 0);
if ((branch < 0) || node->isEmptyBranch(branch))
return SHAMapTreeNode::pointer();
node=getNode(node->getChildNodeID(branch), node->getChildHash(branch), false);
if(!node) throw SHAMapException(MissingNode);
node = getNode(node->getChildNodeID(branch), node->getChildHash(branch), false);
if (!node) throw SHAMapException(MissingNode);
}
return node;
}

View File

@@ -244,7 +244,7 @@ private:
mutable boost::recursive_mutex mLock;
boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer> mTNByID;
boost::shared_ptr<std::map<SHAMapNode, SHAMapTreeNode::pointer> > mDirtyNodes;
boost::shared_ptr< boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer> > mDirtyNodes;
SHAMapTreeNode::pointer root;
@@ -329,7 +329,9 @@ public:
// return value: true=successfully completed, false=too different
bool compare(SHAMap::pointer otherMap, SHAMapDiff& differences, int maxCount);
void armDirty();
int flushDirty(int maxNodes, HashedObjectType t, uint32 seq);
void disarmDirty();
void setSeq(uint32 seq) { mSeq = seq; }
uint32 getSeq() { return mSeq; }

View File

@@ -2,7 +2,6 @@
#define __SCOPEDLOCKHOLDER__
#include <boost/thread/recursive_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/ref.hpp>
@@ -13,11 +12,11 @@
class ScopedLock
{
protected:
mutable boost::shared_ptr<boost::interprocess::scoped_lock<boost::recursive_mutex> > mHolder;
mutable boost::shared_ptr<boost::recursive_mutex::scoped_lock> mHolder;
public:
ScopedLock(boost::recursive_mutex& mutex) :
mHolder(boost::make_shared<boost::interprocess::scoped_lock<boost::recursive_mutex> >(boost::ref(mutex)))
mHolder(boost::make_shared<boost::recursive_mutex::scoped_lock>(boost::ref(mutex)))
{ ; }
void lock() const
{