From 1167ba2cc075264dfc6c40f92d7be2cea5e703e9 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sat, 28 Jul 2012 14:49:34 -0700 Subject: [PATCH 1/6] Set up for ledger diffs to populate the metadata. Special case for unfunded offers -- need to know how much was taken before deletion --- src/LedgerEntrySet.cpp | 9 ++++++++- src/LedgerEntrySet.h | 2 +- src/TransactionEngine.cpp | 7 +++++-- src/TransactionEngine.h | 2 +- src/TransactionMeta.cpp | 6 ++++++ src/TransactionMeta.h | 6 +++++- 6 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/LedgerEntrySet.cpp b/src/LedgerEntrySet.cpp index e325b47dee..0c87f7849b 100644 --- a/src/LedgerEntrySet.cpp +++ b/src/LedgerEntrySet.cpp @@ -147,7 +147,7 @@ void LedgerEntrySet::entryModify(SLE::pointer& sle) } } -void LedgerEntrySet::entryDelete(SLE::pointer& sle) +void LedgerEntrySet::entryDelete(SLE::pointer& sle, bool unfunded) { boost::unordered_map::iterator it = mEntries.find(sle->getIndex()); if (it == mEntries.end()) @@ -166,6 +166,13 @@ void LedgerEntrySet::entryDelete(SLE::pointer& sle) it->second.mSeq = mSeq; it->second.mEntry = sle; it->second.mAction = taaDELETE; + if (unfunded) + { + assert(sle->getType() == ltOFFER); // only offers can be unfunded + mSet.deleteUnfunded(sle->getIndex(), + sle->getIValueFieldAmount(sfTakerPays), + sle->getIValueFieldAmount(sfTakerGets)); + } break; case taaCREATE: diff --git a/src/LedgerEntrySet.h b/src/LedgerEntrySet.h index 01312e0b52..e600060f33 100644 --- a/src/LedgerEntrySet.h +++ b/src/LedgerEntrySet.h @@ -55,7 +55,7 @@ public: LedgerEntryAction hasEntry(const uint256& index) const; void entryCache(SLE::pointer&); // Add this entry to the cache void entryCreate(SLE::pointer&); // This entry will be created - void entryDelete(SLE::pointer&); // This entry will be deleted + void entryDelete(SLE::pointer&, bool unfunded); void entryModify(SLE::pointer&); // This entry will be modified // iterator functions diff --git a/src/TransactionEngine.cpp b/src/TransactionEngine.cpp index 69dde7cb91..8fdf965608 100644 --- a/src/TransactionEngine.cpp +++ b/src/TransactionEngine.cpp @@ -706,7 +706,10 @@ SLE::pointer TransactionEngine::entryCache(LedgerEntryType letType, const uint25 { sleEntry = mLedger->getSLE(uIndex); if (sleEntry) + { mNodes.entryCache(sleEntry); + mOrigNodes.entryCache(sleEntry); // So the metadata code can compare to the original + } } else if(action == taaDELETE) assert(false); @@ -727,9 +730,9 @@ SLE::pointer TransactionEngine::entryCreate(LedgerEntryType letType, const uint2 } -void TransactionEngine::entryDelete(SLE::pointer sleEntry) +void TransactionEngine::entryDelete(SLE::pointer sleEntry, bool unfunded) { - mNodes.entryDelete(sleEntry); + mNodes.entryDelete(sleEntry, unfunded); } void TransactionEngine::entryModify(SLE::pointer sleEntry) diff --git a/src/TransactionEngine.h b/src/TransactionEngine.h index 82a651181b..8fc31aa5e3 100644 --- a/src/TransactionEngine.h +++ b/src/TransactionEngine.h @@ -186,7 +186,7 @@ protected: SLE::pointer entryCreate(LedgerEntryType letType, const uint256& uIndex); SLE::pointer entryCache(LedgerEntryType letType, const uint256& uIndex); - void entryDelete(SLE::pointer sleEntry); + void entryDelete(SLE::pointer sleEntry, bool unfunded = false); void entryModify(SLE::pointer sleEntry); void entryReset(); diff --git a/src/TransactionMeta.cpp b/src/TransactionMeta.cpp index 7948057856..744e142fa7 100644 --- a/src/TransactionMeta.cpp +++ b/src/TransactionMeta.cpp @@ -230,3 +230,9 @@ void TransactionMetaSet::swap(TransactionMetaSet& s) assert((mTransactionID == s.mTransactionID) && (mLedger == s.mLedger)); mNodes.swap(s.mNodes); } + +bool TransactionMetaSet::deleteUnfunded(const uint256& node, const STAmount& firstBalance, const STAmount &secondBalance) +{ + // WRITEME + return true; +} diff --git a/src/TransactionMeta.h b/src/TransactionMeta.h index a0685a1496..573320116c 100644 --- a/src/TransactionMeta.h +++ b/src/TransactionMeta.h @@ -71,8 +71,12 @@ public: class TMNEUnfunded : public TransactionMetaNodeEntry { // node was deleted because it was unfunded +protected: + STAmount firstAmount, secondAmount; // Amounts left when declared unfunded public: TMNEUnfunded() : TransactionMetaNodeEntry(TMNDeleteUnfunded) { ; } + TMNEUnfunded(const STAmount& f, const STAmount& s) : + TransactionMetaNodeEntry(TMNDeleteUnfunded), firstAmount(f), secondAmount(s) { ; } virtual void addRaw(Serializer&) const; virtual Json::Value getJson(int) const; virtual int compare(const TransactionMetaNodeEntry&) const; @@ -132,7 +136,7 @@ public: void threadNode(const uint256& node, const uint256& previousTransaction, uint32 previousLedger); bool signedBy(const uint256& node, const STAmount& fee); - bool deleteUnfunded(const uint256& node); + bool deleteUnfunded(const uint256& node, const STAmount& firstBalance, const STAmount& secondBalance); bool adjustBalance(const uint256& node, unsigned flags, const STAmount &amount); bool adjustBalances(const uint256& node, unsigned flags, const STAmount &firstAmt, const STAmount &secondAmt); }; From a01909fa4bff963e8db0f824cb88903751b98feb Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 30 Jul 2012 00:29:42 -0700 Subject: [PATCH 2/6] Some transaction metadata fixes. --- src/TransactionMeta.cpp | 53 +++++++++++++++++++++++------------------ src/TransactionMeta.h | 7 ++++-- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/TransactionMeta.cpp b/src/TransactionMeta.cpp index 744e142fa7..669b678dea 100644 --- a/src/TransactionMeta.cpp +++ b/src/TransactionMeta.cpp @@ -134,6 +134,14 @@ void TransactionMetaNode::addRaw(Serializer& s) const s.add8(TransactionMetaNodeEntry::TMNEndOfMetadata); } +void TransactionMetaNode::thread(const uint256& prevTx, uint32 prevLgr) +{ + assert((mPreviousLedger == 0) || (mPreviousLedger == prevLgr)); + assert(mPreviousTransaction.isZero() || (mPreviousTransaction == prevTx)); + mPreviousTransaction = prevTx; + mPreviousLedger = prevLgr; +} + Json::Value TransactionMetaNode::getJson(int v) const { Json::Value ret = Json::objectValue; @@ -162,16 +170,16 @@ TransactionMetaSet::TransactionMetaSet(uint32 ledger, const std::vector::const_iterator it = mNodes.begin(), end = mNodes.end(); + for (std::map::const_iterator it = mNodes.begin(), end = mNodes.end(); it != end; ++it) - it->addRaw(s); + it->second.addRaw(s); s.add256(uint256()); } @@ -183,9 +191,9 @@ Json::Value TransactionMetaSet::getJson(int v) const ret["ledger"] = mLedger; Json::Value e = Json::arrayValue; - for (std::set::const_iterator it = mNodes.begin(), end = mNodes.end(); + for (std::map::const_iterator it = mNodes.begin(), end = mNodes.end(); it != end; ++it) - e.append(it->getJson(v)); + e.append(it->second.getJson(v)); ret["nodes_affected"] = e; return ret; @@ -193,28 +201,14 @@ Json::Value TransactionMetaSet::getJson(int v) const bool TransactionMetaSet::isNodeAffected(const uint256& node) const { - for (std::set::const_iterator it = mNodes.begin(), end = mNodes.end(); - it != end; ++it) - if (it->getNode() == node) - return true; - return false; -} - -TransactionMetaNode TransactionMetaSet::getAffectedNode(const uint256& node) -{ - for (std::set::const_iterator it = mNodes.begin(), end = mNodes.end(); - it != end; ++it) - if (it->getNode() == node) - return *it; - return TransactionMetaNode(uint256()); + return mNodes.find(node) != mNodes.end(); } const TransactionMetaNode& TransactionMetaSet::peekAffectedNode(const uint256& node) const { - for (std::set::const_iterator it = mNodes.begin(), end = mNodes.end(); - it != end; ++it) - if (it->getNode() == node) - return *it; + std::map::const_iterator it = mNodes.find(node); + if (it != mNodes.end()) + return it->second; throw std::runtime_error("Affected node not found"); } @@ -231,6 +225,19 @@ void TransactionMetaSet::swap(TransactionMetaSet& s) mNodes.swap(s.mNodes); } +TransactionMetaNode& TransactionMetaSet::modifyNode(const uint256& node) +{ + std::map::iterator it = mNodes.find(node); + if (it != mNodes.end()) + return it->second; + return mNodes.insert(std::make_pair(node, TransactionMetaNode(node))).first->second; +} + +void TransactionMetaSet::threadNode(const uint256& node, const uint256& prevTx, uint32 prevLgr) +{ + modifyNode(node).thread(prevTx, prevLgr); +} + bool TransactionMetaSet::deleteUnfunded(const uint256& node, const STAmount& firstBalance, const STAmount &secondBalance) { // WRITEME diff --git a/src/TransactionMeta.h b/src/TransactionMeta.h index 573320116c..5d680838f3 100644 --- a/src/TransactionMeta.h +++ b/src/TransactionMeta.h @@ -106,6 +106,8 @@ public: bool operator>(const TransactionMetaNode& n) const { return mNode > n.mNode; } bool operator>=(const TransactionMetaNode& n) const { return mNode >= n.mNode; } + void thread(const uint256& prevTx, uint32 prevLgr); + TransactionMetaNode(const uint256&node, SerializerIterator&); void addRaw(Serializer&) const; Json::Value getJson(int) const; @@ -116,7 +118,9 @@ class TransactionMetaSet protected: uint256 mTransactionID; uint32 mLedger; - std::set mNodes; + std::map mNodes; + + TransactionMetaNode& modifyNode(const uint256&); public: TransactionMetaSet() : mLedger(0) { ; } @@ -128,7 +132,6 @@ public: void swap(TransactionMetaSet&); bool isNodeAffected(const uint256&) const; - TransactionMetaNode getAffectedNode(const uint256&); const TransactionMetaNode& peekAffectedNode(const uint256&) const; Json::Value getJson(int) const; From 935588a208991275de3d47ef87f7f2c50ef146fb Mon Sep 17 00:00:00 2001 From: jed Date: Mon, 30 Jul 2012 09:20:02 -0700 Subject: [PATCH 3/6] compile on windows --- newcoin.vcxproj | 2 ++ newcoin.vcxproj.filters | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/newcoin.vcxproj b/newcoin.vcxproj index 58d9966419..c053c90f59 100644 --- a/newcoin.vcxproj +++ b/newcoin.vcxproj @@ -110,6 +110,7 @@ + @@ -150,6 +151,7 @@ + diff --git a/newcoin.vcxproj.filters b/newcoin.vcxproj.filters index 168f3736bb..b8c3acee1e 100644 --- a/newcoin.vcxproj.filters +++ b/newcoin.vcxproj.filters @@ -267,6 +267,12 @@ Source Files + + Source Files + + + Source Files + From 6e1ffd752da930dc8cd7b9c1a770b002bd89479c Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 30 Jul 2012 23:42:57 -0700 Subject: [PATCH 4/6] Well, that was painful. Can't use vectors because they slice. Can't use sets because their contents are immutable. Can't use maps because there's no type that corresponds to the sort order. Can't use a vector of pointers because they won't snapshot/copy correctly. No real choice but to use boost::ptr_vector and create the necessary helper functions for it to work. --- src/TransactionMeta.cpp | 21 ++++++++++++--------- src/TransactionMeta.h | 22 +++++++++++++++++----- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/TransactionMeta.cpp b/src/TransactionMeta.cpp index 669b678dea..6594dc0392 100644 --- a/src/TransactionMeta.cpp +++ b/src/TransactionMeta.cpp @@ -1,5 +1,7 @@ #include "TransactionMeta.h" +#include + #include #include @@ -115,22 +117,23 @@ TransactionMetaNode::TransactionMetaNode(const uint256& node, SerializerIterator { type = sit.get8(); if (type == TransactionMetaNodeEntry::TMNChangedBalance) - mEntries.insert(boost::shared_ptr(new TMNEBalance(sit))); + mEntries.push_back(new TMNEBalance(sit)); if (type == TransactionMetaNodeEntry::TMNDeleteUnfunded) - mEntries.insert(boost::shared_ptr(new TMNEUnfunded())); + mEntries.push_back(new TMNEUnfunded()); else if (type != TransactionMetaNodeEntry::TMNEndOfMetadata) throw std::runtime_error("Unparseable metadata"); } while (type != TransactionMetaNodeEntry::TMNEndOfMetadata); } -void TransactionMetaNode::addRaw(Serializer& s) const +void TransactionMetaNode::addRaw(Serializer& s) { s.add256(mNode); s.add256(mPreviousTransaction); s.add32(mPreviousLedger); - for (std::set::const_iterator it = mEntries.begin(), end = mEntries.end(); + mEntries.sort(); + for (boost::ptr_vector::const_iterator it = mEntries.begin(), end = mEntries.end(); it != end; ++it) - (*it)->addRaw(s); + it->addRaw(s); s.add8(TransactionMetaNodeEntry::TMNEndOfMetadata); } @@ -150,9 +153,9 @@ Json::Value TransactionMetaNode::getJson(int v) const ret["previous_ledger"] = mPreviousLedger; Json::Value e = Json::arrayValue; - for (std::set::const_iterator it = mEntries.begin(), end = mEntries.end(); + for (boost::ptr_vector::const_iterator it = mEntries.begin(), end = mEntries.end(); it != end; ++it) - e.append((*it)->getJson(v)); + e.append(it->getJson(v)); ret["entries"] = e; return ret; @@ -174,10 +177,10 @@ TransactionMetaSet::TransactionMetaSet(uint32 ledger, const std::vector::const_iterator it = mNodes.begin(), end = mNodes.end(); + for (std::map::iterator it = mNodes.begin(), end = mNodes.end(); it != end; ++it) it->second.addRaw(s); s.add256(uint256()); diff --git a/src/TransactionMeta.h b/src/TransactionMeta.h index 5d680838f3..cc1bd50659 100644 --- a/src/TransactionMeta.h +++ b/src/TransactionMeta.h @@ -2,9 +2,9 @@ #define __TRANSACTIONMETA__ #include -#include #include +#include #include "../json/value.h" @@ -35,6 +35,12 @@ public: bool operator<=(const TransactionMetaNodeEntry&) const; bool operator>(const TransactionMetaNodeEntry&) const; bool operator>=(const TransactionMetaNodeEntry&) const; + + std::auto_ptr clone() const + { return std::auto_ptr(clone()); } + +protected: + virtual TransactionMetaNodeEntry* clone(void) = 0; }; class TMNEBalance : public TransactionMetaNodeEntry @@ -67,6 +73,7 @@ public: virtual Json::Value getJson(int) const; virtual int compare(const TransactionMetaNodeEntry&) const; + virtual TransactionMetaNodeEntry* clone(void) { return new TMNEBalance(*this); } }; class TMNEUnfunded : public TransactionMetaNodeEntry @@ -80,8 +87,12 @@ public: virtual void addRaw(Serializer&) const; virtual Json::Value getJson(int) const; virtual int compare(const TransactionMetaNodeEntry&) const; + virtual TransactionMetaNodeEntry* clone(void) { return new TMNEUnfunded(*this); } }; +inline TransactionMetaNodeEntry* new_clone(const TransactionMetaNodeEntry& s) { return s.clone().release(); } +inline void delete_clone(const TransactionMetaNodeEntry* s) { boost::checked_delete(s); } + class TransactionMetaNode { // a node that has been affected by a transaction public: @@ -91,7 +102,7 @@ protected: uint256 mNode; uint256 mPreviousTransaction; uint32 mPreviousLedger; - std::set mEntries; + boost::ptr_vector mEntries; public: TransactionMetaNode(const uint256 &node) : mNode(node) { ; } @@ -99,7 +110,7 @@ public: const uint256& getNode() const { return mNode; } const uint256& getPreviousTransaction() const { return mPreviousTransaction; } uint32 getPreviousLedger() const { return mPreviousLedger; } - const std::set& peekEntries() const { return mEntries; } + const boost::ptr_vector& peekEntries() const { return mEntries; } bool operator<(const TransactionMetaNode& n) const { return mNode < n.mNode; } bool operator<=(const TransactionMetaNode& n) const { return mNode <= n.mNode; } @@ -109,10 +120,11 @@ public: void thread(const uint256& prevTx, uint32 prevLgr); TransactionMetaNode(const uint256&node, SerializerIterator&); - void addRaw(Serializer&) const; + void addRaw(Serializer&); Json::Value getJson(int) const; }; + class TransactionMetaSet { protected: @@ -135,7 +147,7 @@ public: const TransactionMetaNode& peekAffectedNode(const uint256&) const; Json::Value getJson(int) const; - void addRaw(Serializer&) const; + void addRaw(Serializer&); void threadNode(const uint256& node, const uint256& previousTransaction, uint32 previousLedger); bool signedBy(const uint256& node, const STAmount& fee); From 1213f34d754d447638d2bfc0d1bb7b74978b893d Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 31 Jul 2012 01:01:50 -0700 Subject: [PATCH 5/6] More pieces. --- src/TransactionMeta.cpp | 32 +++++++++++++++++++++++++++++--- src/TransactionMeta.h | 4 ++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/TransactionMeta.cpp b/src/TransactionMeta.cpp index 6594dc0392..d1f4840e72 100644 --- a/src/TransactionMeta.cpp +++ b/src/TransactionMeta.cpp @@ -101,6 +101,12 @@ Json::Value TMNEUnfunded::getJson(int) const return Json::Value("delete_unfunded"); } +void TMNEUnfunded::setBalances(const STAmount& first, const STAmount& second) +{ + firstAmount = first; + secondAmount = second; +} + int TMNEUnfunded::compare(const TransactionMetaNodeEntry&) const { assert(false); // Can't be two deletes for same node @@ -137,6 +143,20 @@ void TransactionMetaNode::addRaw(Serializer& s) s.add8(TransactionMetaNodeEntry::TMNEndOfMetadata); } +TransactionMetaNodeEntry* TransactionMetaNode::findEntry(int nodeType) +{ + for (boost::ptr_vector::iterator it = mEntries.begin(), end = mEntries.end(); + it != end; ++it) + if (it->getType() == nodeType) + return &*it; + return NULL; +} + +void TransactionMetaNode::addNode(TransactionMetaNodeEntry* node) +{ + mEntries.push_back(node); +} + void TransactionMetaNode::thread(const uint256& prevTx, uint32 prevLgr) { assert((mPreviousLedger == 0) || (mPreviousLedger == prevLgr)); @@ -241,8 +261,14 @@ void TransactionMetaSet::threadNode(const uint256& node, const uint256& prevTx, modifyNode(node).thread(prevTx, prevLgr); } -bool TransactionMetaSet::deleteUnfunded(const uint256& node, const STAmount& firstBalance, const STAmount &secondBalance) +bool TransactionMetaSet::deleteUnfunded(const uint256& nodeID, + const STAmount& firstBalance, const STAmount &secondBalance) { - // WRITEME - return true; + TransactionMetaNode& node = modifyNode(nodeID); + TMNEUnfunded* entry = dynamic_cast(node.findEntry(TransactionMetaNodeEntry::TMNDeleteUnfunded)); + if (entry) + entry->setBalances(firstBalance, secondBalance); + else + node.addNode(new TMNEUnfunded(firstBalance, secondBalance)); + return true; } diff --git a/src/TransactionMeta.h b/src/TransactionMeta.h index cc1bd50659..5765034186 100644 --- a/src/TransactionMeta.h +++ b/src/TransactionMeta.h @@ -84,6 +84,7 @@ public: TMNEUnfunded() : TransactionMetaNodeEntry(TMNDeleteUnfunded) { ; } TMNEUnfunded(const STAmount& f, const STAmount& s) : TransactionMetaNodeEntry(TMNDeleteUnfunded), firstAmount(f), secondAmount(s) { ; } + void setBalances(const STAmount& firstBalance, const STAmount& secondBalance); virtual void addRaw(Serializer&) const; virtual Json::Value getJson(int) const; virtual int compare(const TransactionMetaNodeEntry&) const; @@ -112,6 +113,9 @@ public: uint32 getPreviousLedger() const { return mPreviousLedger; } const boost::ptr_vector& peekEntries() const { return mEntries; } + TransactionMetaNodeEntry* findEntry(int nodeType); + void addNode(TransactionMetaNodeEntry*); + bool operator<(const TransactionMetaNode& n) const { return mNode < n.mNode; } bool operator<=(const TransactionMetaNode& n) const { return mNode <= n.mNode; } bool operator>(const TransactionMetaNode& n) const { return mNode > n.mNode; } From a17ca0cd4a4af440b5ec71a12d200e865e1e685f Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Wed, 1 Aug 2012 14:19:13 -0700 Subject: [PATCH 6/6] Fix the crash bug. --- src/SerializedTypes.cpp | 6 ++++++ src/SerializedTypes.h | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/SerializedTypes.cpp b/src/SerializedTypes.cpp index bd76f5c843..7177f0fb2c 100644 --- a/src/SerializedTypes.cpp +++ b/src/SerializedTypes.cpp @@ -208,6 +208,12 @@ void STVector256::add(Serializer& s) const s.addVL(mValue.empty() ? NULL : mValue[0].begin(), mValue.size() * (256 / 8)); } +bool STVector256::isEquivalent(const SerializedType& t) const +{ + const STVector256* v = dynamic_cast(&t); + return v && (mValue == v->mValue); +} + // // STAccount // diff --git a/src/SerializedTypes.h b/src/SerializedTypes.h index b1ce80eedb..7b8d10bebf 100644 --- a/src/SerializedTypes.h +++ b/src/SerializedTypes.h @@ -83,7 +83,7 @@ public: virtual void add(Serializer& s) const { return; } virtual bool isEquivalent(const SerializedType& t) const - { assert(getSType() == STI_NOTPRESENT); return t.getSType() == STI_NOTPRESENT; } + { std::cerr << getSType() << std::endl; assert(getSType() == STI_NOTPRESENT); return t.getSType() == STI_NOTPRESENT; } bool operator==(const SerializedType& t) const { return (getSType() == t.getSType()) && isEquivalent(t); } @@ -696,6 +696,7 @@ public: const std::vector& peekValue() const { return mValue; } std::vector& peekValue() { return mValue; } + virtual bool isEquivalent(const SerializedType& t) const; std::vector getValue() const { return mValue; }