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

This commit is contained in:
Arthur Britto
2012-06-04 12:20:00 -07:00
15 changed files with 179 additions and 97 deletions

View File

@@ -12,8 +12,10 @@
#include "BitcoinUtil.h"
#include "key.h"
#include "utils.h"
#include "TaggedCache.h"
Application* theApp=NULL;
Application* theApp = NULL;
DatabaseCon::DatabaseCon(const std::string& name, const char *initStrings[], int initCount)
{
@@ -32,11 +34,12 @@ DatabaseCon::~DatabaseCon()
Application::Application() :
mUNL(mIOService),
mNetOps(mIOService, &mMasterLedger),
mNetOps(mIOService, &mMasterLedger), mNodeCache(16384, 600),
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 *TxnDBInit[], *LedgerDBInit[], *WalletDBInit[], *HashNodeDBInit[], *NetNodeDBInit[];

View File

@@ -1,6 +1,8 @@
#ifndef __APPLICATION__
#define __APPLICATION__
#include <boost/asio.hpp>
#include "LedgerMaster.h"
#include "UniqueNodeList.h"
#include "ConnectionPool.h"
@@ -10,12 +12,13 @@
#include "Wallet.h"
#include "Peer.h"
#include "NetworkOPs.h"
#include "TaggedCache.h"
#include "../database/database.h"
#include <boost/asio.hpp>
class RPCDoor;
class PeerDoor;
typedef TaggedCache< uint256, std::vector<unsigned char> > NodeCache;
class DatabaseCon
{
@@ -40,6 +43,7 @@ class Application
LedgerAcquireMaster mMasterLedgerAcquire;
TransactionMaster mMasterTransaction;
NetworkOPs mNetOps;
NodeCache mNodeCache;
DatabaseCon* mTxnDB, *mLedgerDB, *mWalletDB, *mHashNodeDB, *mNetNodeDB;
@@ -48,6 +52,7 @@ class Application
RPCDoor* mRPCDoor;
uint256 mNonce256;
std::size_t mNonceST;
std::map<std::string, Peer::pointer> mPeerMap;
boost::recursive_mutex mPeerMapLock;
@@ -56,26 +61,28 @@ public:
Application();
~Application();
ConnectionPool& getConnectionPool() { return mConnectionPool; }
ConnectionPool& getConnectionPool() { return mConnectionPool; }
UniqueNodeList& getUNL() { return mUNL; }
UniqueNodeList& getUNL() { return mUNL; }
Wallet& getWallet() { return mWallet ; }
NetworkOPs& getOPs() { return mNetOps; }
Wallet& getWallet() { return mWallet ; }
NetworkOPs& getOPs() { return mNetOps; }
boost::asio::io_service& getIOService() { return mIOService; }
boost::asio::io_service& getIOService() { return mIOService; }
LedgerMaster& getMasterLedger() { return mMasterLedger; }
LedgerAcquireMaster& getMasterLedgerAcquire() { return mMasterLedgerAcquire; }
TransactionMaster& getMasterTransaction() { return mMasterTransaction; }
LedgerMaster& getMasterLedger() { return mMasterLedger; }
LedgerAcquireMaster& getMasterLedgerAcquire() { return mMasterLedgerAcquire; }
TransactionMaster& getMasterTransaction() { return mMasterTransaction; }
NodeCache& getNodeCache() { return mNodeCache; }
DatabaseCon* getTxnDB() { return mTxnDB; }
DatabaseCon* getLedgerDB() { return mLedgerDB; }
DatabaseCon* getWalletDB() { return mWalletDB; }
DatabaseCon* getHashNodeDB() { return mHashNodeDB; }
DatabaseCon* getNetNodeDB() { return mNetNodeDB; }
DatabaseCon* getTxnDB() { return mTxnDB; }
DatabaseCon* getLedgerDB() { return mLedgerDB; }
DatabaseCon* getWalletDB() { return mWalletDB; }
DatabaseCon* getHashNodeDB() { return mHashNodeDB; }
DatabaseCon* getNetNodeDB() { return mNetNodeDB; }
uint256 getNonce256() { return mNonce256; }
uint256 getNonce256() { return mNonce256; }
std::size_t getNonceST() { return mNonceST; }
void run();
void stop();

View File

@@ -67,7 +67,7 @@ void PeerSet::TimerEntry(boost::weak_ptr<PeerSet> wptr, const boost::system::err
}
LedgerAcquire::LedgerAcquire(const uint256& hash) : PeerSet(hash, LEDGER_ACQUIRE_TIMEOUT),
mHaveBase(false), mHaveState(false), mHaveTransactions(false)
mFilter(&theApp->getNodeCache()), mHaveBase(false), mHaveState(false), mHaveTransactions(false)
{
#ifdef DEBUG
std::cerr << "Acquiring ledger " << mHash.GetHex() << std::endl;
@@ -152,7 +152,7 @@ void LedgerAcquire::trigger(Peer::pointer peer)
{
std::vector<SHAMapNode> nodeIDs;
std::vector<uint256> nodeHashes;
mLedger->peekTransactionMap()->getMissingNodes(nodeIDs, nodeHashes, 128);
mLedger->peekTransactionMap()->getMissingNodes(nodeIDs, nodeHashes, 128, &mFilter);
if (nodeIDs.empty())
{
if (!mLedger->peekTransactionMap()->isValid()) mFailed = true;
@@ -204,7 +204,7 @@ void LedgerAcquire::trigger(Peer::pointer peer)
{
std::vector<SHAMapNode> nodeIDs;
std::vector<uint256> nodeHashes;
mLedger->peekAccountStateMap()->getMissingNodes(nodeIDs, nodeHashes, 128);
mLedger->peekAccountStateMap()->getMissingNodes(nodeIDs, nodeHashes, 128, &mFilter);
if (nodeIDs.empty())
{
if (!mLedger->peekAccountStateMap()->isValid()) mFailed = true;
@@ -303,7 +303,7 @@ bool LedgerAcquire::takeTxNode(const std::list<SHAMapNode>& nodeIDs,
if (!mLedger->peekTransactionMap()->addRootNode(mLedger->getTransHash(), *nodeDatait))
return false;
}
else if (!mLedger->peekTransactionMap()->addKnownNode(*nodeIDit, *nodeDatait))
else if (!mLedger->peekTransactionMap()->addKnownNode(*nodeIDit, *nodeDatait, &mFilter))
return false;
++nodeIDit;
++nodeDatait;
@@ -333,7 +333,7 @@ bool LedgerAcquire::takeAsNode(const std::list<SHAMapNode>& nodeIDs,
if (!mLedger->peekAccountStateMap()->addRootNode(mLedger->getAccountHash(), *nodeDatait))
return false;
}
else if (!mLedger->peekAccountStateMap()->addKnownNode(*nodeIDit, *nodeDatait))
else if (!mLedger->peekAccountStateMap()->addKnownNode(*nodeIDit, *nodeDatait, &mFilter))
return false;
++nodeIDit;
++nodeDatait;

View File

@@ -13,6 +13,7 @@
#include "Ledger.h"
#include "Peer.h"
#include "TaggedCache.h"
#include "../obj/src/newcoin.pb.h"
class PeerSet
@@ -53,6 +54,31 @@ private:
static void TimerEntry(boost::weak_ptr<PeerSet>, const boost::system::error_code& result);
};
typedef TaggedCache< uint256, std::vector<unsigned char> > NodeCache;
typedef std::vector<unsigned char> VUC;
class THSyncFilter : public SHAMapSyncFilter
{
protected:
NodeCache* mCache;
public:
THSyncFilter(NodeCache* cache) : mCache(cache) { ; }
virtual void gotNode(const SHAMapNode& id, const uint256& nodeHash,
const std::vector<unsigned char>& nodeData, bool)
{
boost::shared_ptr<VUC> ptr = boost::make_shared<VUC>(nodeData);
mCache->canonicalize(nodeHash, ptr);
}
virtual bool haveNode(const SHAMapNode& id, const uint256& nodeHash, std::vector<unsigned char>& nodeData)
{
boost::shared_ptr<VUC> entry = mCache->fetch(nodeHash);
if (!entry) return false;
nodeData = *entry;
return true;
}
};
class LedgerAcquire : public PeerSet, public boost::enable_shared_from_this<LedgerAcquire>
{ // A ledger we are trying to acquire
public:
@@ -60,6 +86,7 @@ public:
protected:
Ledger::pointer mLedger;
THSyncFilter mFilter;
bool mHaveBase, mHaveState, mHaveTransactions;
std::vector< boost::function<void (LedgerAcquire::pointer)> > mOnComplete;
@@ -106,4 +133,5 @@ public:
};
#endif
// vim:ts=4

View File

@@ -11,7 +11,8 @@
#define TRUST_NETWORK
TransactionAcquire::TransactionAcquire(const uint256& hash) : PeerSet(hash, 1), mHaveRoot(false)
TransactionAcquire::TransactionAcquire(const uint256& hash)
: PeerSet(hash, 1), mFilter(&theApp->getNodeCache()), mHaveRoot(false)
{
mMap = boost::make_shared<SHAMap>();
mMap->setSynching();
@@ -48,7 +49,7 @@ void TransactionAcquire::trigger(Peer::pointer peer)
Log(lsTRACE) << "Have root";
std::vector<SHAMapNode> nodeIDs;
std::vector<uint256> nodeHashes;
mMap->getMissingNodes(nodeIDs, nodeHashes, 256);
mMap->getMissingNodes(nodeIDs, nodeHashes, 256, &mFilter);
if (nodeIDs.empty())
{
if (mMap->isValid())
@@ -100,7 +101,7 @@ bool TransactionAcquire::takeNodes(const std::list<SHAMapNode>& nodeIDs,
return false;
else mHaveRoot = true;
}
else if (!mMap->addKnownNode(*nodeIDit, *nodeDatait))
else if (!mMap->addKnownNode(*nodeIDit, *nodeDatait, &mFilter))
return false;
++nodeIDit;
++nodeDatait;

View File

@@ -21,6 +21,7 @@ public:
protected:
SHAMap::pointer mMap;
THSyncFilter mFilter; // FIXME: Should use transaction master too
bool mHaveRoot;
void onTimer() { trigger(Peer::pointer()); }
@@ -47,7 +48,7 @@ protected:
int mYays, mNays;
bool mOurPosition;
std::vector<unsigned char> transaction;
boost::unordered_map<uint256, bool, hash_SMN> mVotes;
boost::unordered_map<uint256, bool> mVotes;
public:
typedef boost::shared_ptr<LCTransaction> pointer;
@@ -85,17 +86,17 @@ protected:
LedgerProposal::pointer mOurPosition;
// Convergence tracking, trusted peers indexed by hash of public key
boost::unordered_map<uint256, LedgerProposal::pointer, hash_SMN> mPeerPositions;
boost::unordered_map<uint256, LedgerProposal::pointer> mPeerPositions;
// Transaction Sets, indexed by hash of transaction tree
boost::unordered_map<uint256, SHAMap::pointer, hash_SMN> mComplete;
boost::unordered_map<uint256, TransactionAcquire::pointer, hash_SMN> mAcquiring;
boost::unordered_map<uint256, SHAMap::pointer> mComplete;
boost::unordered_map<uint256, TransactionAcquire::pointer> mAcquiring;
// Peer sets
boost::unordered_map<uint256, std::vector< boost::weak_ptr<Peer> >, hash_SMN> mPeerData;
boost::unordered_map<uint256, std::vector< boost::weak_ptr<Peer> > > mPeerData;
// Disputed transactions
boost::unordered_map<uint256, LCTransaction::pointer, hash_SMN> mDisputes;
boost::unordered_map<uint256, LCTransaction::pointer> mDisputes;
// final accept logic
static void Saccept(boost::shared_ptr<LedgerConsensus> This, SHAMap::pointer txSet);

View File

@@ -285,7 +285,7 @@ void NetworkOPs::checkState(const boost::system::error_code& result)
// Do we have sufficient validations for our last closed ledger? Or do sufficient nodes
// agree? And do we have no better ledger available?
// If so, we are either tracking or full.
boost::unordered_map<uint256, ValidationCount, hash_SMN> ledgers;
boost::unordered_map<uint256, ValidationCount> ledgers;
for (std::vector<Peer::pointer>::iterator it = peerList.begin(), end = peerList.end(); it != end; ++it)
{

View File

@@ -726,6 +726,7 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
{
SHAMap::pointer map;
newcoin::TMLedgerData reply;
bool fatLeaves = true;
if (packet.itype() == newcoin::liTS_CANDIDATE)
{ // Request is for a transaction candidate set
@@ -748,6 +749,7 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
reply.set_ledgerseq(0);
reply.set_ledgerhash(txHash.begin(), txHash.size());
reply.set_type(newcoin::liTS_CANDIDATE);
fatLeaves = false; // We'll already have most transactions
}
else
{ // Figure out what ledger they want
@@ -828,7 +830,7 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
}
std::vector<SHAMapNode> nodeIDs;
std::list< std::vector<unsigned char> > rawNodes;
if(map->getNodeFat(mn, nodeIDs, rawNodes))
if(map->getNodeFat(mn, nodeIDs, rawNodes, fatLeaves))
{
std::vector<SHAMapNode>::iterator nodeIDIterator;
std::list< std::vector<unsigned char> >::iterator rawNodeIterator;

View File

@@ -15,17 +15,17 @@
#include "SHAMap.h"
#include "Application.h"
std::size_t hash_SMN::operator() (const SHAMapNode& mn) const
std::size_t hash_value(const SHAMapNode& mn)
{
return mn.getDepth()
^ *reinterpret_cast<const std::size_t *>(mn.getNodeID().begin())
^ *reinterpret_cast<const std::size_t *>(theApp->getNonce256().begin());
std::size_t seed = theApp->getNonceST();
boost::hash_combine(seed, mn.getDepth());
return mn.getNodeID().hash_combine(seed);
}
std::size_t hash_SMN::operator() (const uint256& u) const
std::size_t hash_value(const uint256& u)
{
return *reinterpret_cast<const std::size_t *>(u.begin())
^ *reinterpret_cast<const std::size_t *>(theApp->getNonce256().begin());
std::size_t seed = theApp->getNonceST();
return u.hash_combine(seed);
}
SHAMap::SHAMap(uint32 seq) : mSeq(seq), mState(Modifying)
@@ -671,7 +671,7 @@ void SHAMap::dump(bool hash)
std::cerr << " MAP Contains" << std::endl;
boost::recursive_mutex::scoped_lock sl(mLock);
for(boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer, hash_SMN>::iterator it = mTNByID.begin();
for(boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer>::iterator it = mTNByID.begin();
it != mTNByID.end(); ++it)
{
std::cerr << it->second->getString() << std::endl;

View File

@@ -76,14 +76,8 @@ public:
SHAMapNode(const void *ptr, int len);
};
class hash_SMN
{
public:
std::size_t operator() (const SHAMapNode& mn) const;
std::size_t operator() (const uint256& u) const;
};
extern std::size_t hash_value(const SHAMapNode& mn);
extern std::size_t hash_value(const uint256& u);
class SHAMapItem
{ // an item stored in a SHAMap
@@ -225,6 +219,18 @@ enum SHAMapState
Invalid = 4, // Map is known not to be valid (usually synching a corrupt ledger)
};
class SHAMapSyncFilter
{
public:
SHAMapSyncFilter() { ; }
virtual ~SHAMapSyncFilter() { ; }
virtual void gotNode(const SHAMapNode& id, const uint256& nodeHash,
const std::vector<unsigned char>& nodeData, bool isLeaf)
{ ; }
virtual bool haveNode(const SHAMapNode& id, const uint256& nodeHash, std::vector<unsigned char>& nodeData)
{ return false; }
};
class SHAMap
{
public:
@@ -234,7 +240,7 @@ public:
private:
uint32 mSeq;
mutable boost::recursive_mutex mLock;
boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer, hash_SMN> mTNByID;
boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer> mTNByID;
boost::shared_ptr<std::map<SHAMapNode, SHAMapTreeNode::pointer> > mDirtyNodes;
@@ -299,12 +305,14 @@ public:
SHAMapItem::pointer peekPrevItem(const uint256&);
// comparison/sync functions
void getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint256>& hashes, int max);
void getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint256>& hashes, int max,
SHAMapSyncFilter* filter);
bool getNodeFat(const SHAMapNode& node, std::vector<SHAMapNode>& nodeIDs,
std::list<std::vector<unsigned char> >& rawNode);
std::list<std::vector<unsigned char> >& rawNode, bool fatLeaves);
bool addRootNode(const uint256& hash, const std::vector<unsigned char>& rootNode);
bool addRootNode(const std::vector<unsigned char>& rootNode);
bool addKnownNode(const SHAMapNode& nodeID, const std::vector<unsigned char>& rawNode);
bool addKnownNode(const SHAMapNode& nodeID, const std::vector<unsigned char>& rawNode,
SHAMapSyncFilter* filter);
// status functions
void setImmutable(void) { assert(mState != Invalid); mState = Immutable; }

View File

@@ -11,19 +11,20 @@
#include "Log.h"
void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint256>& hashes, int max)
void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint256>& hashes, int max,
SHAMapSyncFilter* filter)
{
boost::recursive_mutex::scoped_lock sl(mLock);
assert(root->isValid());
if(root->isFullBelow())
if (root->isFullBelow())
{
clearSynching();
return;
}
if(!root->isInner())
if (!root->isInner())
{
Log(lsWARNING) << "synching empty tree";
return;
@@ -43,7 +44,27 @@ void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint2
int branch = (base + ii) % 16;
if (!node->isEmptyBranch(branch))
{
SHAMapTreeNode::pointer d = getNode(node->getChildNodeID(branch), node->getChildHash(branch), false);
SHAMapNode childID = node->getChildNodeID(branch);
const uint256& childHash = node->getChildHash(branch);
SHAMapTreeNode::pointer d = getNode(childID, childHash, false);
if ((!d) && (filter != NULL))
{
std::vector<unsigned char> nodeData;
if (filter->haveNode(childID, childHash, nodeData))
{
d = boost::make_shared<SHAMapTreeNode>(childID, nodeData, mSeq);
if (childHash != d->getNodeHash())
{
Log(lsERROR) << "Wrong hash from cached object";
d = SHAMapTreeNode::pointer();
}
else
{
Log(lsTRACE) << "Got sync node from cache";
mTNByID[*d] = d;
}
}
}
if (!d)
{
nodeIDs.push_back(node->getChildNodeID(branch));
@@ -58,14 +79,14 @@ void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint2
}
bool SHAMap::getNodeFat(const SHAMapNode& wanted, std::vector<SHAMapNode>& nodeIDs,
std::list<std::vector<unsigned char> >& rawNodes)
std::list<std::vector<unsigned char> >& rawNodes, bool fatLeaves)
{ // Gets a node and some of its children
boost::recursive_mutex::scoped_lock sl(mLock);
SHAMapTreeNode::pointer node = getNode(wanted);
if (!node)
{
assert(false); // Remove for release, this can happen if we get a bogus request
assert(false); // FIXME Remove for release, this can happen if we get a bogus request
return false;
}
@@ -82,7 +103,7 @@ bool SHAMap::getNodeFat(const SHAMapNode& wanted, std::vector<SHAMapNode>& nodeI
{
SHAMapTreeNode::pointer nextNode = getNode(node->getChildNodeID(i), node->getChildHash(i), false);
assert(nextNode);
if(nextNode)
if (nextNode && (fatLeaves || !nextNode->isLeaf()))
{
nodeIDs.push_back(*nextNode);
Serializer s;
@@ -153,7 +174,8 @@ bool SHAMap::addRootNode(const uint256& hash, const std::vector<unsigned char>&
return true;
}
bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned char>& rawNode)
bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned char>& rawNode,
SHAMapSyncFilter* filter)
{ // return value: true=okay, false=error
assert(!node.isRoot());
if (!isSynching()) return false;
@@ -199,6 +221,8 @@ bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned cha
if (hash != newNode->getNodeHash()) // these aren't the droids we're looking for
return false;
if (filter) filter->gotNode(node, hash, rawNode, newNode->isLeaf());
mTNByID[*newNode] = newNode;
if (!newNode->isLeaf())
return true; // only a leaf can fill a branch
@@ -209,7 +233,7 @@ bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned cha
iNode = stack.top();
stack.pop();
assert(iNode->isInner());
for(int i = 0; i < 16; ++i)
for (int i = 0; i < 16; ++i)
if (!iNode->isEmptyBranch(i))
{
SHAMapTreeNode::pointer nextNode = getNode(iNode->getChildNodeID(i), iNode->getChildHash(i), false);
@@ -234,7 +258,7 @@ bool SHAMap::deepCompare(SHAMap& other)
stack.pop();
SHAMapTreeNode::pointer otherNode;
if(node->isRoot()) otherNode = other.root;
if (node->isRoot()) otherNode = other.root;
else otherNode = other.getNode(*node, node->getNodeHash(), false);
if (!otherNode)
@@ -262,11 +286,11 @@ bool SHAMap::deepCompare(SHAMap& other)
{
if (!otherNode->isInner())
return false;
for(int i=0; i<16; i++)
for (int i = 0; i < 16; ++i)
{
if(node->isEmptyBranch(i))
if (node->isEmptyBranch(i))
{
if(!otherNode->isEmptyBranch(i)) return false;
if (!otherNode->isEmptyBranch(i)) return false;
}
else
{
@@ -290,9 +314,9 @@ bool SHAMap::deepCompare(SHAMap& other)
static SHAMapItem::pointer makeRandomAS()
{
Serializer s;
for(int d = 0; d < 3; ++d) s.add32(rand());
return boost::make_shared<SHAMapItem>(s.getRIPEMD160().to256(), s.peekData());
Serializer s;
for (int d = 0; d < 3; ++d) s.add32(rand());
return boost::make_shared<SHAMapItem>(s.getRIPEMD160().to256(), s.peekData());
}
static bool confuseMap(SHAMap &map, int count)
@@ -362,32 +386,31 @@ BOOST_AUTO_TEST_CASE( SHAMapSync_test )
SHAMap source, destination;
// add random data to the source map
int items = 10000;
for (int i = 0; i < items; ++i)
source.addItem(*makeRandomAS(), false);
Log(lsTRACE) << "Adding items, then removing them";
if(!confuseMap(source, 500)) BOOST_FAIL("ConfuseMap");
if (!confuseMap(source, 500)) BOOST_FAIL("ConfuseMap");
source.setImmutable();
Log(lsTRACE) << "SOURCE COMPLETE, SYNCHING";
std::vector<SHAMapNode> nodeIDs, gotNodeIDs;
std::list<std::vector<unsigned char> > gotNodes;
std::list< std::vector<unsigned char> > gotNodes;
std::vector<uint256> hashes;
std::vector<SHAMapNode>::iterator nodeIDIterator;
std::list<std::vector<unsigned char> >::iterator rawNodeIterator;
std::list< std::vector<unsigned char> >::iterator rawNodeIterator;
int passes = 0;
int nodes = 0;
destination.setSynching();
if (!source.getNodeFat(SHAMapNode(), nodeIDs, gotNodes))
if (!source.getNodeFat(SHAMapNode(), nodeIDs, gotNodes, (rand() % 2) == 0))
{
Log(lsFATAL) << "GetNodeFat(root) fails";
BOOST_FAIL("GetNodeFat");
@@ -416,14 +439,14 @@ BOOST_AUTO_TEST_CASE( SHAMapSync_test )
hashes.clear();
// get the list of nodes we know we need
destination.getMissingNodes(nodeIDs, hashes, 2048);
if(nodeIDs.empty()) break;
destination.getMissingNodes(nodeIDs, hashes, 2048, NULL);
if (nodeIDs.empty()) break;
Log(lsINFO) << nodeIDs.size() << " needed nodes";
// get as many nodes as possible based on this information
for (nodeIDIterator = nodeIDs.begin(); nodeIDIterator != nodeIDs.end(); ++nodeIDIterator)
if (!source.getNodeFat(*nodeIDIterator, gotNodeIDs, gotNodes))
if (!source.getNodeFat(*nodeIDIterator, gotNodeIDs, gotNodes, (rand() % 2) == 0))
{
Log(lsFATAL) << "GetNodeFat fails";
BOOST_FAIL("GetNodeFat");
@@ -446,7 +469,7 @@ BOOST_AUTO_TEST_CASE( SHAMapSync_test )
#ifdef SMS_DEBUG
bytes += rawNodeIterator->size();
#endif
if (!destination.addKnownNode(*nodeIDIterator, *rawNodeIterator))
if (!destination.addKnownNode(*nodeIDIterator, *rawNodeIterator, NULL))
{
Log(lsTRACE) << "AddKnownNode fails";
BOOST_FAIL("AddKnownNode");

View File

@@ -4,6 +4,7 @@
#include <map>
#include <boost/thread/recursive_mutex.hpp>
#include <boost/unordered_map.hpp>
#include <boost/shared_ptr.hpp>
// This class implemented a cache and a map. The cache keeps objects alive
@@ -25,10 +26,10 @@ protected:
mutable boost::recursive_mutex mLock;
int mTargetSize, mTargetAge;
std::map<key_type, cache_entry> mCache; // Hold strong reference to recent objects
boost::unordered_map<key_type, cache_entry> mCache; // Hold strong reference to recent objects
time_t mLastSweep;
std::map<key_type, weak_data_ptr> mMap; // Track stored objects
boost::unordered_map<key_type, weak_data_ptr> mMap; // Track stored objects
public:
TaggedCache(int size, int age) : mTargetSize(size), mTargetAge(age), mLastSweep(time(NULL)) { ; }
@@ -81,7 +82,7 @@ template<typename c_Key, typename c_Data> void TaggedCache<c_Key, c_Data>::sweep
time_t target = now - mTargetAge;
// Pass 1, remove old objects from cache
typename std::map<key_type, cache_entry>::iterator cit = mCache.begin();
typename boost::unordered_map<key_type, cache_entry>::iterator cit = mCache.begin();
while (cit != mCache.end())
{
if (cit->second->second.first < target)
@@ -90,7 +91,7 @@ template<typename c_Key, typename c_Data> void TaggedCache<c_Key, c_Data>::sweep
}
// Pass 2, remove dead objects from map
typename std::map<key_type, weak_data_ptr>::iterator mit = mMap.begin();
typename boost::unordered_map<key_type, weak_data_ptr>::iterator mit = mMap.begin();
while (mit != mMap.end())
{
if (mit->second->expired())
@@ -104,7 +105,7 @@ template<typename c_Key, typename c_Data> bool TaggedCache<c_Key, c_Data>::touch
boost::recursive_mutex::scoped_lock sl(mLock);
// Is the object in the map?
typename std::map<key_type, weak_data_ptr>::iterator mit = mMap.find(key);
typename boost::unordered_map<key_type, weak_data_ptr>::iterator mit = mMap.find(key);
if (mit == mMap.end()) return false;
if (mit->second->expired())
{ // in map, but expired
@@ -113,7 +114,7 @@ template<typename c_Key, typename c_Data> bool TaggedCache<c_Key, c_Data>::touch
}
// Is the object in the cache?
typename std::map<key_type, cache_entry>::iterator cit = mCache.find(key);
typename boost::unordered_map<key_type, cache_entry>::iterator cit = mCache.find(key);
if (cit != mCache.end())
{ // in both map and cache
cit->second->first = time(NULL);
@@ -129,7 +130,7 @@ template<typename c_Key, typename c_Data> bool TaggedCache<c_Key, c_Data>::del(c
{ // Remove from cache, map unaffected
boost::recursive_mutex::scoped_lock sl(mLock);
typename std::map<key_type, cache_entry>::iterator cit = mCache.find(key);
typename boost::unordered_map<key_type, cache_entry>::iterator cit = mCache.find(key);
if (cit == mCache.end()) return false;
mCache.erase(cit);
return true;
@@ -141,7 +142,7 @@ bool TaggedCache<c_Key, c_Data>::canonicalize(const key_type& key, boost::shared
// Return values: true=we had the data already
boost::recursive_mutex::scoped_lock sl(mLock);
typename std::map<key_type, weak_data_ptr>::iterator mit = mMap.find(key);
typename boost::unordered_map<key_type, weak_data_ptr>::iterator mit = mMap.find(key);
if (mit == mMap.end())
{ // not in map
mCache.insert(std::make_pair(key, std::make_pair(time(NULL), data)));
@@ -159,7 +160,7 @@ bool TaggedCache<c_Key, c_Data>::canonicalize(const key_type& key, boost::shared
assert(!!data);
// Valid in map, is it in cache?
typename std::map<key_type, cache_entry>::iterator cit = mCache.find(key);
typename boost::unordered_map<key_type, cache_entry>::iterator cit = mCache.find(key);
if (cit != mCache.end())
cit->second.first = time(NULL); // Yes, refesh
else // no, add to cache
@@ -174,7 +175,7 @@ boost::shared_ptr<c_Data> TaggedCache<c_Key, c_Data>::fetch(const key_type& key)
boost::recursive_mutex::scoped_lock sl(mLock);
// Is it in the map?
typename std::map<key_type, weak_data_ptr>::iterator mit = mMap.find(key);
typename boost::unordered_map<key_type, weak_data_ptr>::iterator mit = mMap.find(key);
if (mit == mMap.end()) return data_ptr(); // No, we're done
if (mit->second.expired())
{ // in map, but expired
@@ -185,7 +186,7 @@ boost::shared_ptr<c_Data> TaggedCache<c_Key, c_Data>::fetch(const key_type& key)
boost::shared_ptr<c_Data> data = mit->second.lock();
// Valid in map, is it in the cache?
typename std::map<key_type, cache_entry>::iterator cit = mCache.find(key);
typename boost::unordered_map<key_type, cache_entry>::iterator cit = mCache.find(key);
if (cit != mCache.end())
cit->second.first = time(NULL); // Yes, refresh
else // No, add to cache

View File

@@ -11,6 +11,7 @@
#include "BitcoinUtil.h"
#include "Serializer.h"
#include "SerializedTransaction.h"
#include "Log.h"
Transaction::Transaction(const SerializedTransaction::pointer sit, bool bValidate)
: mInLedger(0), mStatus(INVALID), mTransaction(sit)
@@ -43,6 +44,7 @@ Transaction::pointer Transaction::sharedTransaction(const std::vector<unsigned c
}
catch (...)
{
Log(lsWARNING) << "Exception constructing transaction";
return boost::shared_ptr<Transaction>();
}
}
@@ -66,8 +68,8 @@ Transaction::Transaction(
mTransaction = boost::make_shared<SerializedTransaction>(ttKind);
std::cerr << str(boost::format("Transaction: account: %s") % naSourceAccount.humanAccountID()) << std::endl;
std::cerr << str(boost::format("Transaction: mAccountFrom: %s") % mAccountFrom.humanAccountID()) << std::endl;
Log(lsINFO) << str(boost::format("Transaction: account: %s") % naSourceAccount.humanAccountID());
Log(lsINFO) << str(boost::format("Transaction: mAccountFrom: %s") % mAccountFrom.humanAccountID());
mTransaction->setSigningPubKey(mFromPubKey);
mTransaction->setSourceAccount(mAccountFrom);
mTransaction->setSequence(uSeq);
@@ -86,16 +88,12 @@ bool Transaction::sign(const NewcoinAddress& naAccountPrivate)
if (!naAccountPrivate.isValid())
{
#ifdef DEBUG
std::cerr << "No private key for signing" << std::endl;
#endif
Log(lsWARNING) << "No private key for signing";
bResult = false;
}
else if (!getSTransaction()->sign(naAccountPrivate))
{
#ifdef DEBUG
std::cerr << "Failed to make signature" << std::endl;
#endif
Log(lsWARNING) << "Failed to make signature";
assert(false);
bResult = false;
}

View File

@@ -291,6 +291,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
std::cerr << "applyTransaction>" << std::endl;
mLedger = mDefaultLedger;
assert(mLedger);
if (mAlternateLedger && (targetLedger != 0) &&
(targetLedger != mLedger->getLedgerSeq()) && (targetLedger == mAlternateLedger->getLedgerSeq()))
{

View File

@@ -13,6 +13,8 @@
#include <cstring>
#include <cassert>
#include <boost/functional/hash.hpp>
#include "types.h"
#include "utils.h"
@@ -136,6 +138,13 @@ public:
return ret;
}
std::size_t hash_combine(std::size_t& seed) const
{
for (int i = 0; i < WIDTH; ++i)
boost::hash_combine(seed, pn[i]);
return seed;
}
friend inline int compare(const base_uint& a, const base_uint& b)
{
const unsigned char* pA = a.begin();