diff --git a/Account.h b/Account.h index c365f7cc85..260fb6361f 100644 --- a/Account.h +++ b/Account.h @@ -14,6 +14,7 @@ public: bool CheckSignRaw(const std::vector &toSign, const std::vector &signature) const; const uint160& GetAddress(void) const { return mAddress; } + CKey& peekPubKey() { return pubKey; } }; #endif diff --git a/SHAMap.cpp b/SHAMap.cpp index 4f171ca990..a430e3c66f 100644 --- a/SHAMap.cpp +++ b/SHAMap.cpp @@ -91,7 +91,7 @@ SHAMapLeafNode::pointer SHAMap::getLeaf(const SHAMapNode &id, const uint256& has if(leaf != SHAMapLeafNode::pointer()) return leaf; std::vector rawNode; // is it in backing store - if(!fetchNode(hash, id, rawNode)) return leaf; + if(!fetchNode(hash, id, rawNode)) return SHAMapLeafNode::pointer(); Serializer s(rawNode); leaf=SHAMapLeafNode::pointer(new SHAMapLeafNode(id)); @@ -120,7 +120,7 @@ SHAMapInnerNode::pointer SHAMap::getInner(const SHAMapNode &id, const uint256& h if(node != SHAMapInnerNode::pointer()) return node; std::vector rawNode; - if(!fetchNode(hash, id, rawNode)) return node; + if(!fetchNode(hash, id, rawNode)) return SHAMapInnerNode::pointer(); node=SHAMapInnerNode::pointer(new SHAMapInnerNode(id, rawNode)); if(node->getNodeHash()!=hash) @@ -279,6 +279,23 @@ void SHAMapItem::dump() std::cerr << "SHAMapItem(" << mTag.GetHex() << ") " << mData.size() << "bytes" << std::endl; } +// overloads for backed maps +bool SHAMap::fetchNode(const uint256 &, const SHAMapNode &, std::vector &) +{ + return false; +} + +bool SHAMap::writeNode(const uint256 &, const SHAMapNode &, const std::vector &) +{ + return true; +} + +void SHAMap::badNode(const uint256 &, const SHAMapNode &) +{ + return; +} + + void SHAMap::dump() { } @@ -297,3 +314,4 @@ void TestSHAMap() sMap.dump(); } + diff --git a/SHAMap.h b/SHAMap.h index 118b8e2eca..985a094417 100644 --- a/SHAMap.h +++ b/SHAMap.h @@ -2,11 +2,9 @@ #define __SHAMAP__ #include -#include #include #include -#include #include #include "uint256.h" @@ -33,9 +31,9 @@ public: static const int rootDepth=0; static const int leafDepth=10; - SHAMapNode(int depth, const uint256 &hash); + SHAMapNode(int depth, const uint256& hash); int getDepth() const { return mDepth; } - const uint256 &getNodeID() { return mNodeID; } + const uint256& getNodeID() { return mNodeID; } bool isRoot() const { return mDepth==0; } bool isLeaf() const { return mDepth==leafDepth; } @@ -45,19 +43,19 @@ public: SHAMapNode getParentNodeID() { return SHAMapNode(mDepth-1, mNodeID); } SHAMapNode getChildNodeID(int m); - int selectBranch(const uint256 &hash); + int selectBranch(const uint256& hash); - bool operator<(const SHAMapNode &) const; - bool operator>(const SHAMapNode &) const; - bool operator==(const SHAMapNode &) const; - bool operator!=(const SHAMapNode &) const; - bool operator<=(const SHAMapNode &) const; - bool operator>=(const SHAMapNode &) const; + bool operator<(const SHAMapNode&) const; + bool operator>(const SHAMapNode&) const; + bool operator==(const SHAMapNode&) const; + bool operator!=(const SHAMapNode&) const; + bool operator<=(const SHAMapNode&) const; + bool operator>=(const SHAMapNode&) const; virtual void dump(void); static void ClassInit(); - static uint256 getNodeID(int depth, const uint256 &hash); + static uint256 getNodeID(int depth, const uint256& hash); }; @@ -71,15 +69,15 @@ private: std::vector mData; public: - SHAMapItem(const uint256 &tag); // tag is data - SHAMapItem(const uint256 &tag, const std::vector& data); + SHAMapItem(const uint256& tag); // tag is data + SHAMapItem(const uint256& tag, const std::vector& data); SHAMapItem(const std::vector& data); // tag by hash const uint256& getTag(void) const { return mTag; } std::vector getData(void) const { return mData; } const std::vector& peekData(void) const { return mData; } - void updateData(const std::vector &data) { mData=data; } + void updateData(const std::vector& data) { mData=data; } bool operator<(const SHAMapItem& i) const { return mTag(const SHAMapItem& i) const { return mTag>i.mTag; } @@ -113,7 +111,7 @@ private: protected: bool addUpdateItem(SHAMapItem::pointer); bool delItem(const SHAMapItem::pointer i) { delItem(i->getTag()); } - bool delItem(const uint256 &tag); + bool delItem(const uint256& tag); public: SHAMapLeafNode(const SHAMapNode& nodeID); @@ -124,8 +122,8 @@ public: bool isEmpty() const { return mItems.empty(); } int getItemCount() const { return mItems.size(); } - bool hasItem(const uint256 &item) const; - SHAMapItem::pointer findItem(const uint256 &tag); + bool hasItem(const uint256& item) const; + SHAMapItem::pointer findItem(const uint256& tag); SHAMapItem::pointer firstItem(); SHAMapItem::pointer lastItem(); SHAMapItem::pointer nextItem(SHAMapItem::pointer); @@ -152,7 +150,7 @@ protected: public: SHAMapInnerNode(const SHAMapNode& id); - SHAMapInnerNode(const SHAMapNode& id, const std::vector &contents); + SHAMapInnerNode(const SHAMapNode& id, const std::vector& contents); virtual bool isPopulated(void) const { return true; } @@ -189,8 +187,8 @@ protected: SHAMapLeafNode::pointer walkToLeaf(const uint256& id, bool create, std::vector& path); - SHAMapLeafNode::pointer getLeaf(const SHAMapNode &id, const uint256& hash); - SHAMapInnerNode::pointer getInner(const SHAMapNode &id, const uint256& hash); + SHAMapLeafNode::pointer getLeaf(const SHAMapNode& id, const uint256& hash); + SHAMapInnerNode::pointer getInner(const SHAMapNode& id, const uint256& hash); SHAMapItem::pointer firstBelow(SHAMapInnerNode::pointer); SHAMapItem::pointer lastBelow(SHAMapInnerNode::pointer); @@ -202,24 +200,24 @@ public: ScopedLock Lock() const { return ScopedLock(mLock); } // inner node access functions - bool hasInnerNode(const SHAMapNode &id); + bool hasInnerNode(const SHAMapNode& id); bool giveInnerNode(SHAMapInnerNode::pointer); SHAMapInnerNode::pointer getInnerNode(const SHAMapNode &); // leaf node access functions - bool hasLeafNode(const SHAMapNode &id); + bool hasLeafNode(const SHAMapNode& id); bool giveLeafNode(SHAMapLeafNode::pointer); SHAMapLeafNode::pointer getLeafNode(const SHAMapNode &); // generic node functions - std::vector getRawNode(const SHAMapNode &id); + std::vector getRawNode(const SHAMapNode& id); bool addRawNode(const SHAMapNode& nodeID, std::vector rawNode); // normal hash access functions bool hasItem(const uint256& id); bool delItem(const uint256& id); bool addItem(SHAMapItem::pointer item); - SHAMapItem::pointer getItem(const uint256 &id); + SHAMapItem::pointer getItem(const uint256& id); // traverse functions SHAMapItem::pointer firstItem(); @@ -228,18 +226,18 @@ public: SHAMapItem::pointer prevItem(const SHAMapItem &); // comparison/sync functions - void getMissingNodes(std::vector &nodeHashes, int max); - void getMissingObjects(std::vector &objectHashes, int max); - bool getNodeFat(const SHAMapNode &node, std::vector &nodeHashes, int max); - bool getNodeFat(const uint256 &hash, std::vector &nodeHashes, int max); + void getMissingNodes(std::vector& nodeHashes, int max); + void getMissingObjects(std::vector& objectHashes, int max); + bool getNodeFat(const SHAMapNode& node, std::vector& nodeHashes, int max); + bool getNodeFat(const uint256& hash, std::vector& nodeHashes, int max); bool addKnownNode(const std::vector& rawNode); int flushDirty(int maxNodes); // overloads for backed maps - virtual bool fetchNode(const uint256 &hash, const SHAMapNode &id, std::vector& rawNode); - virtual bool writeNode(const uint256 &hash, const SHAMapNode &id, const std::vector& rawNode); - virtual void badNode(const uint256 &hash, const SHAMapNode &id); + virtual bool fetchNode(const uint256& hash, const SHAMapNode& id, std::vector& rawNode); + virtual bool writeNode(const uint256& hash, const SHAMapNode& id, const std::vector& rawNode); + virtual void badNode(const uint256& hash, const SHAMapNode& id); static bool TestSHAMap(); virtual void dump(void); diff --git a/SHAMapNodes.cpp b/SHAMapNodes.cpp index 0e17924798..e6810049fd 100644 --- a/SHAMapNodes.cpp +++ b/SHAMapNodes.cpp @@ -67,7 +67,7 @@ uint256 SHAMapNode::getNodeID(int depth, const uint256& hash) SHAMapNode::SHAMapNode(int depth, const uint256 &hash) { // canonicalize the hash to a node ID for this depth - assert(depth>=0 && depth=0 && depth<=leafDepth); mDepth = depth; mNodeID = getNodeID(depth, hash); } @@ -103,7 +103,7 @@ void SHAMapNode::dump() SHAMapLeafNode::SHAMapLeafNode(const SHAMapNode& nodeID) : SHAMapNode(nodeID), mHash(0) { - ; + assert(nodeID.getDepth()==SHAMapNode::leafDepth); } bool SHAMapLeafNode::hasItem(const uint256& item) const @@ -185,9 +185,15 @@ bool SHAMapLeafNode::updateHash(void) return true; } +void SHAMapLeafNode::dump() +{ + std::cerr << "SHAMapLeafNode(" << getNodeID().GetHex() << ")" << std::endl; + std::cerr << " " << mItems.size() << " items" << std::endl; +} + SHAMapInnerNode::SHAMapInnerNode(const SHAMapNode& id) : SHAMapNode(id) { - ; + assert(id.getDepth()& contents) @@ -230,3 +236,13 @@ bool SHAMapInnerNode::updateHash() return true; } +void SHAMapInnerNode::dump() +{ + std::cerr << "SHAMapInnerNode(" << getDepth() << ", " << getNodeID().GetHex() << ")" << std::endl; + + int children=0; + for(int i=0; i<32; i++) + if(!!mHashes[i]) children++; + + std::cerr << " " << children << " children" << std::endl; +} diff --git a/Serializer.h b/Serializer.h index 623148d448..728212b697 100644 --- a/Serializer.h +++ b/Serializer.h @@ -2,51 +2,57 @@ #define __SERIALIZER__ #include + +#include + #include "key.h" #include "uint256.h" class Serializer { - protected: - std::vector mData; - - public: - Serializer(int n=256) { mData.reserve(n); } - Serializer(const std::vector &data) : mData(data) { ; } + public: + typedef boost::shared_ptr pointer; - // assemble functions - int add32(uint32); // ledger indexes, account sequence - int add64(uint64); // timestamps, amounts - int add160(const uint160&); // account names, hankos - int add256(const uint256&); // transaction and ledger hashes - int addRaw(const std::vector &vector); + protected: + std::vector mData; + + public: + Serializer(int n=256) { mData.reserve(n); } + Serializer(const std::vector &data) : mData(data) { ; } - // disassemble functions - bool get32(uint32&, int offset) const; - bool get64(uint64&, int offset) const; - bool get160(uint160&, int offset) const; - bool get256(uint256&, int offset) const; - uint256 get256(int offset) const; - bool getRaw(std::vector&, int offset, int length) const; - std::vector getRaw(int offset, int length) const; - - // hash functions - uint160 getRIPEMD160(int size=0) const; - uint256 getSHA256(int size=0) const; - uint256 getSHA512Half(int size=0) const; + // assemble functions + int add32(uint32); // ledger indexes, account sequence + int add64(uint64); // timestamps, amounts + int add160(const uint160&); // account names, hankos + int add256(const uint256&); // transaction and ledger hashes + int addRaw(const std::vector &vector); - // totality functions - int getLength() const { return mData.size(); } - const std::vector& peekData() const { return mData; } - std::vector getData() const { return mData; } - - // signature functions - bool checkSignature(int pubkeyOffset, int signatureOffset) const; - bool checkSignature(const std::vector &signature, CKey& rkey) const; - bool makeSignature(std::vector &signature, CKey& rkey) const; - bool addSignature(CKey& rkey); + // disassemble functions + bool get32(uint32&, int offset) const; + bool get64(uint64&, int offset) const; + bool get160(uint160&, int offset) const; + bool get256(uint256&, int offset) const; + uint256 get256(int offset) const; + bool getRaw(std::vector&, int offset, int length) const; + std::vector getRaw(int offset, int length) const; + + // hash functions + uint160 getRIPEMD160(int size=0) const; + uint256 getSHA256(int size=0) const; + uint256 getSHA512Half(int size=0) const; - static void TestSerializer(void); + // totality functions + int getLength() const { return mData.size(); } + const std::vector& peekData() const { return mData; } + std::vector getData() const { return mData; } + + // signature functions + bool checkSignature(int pubkeyOffset, int signatureOffset) const; + bool checkSignature(const std::vector &signature, CKey& rkey) const; + bool makeSignature(std::vector &signature, CKey& rkey) const; + bool addSignature(CKey& rkey); + + static void TestSerializer(void); }; #endif diff --git a/Transaction.cpp b/Transaction.cpp index 88cab7fc7b..d25d8c76b4 100644 --- a/Transaction.cpp +++ b/Transaction.cpp @@ -11,57 +11,54 @@ Transaction::Transaction() : mTransactionID(0), mAccountFrom(0), mAccountTo(0), { } -Transaction::Transaction(TransStatus status, LocalAccount &fromLocalAccount, const Account &fromAccount, - uint32 fromSeq, const uint160 &toAccount, uint64 amount, uint32 ident, uint32 ledger) : - mAccountTo(toAccount), mAmount(amount), mFromAccountSeq(fromSeq), mSourceLedger(ledger), - mIdent(ident), mInLedger(0), mStatus(NEW) +Transaction::Transaction(TransStatus status, LocalAccount& fromLocalAccount, Account& fromAccount, + uint32 fromSeq, const uint160& toAccount, uint64 amount, uint32 ident, uint32 ledger) : + mAccountTo(toAccount), mAmount(amount), mFromAccountSeq(fromSeq), mSourceLedger(ledger), + mIdent(ident), mInLedger(0), mStatus(NEW) { - assert(fromAccount.GetAddress()==fromLocalAccount.mAddress); - assert(fromLocalAccount.mAmount>=amount); - assert((fromSeq+1)==fromLocalAccount.mSeqNum); + assert(fromAccount.GetAddress()==fromLocalAccount.mAddress); + assert(fromLocalAccount.mAmount>=amount); + assert((fromSeq+1)==fromLocalAccount.mSeqNum); - mAccountFrom=fromAccount.GetAddress(); - sign(fromLocalAccount, fromAccount); + mAccountFrom=fromAccount.GetAddress(); + sign(fromLocalAccount, fromAccount); } -bool Transaction::sign(LocalAccount &fromLocalAccount, const Account &fromAccount) +bool Transaction::sign(LocalAccount& fromLocalAccount, Account& fromAccount) { - if( (mAmount==0) || (mSourceLedger==0) || (mAccountTo==0) ) - return false; - if((mAccountFrom!=fromLocalAccount.mAddress)||(mAccountFrom!=fromAccount.GetAddress())) - return false; - - updateHash(); - - std::vector toSign, Signature; - if(!getRawUnsigned(toSign, fromAccount)) return false; - if(!fromLocalAccount.SignRaw(toSign, Signature)) return false; - mSignature=Signature; - return true; + if( (mAmount==0) || (mSourceLedger==0) || (mAccountTo==0) ) + return false; + if((mAccountFrom!=fromLocalAccount.mAddress)||(mAccountFrom!=fromAccount.GetAddress())) + return false; + + Serializer::pointer signBuf(getRawUnsigned(fromAccount)); + if(!signBuf->makeSignature(mSignature, fromLocalAccount.peekPrivKey())) + return false; + signBuf->addRaw(mSignature); + mTransactionID=signBuf->getSHA512Half(); } -bool Transaction::checkSign(const Account &fromAccount) const +bool Transaction::checkSign(Account& fromAccount) const { - if(mAccountFrom!=fromAccount.GetAddress()) return false; + if(mAccountFrom!=fromAccount.GetAddress()) return false; - std::vector toSign; - if(!getRawUnsigned(toSign, fromAccount)) return false; - - return fromAccount.CheckSignRaw(toSign, mSignature); + Serializer::pointer toSign(getRawUnsigned(fromAccount)); + return toSign->checkSignature(mSignature, fromAccount.peekPubKey()); } -bool Transaction::getRawUnsigned(std::vector &raw, const Account &fromAccount) const +Serializer::pointer Transaction::getRawUnsigned(Account& fromAccount) const { - raw.clear(); - + Serializer::pointer ret(new Serializer(104)); + ret->add32(0x54584e00u); + ret->addRaw(fromAccount.peekPubKey().GetPubKey()); + ret->add64(mAmount); + ret->add32(mFromAccountSeq); + ret->add32(mInLedger); + ret->add32(mIdent); + return ret; } -#if 0 -void Transaction::UpdateHash() -{ // FIXME - vector buffer; - buffer.resize(trans->ByteSize()); - trans->SerializeToArray(&(buffer[0]),buffer.size()); - return Hash(buffer.begin(), buffer.end()); +void Transaction::updateID(Account& fromAccount) +{ + mTransactionID=getRawSigned(fromAccount)->getSHA512Half(); } -#endif diff --git a/Transaction.h b/Transaction.h index 779a17f799..e717cb81a8 100644 --- a/Transaction.h +++ b/Transaction.h @@ -41,20 +41,19 @@ private: uint32 mInLedger; TransStatus mStatus; - void UpdateHash(void); - public: Transaction(); Transaction(const std::vector rawTransaction); Transaction(const std::string sqlReply); - Transaction(TransStatus Status, LocalAccount& fromLocal, const Account& from, + Transaction(TransStatus Status, LocalAccount& fromLocal, Account& from, uint32 fromSeq, const uint160& to, uint64 amount, uint32 ident, uint32 ledger); - bool sign(LocalAccount& fromLocalAccount, const Account& fromAccount); - bool checkSign(const Account& fromAccount) const; + bool sign(LocalAccount& fromLocalAccount, Account& fromAccount); + bool checkSign(Account& fromAccount) const; + void updateID(Account& fromAccount); - Serializer::pointer getRawUnsigned(const Account& from) const; - Serializer::pointer getRawSigned(const Account& from) const; + Serializer::pointer getRawUnsigned(Account& from) const; + Serializer::pointer getRawSigned(Account& from) const; const uint256& getID() const { return mTransactionID; } const uint160& getFromAccount() const { return mAccountFrom; } diff --git a/Wallet.h b/Wallet.h index 782a489709..088932ad25 100644 --- a/Wallet.h +++ b/Wallet.h @@ -4,6 +4,7 @@ #include "keystore.h" #include "newcoin.pb.h" #include "Transaction.h" +#include "Serializer.h" #include #include @@ -22,8 +23,10 @@ public: int64 mAmount; uint32 mSeqNum; - bool SignRaw(const std::vector &toSign, std::vector &signature); - bool CheckSignRaw(const std::vector &toSign, const std::vector &signature); + bool signRaw(Serializer::pointer); + bool signRaw(Serializer::pointer, std::vector& signature); + bool checkSignRaw(Serializer::pointer, int signaturePosition=-1, int signedData=-1); + CKey& peekPrivKey() { return mPrivateKey; } }; class Wallet : public CBasicKeyStore