From fb60b99781c49afa81b60db06f29c222d3770fc8 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 23 Jul 2012 01:55:20 -0700 Subject: [PATCH 1/4] Header for classes to manipulate transaction metadata. --- src/TransactionMeta.h | 116 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/TransactionMeta.h diff --git a/src/TransactionMeta.h b/src/TransactionMeta.h new file mode 100644 index 0000000000..4298304e09 --- /dev/null +++ b/src/TransactionMeta.h @@ -0,0 +1,116 @@ +#ifndef __TRANSACTIONMETA__ +#define __TRANSACTIONMETA__ + +#include +#include +#include + +#include + +#include "../json/value.h" + +#include "uint256.h" +#include "SerializedTypes.h" + + +class TransactionMetaNodeEntry +{ // a way that a transaction has affected a node +public: + + typedef boost::shared_ptr pointer; + + static const int TMNEndOfMetadata = 0; + static const int TMNChangedBalance = 1; + + int mType; + TransactionMetaNodeEntry(int type) : mType(type) { ; } + + int getType() const { return mType; } + virtual Json::Value getJson(int) const = 0; + virtual int compare(const TransactionMetaNodeEntry&) = 0; + + bool operator<(const TransactionMetaNodeEntry&) const; + bool operator<=(const TransactionMetaNodeEntry&) const; + bool operator>(const TransactionMetaNodeEntry&) const; + bool operator>=(const TransactionMetaNodeEntry&) const; +}; + +class TMNEBalance : public TransactionMetaNodeEntry +{ // a transaction affected the balance of a node +public: + + static const int TMBTwoAmounts = 0x001; + static const int TMBReverse = 0x010; + static const int TMBDestroyed = 0x020; + static const int TMBPaidFee = 0x040; + static const int TMBRipple = 0x100; + static const int TMBOffer = 0x200; + +protected: + unsigned mFlags; + STAmount mFirstAmount, mSecondAmount; + +public: + TMNEBalance() : TransactionMetaNodeEntry(TMNChangedBalance), mFlags(0) { ; } + + unsigned getFlags() const { return mFlags; } + const STAmount& getFirstAmount() const { return mFirstAmount; } + const STAmount& getSecondAmount() const { return mSecondAmount; } + + void adjustFirstAmount(const STAmount&); + void adjustSecondAmount(const STAmount&); + void setFlags(unsigned flags); + + virtual Json::Value getJson(int) const; + virtual int compare(const TransactionMetaNodeEntry&) const; +}; + +class TransactionMetaNode +{ // a node that has been affected by a transaction +protected: + uint256 mNode; + uint256 mPreviousTransaction; + uint32 mPreviousLedger; + std::list mEntries; + +public: + TransactionMetaNode(const uint256 &node) : mNode(node) { ; } + + const uint256& getNode() const { return mNode; } + const uint256& getPreviousTransaction() const { return mPreviousTransaction; } + uint32 getPreviousLedger() const { return mPreviousLedger; } + const std::list& peekEntries() const { return mEntries; } + + 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; } + bool operator>=(const TransactionMetaNode& n) const { return mNode >= n.mNode; } +}; + +class TransactionMetaSet +{ +protected: + uint256 mTransactionID; + uint32 mLedger; + std::set mEntries; + +public: + TransactionMetaSet(const uint256& txID, uint32 ledger) : mTransactionID(txID), mLedger(ledger) + { ; } + TransactionMetaSet(uint32 ledger, const std::vector&); + + bool isNodeAffected(const uint256&) const; + TransactionMetaNode getAffectedAccount(const uint256&) const; + const TransactionMetaNode& peekAffectedAccount(const uint256&) const; + + Json::Value getJson(int) const; + void addRaw(Serializer&) const; + + void threadNode(const uint256& node, const uint256& previousTransaction, uint32 previousLedger); + bool signedBy(const uint256& node); + bool adjustBalance(const uint256& node, unsigned flags, const STAmount &amount); + bool adjustBalances(const uint256& node, unsigned flags, const STAmount &firstAmt, const STAmount &secondAmt); + +}; + +#endif From 2ba8527f07804c20ea4186248ea46dd9c31006c5 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 23 Jul 2012 02:59:49 -0700 Subject: [PATCH 2/4] More TransactionMetadata work. --- src/TransactionMeta.cpp | 70 +++++++++++++++++++++++++++++++++++++++++ src/TransactionMeta.h | 7 ++--- 2 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 src/TransactionMeta.cpp diff --git a/src/TransactionMeta.cpp b/src/TransactionMeta.cpp new file mode 100644 index 0000000000..0772c0f067 --- /dev/null +++ b/src/TransactionMeta.cpp @@ -0,0 +1,70 @@ +#include "TransactionMeta.h" + +bool TransactionMetaNodeEntry::operator<(const TransactionMetaNodeEntry& e) const +{ + if (mType < e.mType) return true; + if (mType > e.mType) return false; + return compare(e) < 0; +} + +bool TransactionMetaNodeEntry::operator<=(const TransactionMetaNodeEntry& e) const +{ + if (mType < e.mType) return true; + if (mType > e.mType) return false; + return compare(e) <= 0; +} + +bool TransactionMetaNodeEntry::operator>(const TransactionMetaNodeEntry& e) const +{ + if (mType > e.mType) return true; + if (mType < e.mType) return false; + return compare(e) > 0; +} + +bool TransactionMetaNodeEntry::operator>=(const TransactionMetaNodeEntry& e) const +{ + if (mType > e.mType) return true; + if (mType < e.mType) return false; + return compare(e) >= 0; +} + +void TMNEBalance::adjustFirstAmount(const STAmount& a) +{ + mFirstAmount += a; +} + +void TMNEBalance::adjustSecondAmount(const STAmount& a) +{ + mSecondAmount += a; + mFlags |= TMBTwoAmounts; +} + +int TMNEBalance::compare(const TransactionMetaNodeEntry&) const +{ + assert(false); // should never be two TMNEBalance entries for the same node (as of now) + return 0; +} + +Json::Value TMNEBalance::getJson(int p) const +{ + Json::Value ret(Json::objectValue); + + if ((mFlags & TMBDestroyed) != 0) + ret["destroyed"] = "true"; + if ((mFlags & TMBPaidFee) != 0) + ret["transaction_fee"] = "true"; + + if ((mFlags & TMBRipple) != 0) + ret["type"] = "ripple"; + else if ((mFlags & TMBOffer) != 0) + ret["type"] = "offer"; + else + ret["type"] = "account"; + + if (!mFirstAmount.isZero()) + ret["amount"] = mFirstAmount.getJson(p); + if (!mSecondAmount.isZero()) + ret["second_amount"] = mSecondAmount.getJson(p); + + return ret; +} diff --git a/src/TransactionMeta.h b/src/TransactionMeta.h index 4298304e09..97991034d4 100644 --- a/src/TransactionMeta.h +++ b/src/TransactionMeta.h @@ -27,7 +27,7 @@ public: int getType() const { return mType; } virtual Json::Value getJson(int) const = 0; - virtual int compare(const TransactionMetaNodeEntry&) = 0; + virtual int compare(const TransactionMetaNodeEntry&) const = 0; bool operator<(const TransactionMetaNodeEntry&) const; bool operator<=(const TransactionMetaNodeEntry&) const; @@ -40,9 +40,8 @@ class TMNEBalance : public TransactionMetaNodeEntry public: static const int TMBTwoAmounts = 0x001; - static const int TMBReverse = 0x010; - static const int TMBDestroyed = 0x020; - static const int TMBPaidFee = 0x040; + static const int TMBDestroyed = 0x010; + static const int TMBPaidFee = 0x020; static const int TMBRipple = 0x100; static const int TMBOffer = 0x200; From 478d5675310cda5caec86391ad700f60de164f5f Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 23 Jul 2012 23:11:03 -0700 Subject: [PATCH 3/4] More transaction metadata work. --- src/TransactionMeta.cpp | 72 +++++++++++++++++++++++++++++++++++++++++ src/TransactionMeta.h | 21 +++++++++--- 2 files changed, 88 insertions(+), 5 deletions(-) diff --git a/src/TransactionMeta.cpp b/src/TransactionMeta.cpp index 0772c0f067..b1c80d348d 100644 --- a/src/TransactionMeta.cpp +++ b/src/TransactionMeta.cpp @@ -1,5 +1,8 @@ #include "TransactionMeta.h" +#include +#include + bool TransactionMetaNodeEntry::operator<(const TransactionMetaNodeEntry& e) const { if (mType < e.mType) return true; @@ -28,6 +31,23 @@ bool TransactionMetaNodeEntry::operator>=(const TransactionMetaNodeEntry& e) con return compare(e) >= 0; } +TMNEBalance::TMNEBalance(SerializerIterator& sit) : TransactionMetaNodeEntry(TMNChangedBalance) +{ + mFlags = sit.get32(); + mFirstAmount = * dynamic_cast(STAmount::deserialize(sit, "FirstAmount").get()); + if ((mFlags & TMBTwoAmounts) != 0) + mSecondAmount = * dynamic_cast(STAmount::deserialize(sit, "SecondAmount").get()); +} + +void TMNEBalance::addRaw(Serializer& sit) const +{ + sit.add8(mType); + sit.add32(mFlags); + mFirstAmount.add(sit); + if ((mFlags & TMBTwoAmounts) != 0) + mSecondAmount.add(sit); +} + void TMNEBalance::adjustFirstAmount(const STAmount& a) { mFirstAmount += a; @@ -68,3 +88,55 @@ Json::Value TMNEBalance::getJson(int p) const return ret; } + +TransactionMetaNode::TransactionMetaNode(const uint256& node, SerializerIterator& sit) : mNode(node) +{ + mNode = sit.get256(); + mPreviousTransaction = sit.get256(); + mPreviousLedger = sit.get32(); + int type; + do + { + type = sit.get8(); + if (type == TransactionMetaNodeEntry::TMNChangedBalance) + mEntries.push_back(boost::shared_ptr(new TMNEBalance(sit))); + else if (type != TransactionMetaNodeEntry::TMNEndOfMetadata) + throw std::runtime_error("Unparseable metadata"); + } while (type != TransactionMetaNodeEntry::TMNEndOfMetadata); +} + +void TransactionMetaNode::addRaw(Serializer& s) const +{ + s.add256(mNode); + s.add256(mPreviousTransaction); + s.add32(mPreviousLedger); + for (std::list::const_iterator it = mEntries.begin(), end = mEntries.end(); + it != end; ++it) + (*it)->addRaw(s); + s.add8(TransactionMetaNodeEntry::TMNEndOfMetadata); +} + +TransactionMetaSet::TransactionMetaSet(uint32 ledger, const std::vector& vec) : mLedger(ledger) +{ + Serializer s(vec); + SerializerIterator sit(s); + + mTransactionID = sit.get256(); + + do + { + uint256 node = sit.get256(); + if (node.isZero()) + break; + mNodes.insert(TransactionMetaNode(node, sit)); + } while(1); +} + +void TransactionMetaSet::addRaw(Serializer& s) const +{ + s.add256(mTransactionID); + for (std::set::const_iterator it = mNodes.begin(), end = mNodes.end(); + it != end; ++it) + it->addRaw(s); + s.add256(uint256()); +} diff --git a/src/TransactionMeta.h b/src/TransactionMeta.h index 97991034d4..737186c54a 100644 --- a/src/TransactionMeta.h +++ b/src/TransactionMeta.h @@ -10,6 +10,7 @@ #include "../json/value.h" #include "uint256.h" +#include "Serializer.h" #include "SerializedTypes.h" @@ -27,6 +28,7 @@ public: int getType() const { return mType; } virtual Json::Value getJson(int) const = 0; + virtual void addRaw(Serializer&) const = 0; virtual int compare(const TransactionMetaNodeEntry&) const = 0; bool operator<(const TransactionMetaNodeEntry&) const; @@ -52,6 +54,9 @@ protected: public: TMNEBalance() : TransactionMetaNodeEntry(TMNChangedBalance), mFlags(0) { ; } + TMNEBalance(SerializerIterator&); + virtual void addRaw(Serializer&) const; + unsigned getFlags() const { return mFlags; } const STAmount& getFirstAmount() const { return mFirstAmount; } const STAmount& getSecondAmount() const { return mSecondAmount; } @@ -66,6 +71,9 @@ public: class TransactionMetaNode { // a node that has been affected by a transaction +public: + typedef boost::shared_ptr pointer; + protected: uint256 mNode; uint256 mPreviousTransaction; @@ -80,10 +88,13 @@ public: uint32 getPreviousLedger() const { return mPreviousLedger; } const std::list& peekEntries() const { return mEntries; } - 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; } - 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; } + bool operator>(const TransactionMetaNode& n) const { return mNode > n.mNode; } + bool operator>=(const TransactionMetaNode& n) const { return mNode >= n.mNode; } + + TransactionMetaNode(const uint256&node, SerializerIterator&); + void addRaw(Serializer&) const; }; class TransactionMetaSet @@ -91,7 +102,7 @@ class TransactionMetaSet protected: uint256 mTransactionID; uint32 mLedger; - std::set mEntries; + std::set mNodes; public: TransactionMetaSet(const uint256& txID, uint32 ledger) : mTransactionID(txID), mLedger(ledger) From f9e8a77d9042960494639f5a6f220cb41eaa6a2c Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 24 Jul 2012 13:27:57 -0700 Subject: [PATCH 4/4] Bugfix and some more missing pieces. --- src/TransactionMeta.cpp | 36 ++++++++++++++++++++++++++++++++++-- src/TransactionMeta.h | 6 +++--- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/TransactionMeta.cpp b/src/TransactionMeta.cpp index b1c80d348d..4c3eee3c3d 100644 --- a/src/TransactionMeta.cpp +++ b/src/TransactionMeta.cpp @@ -99,7 +99,7 @@ TransactionMetaNode::TransactionMetaNode(const uint256& node, SerializerIterator { type = sit.get8(); if (type == TransactionMetaNodeEntry::TMNChangedBalance) - mEntries.push_back(boost::shared_ptr(new TMNEBalance(sit))); + mEntries.insert(boost::shared_ptr(new TMNEBalance(sit))); else if (type != TransactionMetaNodeEntry::TMNEndOfMetadata) throw std::runtime_error("Unparseable metadata"); } while (type != TransactionMetaNodeEntry::TMNEndOfMetadata); @@ -110,12 +110,28 @@ void TransactionMetaNode::addRaw(Serializer& s) const s.add256(mNode); s.add256(mPreviousTransaction); s.add32(mPreviousLedger); - for (std::list::const_iterator it = mEntries.begin(), end = mEntries.end(); + for (std::set::const_iterator it = mEntries.begin(), end = mEntries.end(); it != end; ++it) (*it)->addRaw(s); s.add8(TransactionMetaNodeEntry::TMNEndOfMetadata); } +Json::Value TransactionMetaNode::getJson(int v) const +{ + Json::Value ret = Json::objectValue; + ret["node"] = mNode.GetHex(); + ret["previous_transaction"] = mPreviousTransaction.GetHex(); + ret["previous_ledger"] = mPreviousLedger; + + Json::Value e = Json::arrayValue; + for (std::set::const_iterator it = mEntries.begin(), end = mEntries.end(); + it != end; ++it) + e.append((*it)->getJson(v)); + ret["entries"] = e; + + return ret; +} + TransactionMetaSet::TransactionMetaSet(uint32 ledger, const std::vector& vec) : mLedger(ledger) { Serializer s(vec); @@ -140,3 +156,19 @@ void TransactionMetaSet::addRaw(Serializer& s) const it->addRaw(s); s.add256(uint256()); } + +Json::Value TransactionMetaSet::getJson(int v) const +{ + Json::Value ret = Json::objectValue; + + ret["transaction_id"] = mTransactionID.GetHex(); + ret["ledger"] = mLedger; + + Json::Value e = Json::arrayValue; + for (std::set::const_iterator it = mNodes.begin(), end = mNodes.end(); + it != end; ++it) + e.append(it->getJson(v)); + ret["nodes_affected"] = e; + + return ret; +} diff --git a/src/TransactionMeta.h b/src/TransactionMeta.h index 737186c54a..4805562e5c 100644 --- a/src/TransactionMeta.h +++ b/src/TransactionMeta.h @@ -2,7 +2,6 @@ #define __TRANSACTIONMETA__ #include -#include #include #include @@ -78,7 +77,7 @@ protected: uint256 mNode; uint256 mPreviousTransaction; uint32 mPreviousLedger; - std::list mEntries; + std::set mEntries; public: TransactionMetaNode(const uint256 &node) : mNode(node) { ; } @@ -86,7 +85,7 @@ public: const uint256& getNode() const { return mNode; } const uint256& getPreviousTransaction() const { return mPreviousTransaction; } uint32 getPreviousLedger() const { return mPreviousLedger; } - const std::list& peekEntries() const { return mEntries; } + const std::set& peekEntries() const { return mEntries; } bool operator<(const TransactionMetaNode& n) const { return mNode < n.mNode; } bool operator<=(const TransactionMetaNode& n) const { return mNode <= n.mNode; } @@ -95,6 +94,7 @@ public: TransactionMetaNode(const uint256&node, SerializerIterator&); void addRaw(Serializer&) const; + Json::Value getJson(int) const; }; class TransactionMetaSet