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

This commit is contained in:
Arthur Britto
2012-05-07 18:39:32 -07:00
8 changed files with 231 additions and 183 deletions

View File

@@ -7,6 +7,7 @@
#include "Application.h" #include "Application.h"
#include "Ledger.h" #include "Ledger.h"
#include "utils.h"
#include "../obj/src/newcoin.pb.h" #include "../obj/src/newcoin.pb.h"
#include "PackedMessage.h" #include "PackedMessage.h"
#include "Config.h" #include "Config.h"
@@ -50,9 +51,7 @@ Ledger::Ledger(Ledger::pointer prevLedger) : mParentHash(prevLedger->getHash()),
prevLedger->setClosed(); prevLedger->setClosed();
prevLedger->updateHash(); prevLedger->updateHash();
mAccountStateMap->setSeq(mLedgerSeq); mAccountStateMap->setSeq(mLedgerSeq);
if (prevLedger->mTimeStamp == 0) mTimeStamp = prevLedger->getNextLedgerClose();
mTimeStamp = (theApp->getOPs().getNetworkTime() % mLedgerInterval) + mLedgerInterval;
else mTimeStamp = prevLedger->mTimeStamp + prevLedger->mLedgerInterval;
} }
Ledger::Ledger(const std::vector<unsigned char>& rawLedger) : mTotCoins(0), mTimeStamp(0), Ledger::Ledger(const std::vector<unsigned char>& rawLedger) : mTotCoins(0), mTimeStamp(0),
@@ -426,4 +425,22 @@ bool Ledger::isAcquiringAS(void)
{ {
return mAccountStateMap->isSynching(); return mAccountStateMap->isSynching();
} }
boost::posix_time::ptime Ledger::getCloseTime() const
{
return ptFromSeconds(mTimeStamp);
}
void Ledger::setCloseTime(boost::posix_time::ptime ptm)
{
mTimeStamp = iToSeconds(ptm);
}
uint64 Ledger::getNextLedgerClose() const
{
if (mTimeStamp == 0)
return theApp->getOPs().getNetworkTimeNC() + 2 * mLedgerInterval - 1;
return mTimeStamp + mLedgerInterval;
}
// vim:ts=4 // vim:ts=4

View File

@@ -6,6 +6,7 @@
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp> #include <boost/enable_shared_from_this.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include "../json/value.h" #include "../json/value.h"
@@ -56,7 +57,8 @@ public:
private: private:
uint256 mHash, mParentHash, mTransHash, mAccountHash; uint256 mHash, mParentHash, mTransHash, mAccountHash;
uint64 mTotCoins, mTimeStamp; uint64 mTotCoins;
uint64 mTimeStamp; // when this ledger closes
uint32 mLedgerSeq; uint32 mLedgerSeq;
uint16 mLedgerInterval; uint16 mLedgerInterval;
bool mClosed, mValidHash, mAccepted, mImmutable; bool mClosed, mValidHash, mAccepted, mImmutable;
@@ -81,7 +83,7 @@ protected:
public: public:
Ledger(const NewcoinAddress& masterID, uint64 startAmount); // used for the starting bootstrap ledger Ledger(const NewcoinAddress& masterID, uint64 startAmount); // used for the starting bootstrap ledger
Ledger(const uint256 &parentHash, const uint256 &transHash, const uint256 &accountHash, Ledger(const uint256 &parentHash, const uint256 &transHash, const uint256 &accountHash,
uint64 totCoins, uint64 timeStamp, uint32 ledgerSeq); // used for received ledgers uint64 totCoins, uint64 timeStamp, uint32 ledgerSeq); // used for database ledgers
Ledger(const std::vector<unsigned char>& rawLedger); Ledger(const std::vector<unsigned char>& rawLedger);
Ledger(const std::string& rawLedger); Ledger(const std::string& rawLedger);
Ledger(Ledger::pointer previous); // ledger after this one Ledger(Ledger::pointer previous); // ledger after this one
@@ -100,10 +102,15 @@ public:
const uint256& getTransHash() const { return mTransHash; } const uint256& getTransHash() const { return mTransHash; }
const uint256& getAccountHash() const { return mAccountHash; } const uint256& getAccountHash() const { return mAccountHash; }
uint64 getTotalCoins() const { return mTotCoins; } uint64 getTotalCoins() const { return mTotCoins; }
uint64 getTimeStamp() const { return mTimeStamp; } uint64 getRawTimeStamp() const { return mTimeStamp; }
uint32 getLedgerSeq() const { return mLedgerSeq; } uint32 getLedgerSeq() const { return mLedgerSeq; }
uint16 getInterval() const { return mLedgerInterval; } uint16 getInterval() const { return mLedgerInterval; }
// close time functions
boost::posix_time::ptime getCloseTime() const;
void setCloseTime(boost::posix_time::ptime);
uint64 getNextLedgerClose() const;
// low level functions // low level functions
SHAMap::pointer peekTransactionMap() { return mTransactionMap; } SHAMap::pointer peekTransactionMap() { return mTransactionMap; }
SHAMap::pointer peekAccountStateMap() { return mAccountStateMap; } SHAMap::pointer peekAccountStateMap() { return mAccountStateMap; }

View File

@@ -4,6 +4,7 @@
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include "utils.h"
#include "Application.h" #include "Application.h"
#include "Transaction.h" #include "Transaction.h"
@@ -24,11 +25,21 @@ NetworkOPs::NetworkOPs(boost::asio::io_service& io_service) : mMode(omDISCONNECT
setStateTimer(5); setStateTimer(5);
} }
uint64 NetworkOPs::getNetworkTime() time_t NetworkOPs::getNetworkTimeTT()
{ {
return time(NULL); return time(NULL);
} }
boost::posix_time::ptime NetworkOPs::getNetworkTimePT()
{
return boost::posix_time::from_time_t(getNetworkTimeTT());
}
uint64 NetworkOPs::getNetworkTimeNC()
{
return iToSeconds(getNetworkTimePT());
}
uint32 NetworkOPs::getCurrentLedgerID() uint32 NetworkOPs::getCurrentLedgerID()
{ {
return theApp->getMasterLedger().getCurrentLedger()->getLedgerSeq(); return theApp->getMasterLedger().getCurrentLedger()->getLedgerSeq();
@@ -89,7 +100,7 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans,
trans->getSTransaction()->getTransaction(*s, false); trans->getSTransaction()->getTransaction(*s, false);
tx->set_rawtransaction(&s->getData().front(), s->getLength()); tx->set_rawtransaction(&s->getData().front(), s->getLength());
tx->set_status(newcoin::tsCURRENT); tx->set_status(newcoin::tsCURRENT);
tx->set_receivetimestamp(getNetworkTime()); tx->set_receivetimestamp(getNetworkTimeNC());
tx->set_ledgerindexpossible(trans->getLedger()); tx->set_ledgerindexpossible(trans->getLedger());
PackedMessage::pointer packet(new PackedMessage(PackedMessage::MessagePointer(tx), newcoin::mtTRANSACTION)); PackedMessage::pointer packet(new PackedMessage(PackedMessage::MessagePointer(tx), newcoin::mtTRANSACTION));
@@ -280,8 +291,19 @@ void NetworkOPs::checkState()
void NetworkOPs::switchLastClosedLedger(Ledger::pointer newLedger) void NetworkOPs::switchLastClosedLedger(Ledger::pointer newLedger)
{ // set the newledger as our last closed ledger { // set the newledger as our last closed ledger
// FIXME: Must recover transactions // FIXME: Correct logic is:
// 1) Mark this ledger closed, schedule it to be saved
// 2) Open a new subsequent ledger
// 3) Walk back the previous ledger chain from our current ledger and the new last closed ledger
// find a common previous ledger, if possible. Try to insert any transactions in our ledger
// chain into the new open ledger. Broadcast any that make it in.
Ledger::pointer openLedger = boost::make_shared<Ledger>(newLedger); Ledger::pointer openLedger = boost::make_shared<Ledger>(newLedger);
theApp->getMasterLedger().switchLedgers(newLedger, openLedger); theApp->getMasterLedger().switchLedgers(newLedger, openLedger);
// FIXME: Set close timer
#if 0
if (getNetworkTime() > openLedger->getCloseTime())
{ // this ledger has already closed
}
#endif
} }

View File

@@ -37,7 +37,9 @@ public:
NetworkOPs(boost::asio::io_service& io_service); NetworkOPs(boost::asio::io_service& io_service);
// network information // network information
uint64 getNetworkTime(); uint64 getNetworkTimeNC();
time_t getNetworkTimeTT();
boost::posix_time::ptime getNetworkTimePT();
uint32 getCurrentLedgerID(); uint32 getCurrentLedgerID();
OperatingMode getOperatingMode() { return mMode; } OperatingMode getOperatingMode() { return mMode; }

View File

@@ -774,7 +774,7 @@ void Peer::sendHello()
h->set_version(theConfig.VERSION); h->set_version(theConfig.VERSION);
h->set_ledgerindex(theApp->getOPs().getCurrentLedgerID()); h->set_ledgerindex(theApp->getOPs().getCurrentLedgerID());
h->set_nettime(theApp->getOPs().getNetworkTime()); h->set_nettime(theApp->getOPs().getNetworkTimeNC());
h->set_nodepublic(theApp->getWallet().getNodePublic().humanNodePublic()); h->set_nodepublic(theApp->getWallet().getNodePublic().humanNodePublic());
h->set_nodeproof(&vchSig[0], vchSig.size()); h->set_nodeproof(&vchSig[0], vchSig.size());
h->set_ipv4port(theConfig.PEER_PORT); h->set_ipv4port(theConfig.PEER_PORT);

View File

@@ -11,9 +11,9 @@
SHAMap::SHAMap(uint32 seq) : mSeq(seq), mState(Modifying) SHAMap::SHAMap(uint32 seq) : mSeq(seq), mState(Modifying)
{ {
root=boost::make_shared<SHAMapTreeNode>(SHAMapNode(0, uint256()), mSeq); root = boost::make_shared<SHAMapTreeNode>(SHAMapNode(0, uint256()), mSeq);
root->makeInner(); root->makeInner();
mTNByID[*root]=root; mTNByID[*root] = root;
} }
std::stack<SHAMapTreeNode::pointer> SHAMap::getStack(const uint256& id, bool include_nonmatching_leaf) std::stack<SHAMapTreeNode::pointer> SHAMap::getStack(const uint256& id, bool include_nonmatching_leaf)
@@ -21,27 +21,27 @@ std::stack<SHAMapTreeNode::pointer> SHAMap::getStack(const uint256& id, bool inc
// Walk the tree as far as possible to the specified identifier // Walk the tree as far as possible to the specified identifier
// produce a stack of nodes along the way, with the terminal node at the top // produce a stack of nodes along the way, with the terminal node at the top
std::stack<SHAMapTreeNode::pointer> stack; std::stack<SHAMapTreeNode::pointer> stack;
SHAMapTreeNode::pointer node=root; SHAMapTreeNode::pointer node = root;
while(!node->isLeaf()) while (!node->isLeaf())
{ {
stack.push(node); stack.push(node);
int branch=node->selectBranch(id); int branch = node->selectBranch(id);
assert(branch>=0); assert(branch >= 0);
uint256 hash=node->getChildHash(branch); uint256 hash = node->getChildHash(branch);
if(hash.isZero()) return stack; if (hash.isZero()) return stack;
node=getNode(node->getChildNodeID(branch), hash, false); node = getNode(node->getChildNodeID(branch), hash, false);
if(!node) if (!node)
{ {
if(isSynching()) return stack; if (isSynching()) return stack;
throw SHAMapException(MissingNode); throw SHAMapException(MissingNode);
} }
} }
if(include_nonmatching_leaf || (node->peekItem()->getTag()==id)) if (include_nonmatching_leaf || (node->peekItem()->getTag() == id))
stack.push(node); stack.push(node);
return stack; return stack;
@@ -51,20 +51,20 @@ void SHAMap::dirtyUp(std::stack<SHAMapTreeNode::pointer>& stack, const uint256&
{ // walk the tree up from through the inner nodes to the root { // walk the tree up from through the inner nodes to the root
// update linking hashes and add nodes to dirty list // update linking hashes and add nodes to dirty list
assert(mState!=Synching && mState!=Immutable); assert((mState != Synching) && (mState != Immutable));
while(!stack.empty()) while (!stack.empty())
{ {
SHAMapTreeNode::pointer node=stack.top(); SHAMapTreeNode::pointer node=stack.top();
stack.pop(); stack.pop();
assert(node->isInnerNode()); assert(node->isInnerNode());
int branch=node->selectBranch(target); int branch = node->selectBranch(target);
assert(branch>=0); assert(branch >= 0);
returnNode(node, true); returnNode(node, true);
if(!node->setChildHash(branch, prevHash)) if (!node->setChildHash(branch, prevHash))
{ {
std::cerr << "dirtyUp terminates early" << std::endl; std::cerr << "dirtyUp terminates early" << std::endl;
assert(false); assert(false);
@@ -73,15 +73,15 @@ void SHAMap::dirtyUp(std::stack<SHAMapTreeNode::pointer>& stack, const uint256&
#ifdef ST_DEBUG #ifdef ST_DEBUG
std::cerr << "dirtyUp sets branch " << branch << " to " << prevHash.GetHex() << std::endl; std::cerr << "dirtyUp sets branch " << branch << " to " << prevHash.GetHex() << std::endl;
#endif #endif
prevHash=node->getNodeHash(); prevHash = node->getNodeHash();
assert(prevHash.isNonZero()); assert(prevHash.isNonZero());
} }
} }
SHAMapTreeNode::pointer SHAMap::checkCacheNode(const SHAMapNode& iNode) SHAMapTreeNode::pointer SHAMap::checkCacheNode(const SHAMapNode& iNode)
{ {
boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer>::iterator it=mTNByID.find(iNode); boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer>::iterator it = mTNByID.find(iNode);
if(it==mTNByID.end()) return SHAMapTreeNode::pointer(); if (it == mTNByID.end()) return SHAMapTreeNode::pointer();
return it->second; return it->second;
} }
@@ -90,27 +90,27 @@ SHAMapTreeNode::pointer SHAMap::walkTo(const uint256& id, bool modify)
SHAMapTreeNode::pointer inNode=root; SHAMapTreeNode::pointer inNode=root;
while(!inNode->isLeaf()) while (!inNode->isLeaf())
{ {
int branch=inNode->selectBranch(id); int branch = inNode->selectBranch(id);
if(inNode->isEmptyBranch(branch)) return inNode; if (inNode->isEmptyBranch(branch)) return inNode;
uint256 childHash=inNode->getChildHash(branch); uint256 childHash = inNode->getChildHash(branch);
if(childHash.isZero()) return inNode; if (childHash.isZero()) return inNode;
SHAMapTreeNode::pointer nextNode=getNode(inNode->getChildNodeID(branch), childHash, false); SHAMapTreeNode::pointer nextNode = getNode(inNode->getChildNodeID(branch), childHash, false);
if(!nextNode) throw SHAMapException(MissingNode); if (!nextNode) throw SHAMapException(MissingNode);
inNode=nextNode; inNode = nextNode;
} }
if(modify) returnNode(inNode, true); if (modify) returnNode(inNode, true);
return inNode; return inNode;
} }
SHAMapTreeNode::pointer SHAMap::getNode(const SHAMapNode& id, const uint256& hash, bool modify) SHAMapTreeNode::pointer SHAMap::getNode(const SHAMapNode& id, const uint256& hash, bool modify)
{ // retrieve a node whose node hash is known { // retrieve a node whose node hash is known
SHAMapTreeNode::pointer node=checkCacheNode(id); SHAMapTreeNode::pointer node = checkCacheNode(id);
if(node) if (node)
{ {
if(node->getNodeHash()!=hash) if (node->getNodeHash()!=hash)
{ {
#ifdef DEBUG #ifdef DEBUG
std::cerr << "Attempt to get node, hash not in tree" << std::endl; std::cerr << "Attempt to get node, hash not in tree" << std::endl;
@@ -128,10 +128,10 @@ SHAMapTreeNode::pointer SHAMap::getNode(const SHAMapNode& id, const uint256& has
std::vector<unsigned char> nodeData; std::vector<unsigned char> nodeData;
if(!fetchNode(hash, nodeData)) return SHAMapTreeNode::pointer(); if(!fetchNode(hash, nodeData)) return SHAMapTreeNode::pointer();
node=boost::make_shared<SHAMapTreeNode>(id, nodeData, mSeq); node = boost::make_shared<SHAMapTreeNode>(id, nodeData, mSeq);
if(node->getNodeHash()!=hash) throw SHAMapException(InvalidNode); if (node->getNodeHash() != hash) throw SHAMapException(InvalidNode);
if(!mTNByID.insert(std::make_pair(id, node)).second) if (!mTNByID.insert(std::make_pair(id, node)).second)
assert(false); assert(false);
return node; return node;
} }
@@ -139,15 +139,15 @@ SHAMapTreeNode::pointer SHAMap::getNode(const SHAMapNode& id, const uint256& has
void SHAMap::returnNode(SHAMapTreeNode::pointer& node, bool modify) void SHAMap::returnNode(SHAMapTreeNode::pointer& node, bool modify)
{ // make sure the node is suitable for the intended operation (copy on write) { // make sure the node is suitable for the intended operation (copy on write)
assert(node->isValid()); assert(node->isValid());
if(node && modify && (node->getSeq()!=mSeq)) if (node && modify && (node->getSeq()!=mSeq))
{ {
#ifdef DEBUG #ifdef DEBUG
std::cerr << "returnNode COW" << std::endl; std::cerr << "returnNode COW" << std::endl;
#endif #endif
if(mDirtyNodes) (*mDirtyNodes)[*node]=node; if (mDirtyNodes) (*mDirtyNodes)[*node] = node;
node=boost::make_shared<SHAMapTreeNode>(*node, mSeq); node = boost::make_shared<SHAMapTreeNode>(*node, mSeq);
assert(node->isValid()); assert(node->isValid());
mTNByID[*node]=node; mTNByID[*node] = node;
} }
} }
@@ -163,24 +163,24 @@ SHAMapItem::pointer SHAMap::firstBelow(SHAMapTreeNode::pointer node)
#endif #endif
do do
{ // Walk down the tree { // Walk down the tree
if(node->hasItem()) return node->peekItem(); if (node->hasItem()) return node->peekItem();
bool foundNode=false; bool foundNode = false;
for(int i=0; i<16; i++) for (int i = 0; i < 16; ++i)
if(!node->isEmptyBranch(i)) if (!node->isEmptyBranch(i))
{ {
#ifdef ST_DEBUG #ifdef ST_DEBUG
std::cerr << " FB: node " << node->getString() << std::endl; std::cerr << " FB: node " << node->getString() << std::endl;
std::cerr << " has non-empty branch " << i << " : " << std::cerr << " has non-empty branch " << i << " : " <<
node->getChildNodeID(i).getString() << ", " << node->getChildHash(i).GetHex() << std::endl; node->getChildNodeID(i).getString() << ", " << node->getChildHash(i).GetHex() << std::endl;
#endif #endif
node=getNode(node->getChildNodeID(i), node->getChildHash(i), false); node = getNode(node->getChildNodeID(i), node->getChildHash(i), false);
if(!node) throw SHAMapException(MissingNode); if (!node) throw SHAMapException(MissingNode);
foundNode=true; foundNode = true;
break; break;
} }
if(!foundNode) return SHAMapItem::pointer(); if (!foundNode) return SHAMapItem::pointer();
} while(1); } while (1);
} }
SHAMapItem::pointer SHAMap::lastBelow(SHAMapTreeNode::pointer node) SHAMapItem::pointer SHAMap::lastBelow(SHAMapTreeNode::pointer node)
@@ -191,46 +191,46 @@ SHAMapItem::pointer SHAMap::lastBelow(SHAMapTreeNode::pointer node)
do do
{ // Walk down the tree { // Walk down the tree
if(node->hasItem()) return node->peekItem(); if (node->hasItem()) return node->peekItem();
bool foundNode=false; bool foundNode = false;
for(int i=15; i>=0; i++) for (int i = 15; i >= 0; ++i)
if(!node->isEmptyBranch(i)) if (!node->isEmptyBranch(i))
{ {
node=getNode(node->getChildNodeID(i), node->getChildHash(i), false); node = getNode(node->getChildNodeID(i), node->getChildHash(i), false);
if(!node) throw SHAMapException(MissingNode); if (!node) throw SHAMapException(MissingNode);
foundNode=true; foundNode = true;
break; break;
} }
if(!foundNode) return SHAMapItem::pointer(); if (!foundNode) return SHAMapItem::pointer();
} while(1); } while (1);
} }
SHAMapItem::pointer SHAMap::onlyBelow(SHAMapTreeNode::pointer node) SHAMapItem::pointer SHAMap::onlyBelow(SHAMapTreeNode::pointer node)
{ {
// If there is only one item below this node, return it // If there is only one item below this node, return it
bool found; bool found;
while(!node->isLeaf()) while (!node->isLeaf())
{ {
found=false; found = false;
SHAMapTreeNode::pointer nextNode; SHAMapTreeNode::pointer nextNode;
for(int i=0; i<16; i++) for (int i = 0; i < 16; ++i)
if(!node->isEmptyBranch(i)) if (!node->isEmptyBranch(i))
{ {
if(found) return SHAMapItem::pointer(); // two leaves below if( found) return SHAMapItem::pointer(); // two leaves below
nextNode=getNode(node->getChildNodeID(i), node->getChildHash(i), false); nextNode = getNode(node->getChildNodeID(i), node->getChildHash(i), false);
if(!nextNode) throw SHAMapException(MissingNode); if (!nextNode) throw SHAMapException(MissingNode);
found=true; found = true;
} }
if(!found) if (!found)
{ {
std::cerr << node->getString() << std::endl; std::cerr << node->getString() << std::endl;
assert(false); assert(false);
return SHAMapItem::pointer(); return SHAMapItem::pointer();
} }
node=nextNode; node = nextNode;
} }
assert(node->hasItem()); assert(node->hasItem());
return node->peekItem(); return node->peekItem();
@@ -618,11 +618,11 @@ void SHAMap::dump(bool hash)
} }
static std::vector<unsigned char>IntToVUC(int i) static std::vector<unsigned char>IntToVUC(int v)
{ {
std::vector<unsigned char> vuc; std::vector<unsigned char> vuc;
for(int i=0; i<32; i++) for (int i = 0; i < 32; ++i)
vuc.push_back((unsigned char) i); vuc.push_back(static_cast<unsigned char>(v));
return vuc; return vuc;
} }

View File

@@ -40,14 +40,14 @@ public:
SHAMapNode(int depth, const uint256& hash); SHAMapNode(int depth, const uint256& hash);
int getDepth() const { return mDepth; } int getDepth() const { return mDepth; }
const uint256& getNodeID() const { return mNodeID; } const uint256& getNodeID() const { return mNodeID; }
bool isValid() const { return (mDepth>=0) && (mDepth<64); } bool isValid() const { return (mDepth >= 0) && (mDepth < 64); }
virtual bool isPopulated() const { return false; } virtual bool isPopulated() const { return false; }
SHAMapNode getParentNodeID() const SHAMapNode getParentNodeID() const
{ {
assert(mDepth); assert(mDepth);
return SHAMapNode(mDepth-1, mNodeID); return SHAMapNode(mDepth - 1, mNodeID);
} }
SHAMapNode getChildNodeID(int m) const; SHAMapNode getChildNodeID(int m) const;
int selectBranch(const uint256& hash) const; int selectBranch(const uint256& hash) const;
@@ -108,18 +108,18 @@ public:
void updateData(const std::vector<unsigned char>& data) { mData=data; } void updateData(const std::vector<unsigned char>& data) { mData=data; }
bool operator<(const SHAMapItem& i) const { return mTag<i.mTag; } bool operator<(const SHAMapItem& i) const { return mTag < i.mTag; }
bool operator>(const SHAMapItem& i) const { return mTag>i.mTag; } bool operator>(const SHAMapItem& i) const { return mTag > i.mTag; }
bool operator==(const SHAMapItem& i) const { return mTag==i.mTag; } bool operator==(const SHAMapItem& i) const { return mTag == i.mTag; }
bool operator!=(const SHAMapItem& i) const { return mTag!=i.mTag; } bool operator!=(const SHAMapItem& i) const { return mTag != i.mTag; }
bool operator<=(const SHAMapItem& i) const { return mTag<=i.mTag; } bool operator<=(const SHAMapItem& i) const { return mTag <= i.mTag; }
bool operator>=(const SHAMapItem& i) const { return mTag>=i.mTag; } bool operator>=(const SHAMapItem& i) const { return mTag >= i.mTag; }
bool operator<(const uint256& i) const { return mTag<i; } bool operator<(const uint256& i) const { return mTag < i; }
bool operator>(const uint256& i) const { return mTag>i; } bool operator>(const uint256& i) const { return mTag > i; }
bool operator==(const uint256& i) const { return mTag==i; } bool operator==(const uint256& i) const { return mTag == i; }
bool operator!=(const uint256& i) const { return mTag!=i; } bool operator!=(const uint256& i) const { return mTag != i; }
bool operator<=(const uint256& i) const { return mTag<=i; } bool operator<=(const uint256& i) const { return mTag <= i; }
bool operator>=(const uint256& i) const { return mTag>=i; } bool operator>=(const uint256& i) const { return mTag >= i; }
virtual void dump(); virtual void dump();
}; };
@@ -132,10 +132,10 @@ public:
enum TNType enum TNType
{ {
tnERROR =0, tnERROR = 0,
tnINNER =1, tnINNER = 1,
tnTRANSACTION =2, tnTRANSACTION = 2,
tnACCOUNT_STATE =3 tnACCOUNT_STATE = 3
}; };
private: private:
@@ -295,7 +295,7 @@ public:
// status functions // status functions
void setImmutable(void) { assert(mState != Invalid); mState = Immutable; } void setImmutable(void) { assert(mState != Invalid); mState = Immutable; }
void clearImmutable(void) { mState = Modifying; } void clearImmutable(void) { mState = Modifying; }
bool isSynching(void) const { return mState == Floating || mState == Synching; } bool isSynching(void) const { return (mState == Floating) || (mState == Synching); }
void setSynching(void) { mState = Synching; } void setSynching(void) { mState = Synching; }
void setFloating(void) { mState = Floating; } void setFloating(void) { mState = Floating; }
void clearSynching(void) { mState = Modifying; } void clearSynching(void) { mState = Modifying; }

View File

@@ -97,11 +97,11 @@ SHAMapNode::SHAMapNode(int depth, const uint256 &hash) : mDepth(depth)
SHAMapNode::SHAMapNode(const void *ptr, int len) SHAMapNode::SHAMapNode(const void *ptr, int len)
{ {
if(len<33) mDepth=-1; if (len < 33) mDepth = -1;
else else
{ {
memcpy(&mNodeID, ptr, 32); memcpy(&mNodeID, ptr, 32);
mDepth=*(static_cast<const unsigned char *>(ptr) + 32); mDepth = *(static_cast<const unsigned char *>(ptr) + 32);
} }
} }
@@ -120,21 +120,21 @@ std::string SHAMapNode::getRawString() const
SHAMapNode SHAMapNode::getChildNodeID(int m) const SHAMapNode SHAMapNode::getChildNodeID(int m) const
{ // This can be optimized to avoid the << if needed { // This can be optimized to avoid the << if needed
assert((m>=0) && (m<16)); assert((m >= 0) && (m < 16));
uint256 child(mNodeID); uint256 child(mNodeID);
child.PeekAt(mDepth/8) |= m << (4*(mDepth%8)); child.PeekAt(mDepth / 8) |= m << (4 * (mDepth % 8));
return SHAMapNode(mDepth+1, child); return SHAMapNode(mDepth + 1, child);
} }
int SHAMapNode::selectBranch(const uint256& hash) const int SHAMapNode::selectBranch(const uint256& hash) const
{ // Which branch would contain the specified hash { // Which branch would contain the specified hash
if(mDepth==63) if (mDepth == 63)
{ {
assert(false); assert(false);
return -1; return -1;
} }
if((hash&smMasks[mDepth])!=mNodeID) if ((hash & smMasks[mDepth]) != mNodeID)
{ {
std::cerr << "selectBranch(" << getString() << std::endl; std::cerr << "selectBranch(" << getString() << std::endl;
std::cerr << " " << hash.GetHex() << " off branch" << std::endl; std::cerr << " " << hash.GetHex() << " off branch" << std::endl;
@@ -142,11 +142,11 @@ int SHAMapNode::selectBranch(const uint256& hash) const
return -1; // does not go under this node return -1; // does not go under this node
} }
int branch=*(hash.begin()+(mDepth/2)); int branch = *(hash.begin() + (mDepth / 2));
if(mDepth%2) branch>>=4; if (mDepth % 2) branch >>= 4;
else branch&=0xf; else branch &= 0xf;
assert(branch>=0 && branch<16); assert((branch >= 0) && (branch < 16));
return branch; return branch;
} }
@@ -164,7 +164,7 @@ SHAMapTreeNode::SHAMapTreeNode(const SHAMapTreeNode& node, uint32 seq) : SHAMapN
mHash(node.mHash), mItem(node.mItem), mSeq(seq), mType(node.mType), mFullBelow(false) mHash(node.mHash), mItem(node.mItem), mSeq(seq), mType(node.mType), mFullBelow(false)
{ {
if(node.mItem) if(node.mItem)
mItem=boost::make_shared<SHAMapItem>(*node.mItem); mItem = boost::make_shared<SHAMapItem>(*node.mItem);
else else
memcpy(mHashes, node.mHashes, sizeof(mHashes)); memcpy(mHashes, node.mHashes, sizeof(mHashes));
} }
@@ -172,7 +172,7 @@ SHAMapTreeNode::SHAMapTreeNode(const SHAMapTreeNode& node, uint32 seq) : SHAMapN
SHAMapTreeNode::SHAMapTreeNode(const SHAMapNode& node, SHAMapItem::pointer item, TNType type, uint32 seq) : SHAMapTreeNode::SHAMapTreeNode(const SHAMapNode& node, SHAMapItem::pointer item, TNType type, uint32 seq) :
SHAMapNode(node), mItem(item), mSeq(seq), mType(type), mFullBelow(true) SHAMapNode(node), mItem(item), mSeq(seq), mType(type), mFullBelow(true)
{ {
assert(item->peekData().size()>=12); assert(item->peekData().size() >= 12);
updateHash(); updateHash();
} }
@@ -181,41 +181,41 @@ SHAMapTreeNode::SHAMapTreeNode(const SHAMapNode& id, const std::vector<unsigned
{ {
Serializer s(rawNode); Serializer s(rawNode);
int type=s.removeLastByte(); int type = s.removeLastByte();
int len=s.getLength(); int len = s.getLength();
if( (type<0) || (type>3) || (len<32) ) throw SHAMapException(InvalidNode); if ((type < 0) || (type > 3) || (len < 32)) throw SHAMapException(InvalidNode);
if(type==0) if (type == 0)
{ // transaction { // transaction
mItem=boost::make_shared<SHAMapItem>(s.getSHA512Half(), s.peekData()); mItem = boost::make_shared<SHAMapItem>(s.getSHA512Half(), s.peekData());
mType=tnTRANSACTION; mType = tnTRANSACTION;
} }
else if(type==1) else if (type == 1)
{ // account state { // account state
uint256 u; uint256 u;
s.get256(u, len-32); s.get256(u, len - 32);
s.chop(256/8); s.chop(256 / 8);
if(u.isZero()) throw SHAMapException(InvalidNode); if (u.isZero()) throw SHAMapException(InvalidNode);
mItem=boost::make_shared<SHAMapItem>(u, s.peekData()); mItem = boost::make_shared<SHAMapItem>(u, s.peekData());
mType=tnACCOUNT_STATE; mType = tnACCOUNT_STATE;
} }
else if(type==2) else if (type == 2)
{ // full inner { // full inner
if(len!=512) throw SHAMapException(InvalidNode); if (len != 512) throw SHAMapException(InvalidNode);
for(int i=0; i<16; i++) for (int i = 0; i < 16; ++i)
s.get256(mHashes[i], i*32); s.get256(mHashes[i], i * 32);
mType=tnINNER; mType = tnINNER;
} }
else if(type==3) else if (type == 3)
{ // compressed inner { // compressed inner
for(int i=0; i<(len/33); i++) for (int i = 0; i < (len / 33); ++i)
{ {
int pos; int pos;
s.get8(pos, 32+(i*33)); s.get8(pos, 32 + (i * 33));
if( (pos<0) || (pos>=16)) throw SHAMapException(InvalidNode); if ((pos < 0) || (pos >= 16)) throw SHAMapException(InvalidNode);
s.get256(mHashes[pos], i*33); s.get256(mHashes[pos], i* 3 3);
} }
mType=tnINNER; mType = tnINNER;
} }
updateHash(); updateHash();
@@ -223,17 +223,17 @@ SHAMapTreeNode::SHAMapTreeNode(const SHAMapNode& id, const std::vector<unsigned
void SHAMapTreeNode::addRaw(Serializer &s) void SHAMapTreeNode::addRaw(Serializer &s)
{ {
if(mType==tnERROR) throw SHAMapException(InvalidNode); if (mType == tnERROR) throw SHAMapException(InvalidNode);
if(mType==tnTRANSACTION) if (mType == tnTRANSACTION)
{ {
mItem->addRaw(s); mItem->addRaw(s);
s.add8(0); s.add8(0);
assert(s.getLength()>32); assert(s.getLength() > 32);
return; return;
} }
if(mType==tnACCOUNT_STATE) if (mType == tnACCOUNT_STATE)
{ {
mItem->addRaw(s); mItem->addRaw(s);
s.add256(mItem->getTag()); s.add256(mItem->getTag());
@@ -241,10 +241,10 @@ void SHAMapTreeNode::addRaw(Serializer &s)
return; return;
} }
if(getBranchCount()<12) if (getBranchCount() < 12)
{ // compressed node { // compressed node
for(int i=0; i<16; i++) for (int i = 0; i < 16; ++i)
if(mHashes[i].isNonZero()) if (mHashes[i].isNonZero())
{ {
s.add256(mHashes[i]); s.add256(mHashes[i]);
s.add8(i); s.add8(i);
@@ -253,7 +253,7 @@ void SHAMapTreeNode::addRaw(Serializer &s)
return; return;
} }
for(int i=0; i<16; i++) for (int i = 0; i < 16; ++i)
s.add256(mHashes[i]); s.add256(mHashes[i]);
s.add8(2); s.add8(2);
} }
@@ -262,44 +262,44 @@ bool SHAMapTreeNode::updateHash()
{ {
uint256 nh; uint256 nh;
if(mType==tnINNER) if (mType == tnINNER)
{ {
bool empty=true; bool empty = true;
for(int i=0; i<16; i++) for (int i = 0; i < 16; ++i)
if(mHashes[i].isNonZero()) if (mHashes[i].isNonZero())
{ {
empty=false; empty = false;
break; break;
} }
if(!empty) if(!empty)
nh=Serializer::getSHA512Half(reinterpret_cast<unsigned char *>(mHashes), sizeof(mHashes)); nh = Serializer::getSHA512Half(reinterpret_cast<unsigned char *>(mHashes), sizeof(mHashes));
} }
else if(mType==tnACCOUNT_STATE) else if (mType == tnACCOUNT_STATE)
{ {
Serializer s; Serializer s;
mItem->addRaw(s); mItem->addRaw(s);
s.add160(mItem->getTag().to160()); s.add160(mItem->getTag().to160());
nh=s.getSHA512Half(); nh = s.getSHA512Half();
} }
else if(mType==tnTRANSACTION) else if (mType == tnTRANSACTION)
{ {
nh=Serializer::getSHA512Half(mItem->peekData()); nh = Serializer::getSHA512Half(mItem->peekData());
} }
else assert(false); else assert(false);
if(nh==mHash) return false; if (nh == mHash) return false;
mHash=nh; mHash = nh;
return true; return true;
} }
bool SHAMapTreeNode::setItem(SHAMapItem::pointer& i, TNType type) bool SHAMapTreeNode::setItem(SHAMapItem::pointer& i, TNType type)
{ {
uint256 hash=getNodeHash(); uint256 hash = getNodeHash();
mType=type; mType = type;
mItem=i; mItem = i;
assert(isLeaf()); assert(isLeaf());
updateHash(); updateHash();
return getNodeHash()==hash; return getNodeHash() == hash;
} }
SHAMapItem::pointer SHAMapTreeNode::getItem() const SHAMapItem::pointer SHAMapTreeNode::getItem() const
@@ -311,17 +311,17 @@ SHAMapItem::pointer SHAMapTreeNode::getItem() const
int SHAMapTreeNode::getBranchCount() const int SHAMapTreeNode::getBranchCount() const
{ {
assert(isInner()); assert(isInner());
int ret=0; int ret = 0;
for(int i=0; i<16; ++i) for (int i = 0; i < 16; ++i)
if(mHashes[i].isNonZero()) ++ret; if (mHashes[i].isNonZero()) ++ret;
return ret; return ret;
} }
void SHAMapTreeNode::makeInner() void SHAMapTreeNode::makeInner()
{ {
mItem=SHAMapItem::pointer(); mItem = SHAMapItem::pointer();
memset(mHashes, 0, sizeof(mHashes)); memset(mHashes, 0, sizeof(mHashes));
mType=tnINNER; mType = tnINNER;
mHash.zero(); mHash.zero();
} }
@@ -332,40 +332,40 @@ void SHAMapTreeNode::dump()
std::string SHAMapTreeNode::getString() const std::string SHAMapTreeNode::getString() const
{ {
std::string ret="NodeID("; std::string ret = "NodeID(";
ret+=boost::lexical_cast<std::string>(getDepth()); ret += boost::lexical_cast<std::string>(getDepth());
ret+=","; ret += ",";
ret+=getNodeID().GetHex(); ret += getNodeID().GetHex();
ret+=")"; ret += ")";
if(isInner()) if (isInner())
{ {
for(int i=0; i<16; i++) for(int i = 0; i < 16; ++i)
if(!isEmptyBranch(i)) if (!isEmptyBranch(i))
{ {
ret+=",b"; ret += ",b";
ret+=boost::lexical_cast<std::string>(i); ret += boost::lexical_cast<std::string>(i);
} }
} }
if(isLeaf()) if (isLeaf())
{ {
ret+=",leaf"; ret += ",leaf";
} }
return ret; return ret;
} }
bool SHAMapTreeNode::setChildHash(int m, const uint256 &hash) bool SHAMapTreeNode::setChildHash(int m, const uint256 &hash)
{ {
assert( (m>=0) && (m<16) ); assert((m >= 0) && (m < 16));
assert(mType==tnINNER); assert(mType == tnINNER);
if(mHashes[m]==hash) if(mHashes[m] == hash)
return false; return false;
mHashes[m]=hash; mHashes[m] = hash;
return updateHash(); return updateHash();
} }
const uint256& SHAMapTreeNode::getChildHash(int m) const const uint256& SHAMapTreeNode::getChildHash(int m) const
{ {
assert( (m>=0) && (m<16) && (mType==tnINNER) ); assert((m >= 0) && (m < 16) && (mType == tnINNER));
return mHashes[m]; return mHashes[m];
} }
// vim:ts=4 // vim:ts=4