diff --git a/src/TransactionMeta.cpp b/src/TransactionMeta.cpp index d1372ebdc..33840cc10 100644 --- a/src/TransactionMeta.cpp +++ b/src/TransactionMeta.cpp @@ -6,314 +6,50 @@ #include #include -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; -} - -TMNEThread::TMNEThread(SerializerIterator& sit) : TransactionMetaNodeEntry(TMSThread) -{ - mPrevTxID = sit.get256(); - mPrevLgrSeq = sit.get32(); -} - -void TMNEThread::addRaw(Serializer& sit) const -{ - sit.add8(mType); - sit.add256(mPrevTxID); - sit.add32(mPrevLgrSeq); -} - -int TMNEThread::compare(const TransactionMetaNodeEntry&) const -{ - assert(false); // should never be two entries for the same node (as of now) - return 0; -} - -Json::Value TMNEThread::getJson(int) const -{ - Json::Value inner(Json::objectValue); - inner["prev_transaction"] = mPrevTxID.GetHex(); - inner["prev_ledger_seq"] = mPrevLgrSeq; - - Json::Value outer(Json::objectValue); - outer["thread"] = inner; - return outer; -} - -TMNEAmount::TMNEAmount(int type, SerializerIterator& sit) : TransactionMetaNodeEntry(type) -{ - mAmount = *dynamic_cast(STAmount::deserialize(sit, sfAmount).get()); // Ouch -} - -void TMNEAmount::addRaw(Serializer& s) const -{ - s.add8(mType); - mAmount.add(s); -} - -Json::Value TMNEAmount::getJson(int v) const -{ - Json::Value outer(Json::objectValue); - switch (mType) - { - case TMSPrevBalance: outer["prev_balance"] = mAmount.getJson(v); break; - case TMSFinalBalance: outer["final_balance"] = mAmount.getJson(v); break; - case TMSPrevTakerPays: outer["prev_taker_pays"] = mAmount.getJson(v); break; - case TMSPrevTakerGets: outer["prev_taker_gets"] = mAmount.getJson(v); break; - case TMSFinalTakerPays: outer["final_taker_pays"] = mAmount.getJson(v); break; - case TMSFinalTakerGets: outer["final_taker_gets"] = mAmount.getJson(v); break; - default: assert(false); - } - return outer; -} - -int TMNEAmount::compare(const TransactionMetaNodeEntry& e) const -{ - assert(false); // can't be two changed amounts of same type - return 0; -} - -TMNEAccount::TMNEAccount(int type, SerializerIterator& sit) - : TransactionMetaNodeEntry(type), mAccount(STAccount(sit.getVL()).getValueNCA()) -{ ; } - -void TMNEAccount::addRaw(Serializer& sit) const -{ - sit.add8(mType); - - STAccount sta; - sta.setValueNCA(mAccount); - sta.add(sit); -} - -Json::Value TMNEAccount::getJson(int) const -{ - Json::Value outer(Json::objectValue); - switch (mType) - { - case TMSPrevAccount: outer["prev_account"] = mAccount.humanAccountID(); break; - case TMSLowID: outer["lowID"] = mAccount.humanAccountID(); break; - case TMSHighID: outer["highID"] = mAccount.humanAccountID(); break; - default: assert(false); - } - return outer; -} - -int TMNEAccount::compare(const TransactionMetaNodeEntry&) const -{ - assert(false); // Can't be two modified accounts of same type for same node - return 0; -} - -TransactionMetaNode::TransactionMetaNode(int type, const uint256& node, SerializerIterator& sit) - : mType(type), mNode(node) -{ - while (1) - { - int nType = sit.get8(); - switch (nType) - { - case TMSEndOfNode: - return; - - case TMSThread: - mEntries.push_back(new TMNEThread(sit)); - break; - - // Nodes that contain an amount - case TMSPrevBalance: - case TMSPrevTakerPays: - case TMSPrevTakerGets: - case TMSFinalTakerPays: - case TMSFinalTakerGets: - mEntries.push_back(new TMNEAmount(nType, sit)); - - case TMSPrevAccount: - mEntries.push_back(new TMNEAccount(nType, sit)); - } - } -} - -void TransactionMetaNode::addRaw(Serializer& s) -{ - s.add8(mType); - s.add256(mNode); - mEntries.sort(); - BOOST_FOREACH(TransactionMetaNodeEntry& it, mEntries) - it.addRaw(s); - s.add8(TMSEndOfNode); -} - -TransactionMetaNodeEntry* TransactionMetaNode::findEntry(int nodeType) -{ - BOOST_FOREACH(TransactionMetaNodeEntry& it, mEntries) - if (it.getType() == nodeType) - return ⁢ - return NULL; -} - -TMNEAmount* TransactionMetaNode::findAmount(int nType) -{ - BOOST_FOREACH(TransactionMetaNodeEntry& it, mEntries) - if (it.getType() == nType) - return dynamic_cast(&it); - TMNEAmount* node = new TMNEAmount(nType); - mEntries.push_back(node); - return node; -} - -void TransactionMetaNode::addNode(TransactionMetaNodeEntry* node) -{ - mEntries.push_back(node); -} - -bool TransactionMetaNode::thread(const uint256& prevTx, uint32 prevLgr) -{ - BOOST_FOREACH(TransactionMetaNodeEntry& it, mEntries) - if (it.getType() == TMSThread) - { - TMNEThread* a = dynamic_cast(&it); - assert(a && (a->getPrevTxID() == prevTx) && (a->getPrevLgr() == prevLgr)); - return false; - } - addNode(new TMNEThread(prevTx, prevLgr)); - return true; -} - -bool TransactionMetaNode::addAmount(int nodeType, const STAmount& amount) -{ - BOOST_FOREACH(TransactionMetaNodeEntry& it, mEntries) - if (it.getType() == nodeType) - { - TMNEAmount* a = dynamic_cast(&it); - assert(a && (a->getAmount() == amount)); - return false; - } - addNode(new TMNEAmount(nodeType, amount)); - return true; -} - -bool TransactionMetaNode::addAccount(int nodeType, const NewcoinAddress& account) -{ - BOOST_FOREACH(TransactionMetaNodeEntry& it, mEntries) - if (it.getType() == nodeType) - { - TMNEAccount* a = dynamic_cast(&it); - assert(a && (a->getAccount() == account)); - return false; - } - addNode(new TMNEAccount(nodeType, account)); - return true; -} - -Json::Value TransactionMetaNode::getJson(int v) const -{ - Json::Value ret = Json::objectValue; - - switch (mType) - { - case TMNCreatedNode: ret["action"] = "create"; break; - case TMNDeletedNode: ret["action"] = "delete"; break; - case TMNModifiedNode: ret["action"] = "modify"; break; - default: - assert(false); - } - - ret["node"] = mNode.GetHex(); - - Json::Value e = Json::arrayValue; - BOOST_FOREACH(const TransactionMetaNodeEntry& it, mEntries) - e.append(it.getJson(v)); - ret["entries"] = e; - - return ret; -} - -TransactionMetaSet::TransactionMetaSet(uint32 ledger, const std::vector& vec) : mLedger(ledger) +TransactionMetaSet::TransactionMetaSet(const uint256& txid, uint32 ledger, const std::vector& vec) : + mTransactionID(txid), mLedger(ledger), mNodes(sfTransactionMetaData) { Serializer s(vec); SerializerIterator sit(s); - mTransactionID = sit.get256(); - - int type; - while ((type = sit.get8()) != TMNEndOfMetadata) - { - uint256 node = sit.get256(); - mNodes.insert(std::make_pair(node, TransactionMetaNode(type, node, sit))); - } -} - -void TransactionMetaSet::addRaw(Serializer& s) -{ - s.add256(mTransactionID); - for (std::map::iterator it = mNodes.begin(), end = mNodes.end(); it != end; ++it) - it->second.addRaw(s); - s.add8(TMNEndOfMetadata); -} - -Json::Value TransactionMetaSet::getJson(int v) const -{ - Json::Value ret = Json::objectValue; - - ret["hash"] = mTransactionID.GetHex(); - ret["ledger"] = mLedger; - - Json::Value e = Json::arrayValue; - for (std::map::const_iterator it = mNodes.begin(), end = mNodes.end(); - it != end; ++it) - e.append(it->second.getJson(v)); - ret["nodes_affected"] = e; - - return ret; + std::auto_ptr obj = STArray::deserialize(sit, sfTransactionMetaData); + mNodes = * static_cast(obj.get()); } bool TransactionMetaSet::isNodeAffected(const uint256& node) const { - return mNodes.find(node) != mNodes.end(); + for (STArray::const_iterator it = mNodes.begin(); it != mNodes.end(); ++it) + if (it->getFieldH256(sfLedgerIndex) == node) + return true; + return false; } -TransactionMetaNode& TransactionMetaSet::getAffectedNode(const uint256& node, int type, bool overrideType) +STObject& TransactionMetaSet::getAffectedNode(const uint256& node, SField::ref type, bool overrideType) { - std::map::iterator it = mNodes.find(node); - if (it != mNodes.end()) + for (STArray::iterator it = mNodes.begin(); it != mNodes.end(); ++it) { - if (overrideType) - it->second.setType(type); - return it->second; + if (it->getFieldH256(sfLedgerIndex) == node) + { + if (overrideType) + it->setFName(type); + return *it; + } } - return mNodes.insert(std::make_pair(node, TransactionMetaNode(node, type))).first->second; + + mNodes.push_back(STObject(type)); + STObject& obj = mNodes.back(); + + assert(obj.getFName() == type); + obj.setFieldH256(sfLedgerIndex, node); + + return mNodes.back(); } -const TransactionMetaNode& TransactionMetaSet::peekAffectedNode(const uint256& node) const +const STObject& TransactionMetaSet::peekAffectedNode(const uint256& node) const { - std::map::const_iterator it = mNodes.find(node); - if (it != mNodes.end()) - return it->second; + for (STArray::const_iterator it = mNodes.begin(); it != mNodes.end(); ++it) + if (it->getFieldH256(sfLedgerIndex) == node) + return *it; throw std::runtime_error("Affected node not found"); } @@ -321,7 +57,7 @@ void TransactionMetaSet::init(const uint256& id, uint32 ledger) { mTransactionID = id; mLedger = ledger; - mNodes.clear(); + mNodes = STArray(sfTransactionMetaData); } void TransactionMetaSet::swap(TransactionMetaSet& s) @@ -330,4 +66,29 @@ void TransactionMetaSet::swap(TransactionMetaSet& s) mNodes.swap(s.mNodes); } +bool TransactionMetaSet::thread(STObject& node, const uint256& prevTxID, uint32 prevLgrID) +{ + if (node.getFieldIndex(sfLastTxnID) == -1) + { + assert(node.getFieldIndex(sfLastTxnSeq) == -1); + node.setFieldH256(sfLastTxnID, prevTxID); + node.setFieldU32(sfLastTxnSeq, prevLgrID); + return true; + } + assert(node.getFieldH256(sfLastTxnID) == prevTxID); + assert(node.getFieldU32(sfLastTxnSeq) == prevLgrID); + return false; +} + +static bool compare(const STObject& o1, const STObject& o2) +{ + return o1.getFieldH256(sfLedgerIndex) < o2.getFieldH256(sfLedgerIndex); +} + +void TransactionMetaSet::addRaw(Serializer& s) +{ + mNodes.sort(compare); + mNodes.add(s); +} + // vim:ts=4 diff --git a/src/TransactionMeta.h b/src/TransactionMeta.h index b329fdb61..90623b8de 100644 --- a/src/TransactionMeta.h +++ b/src/TransactionMeta.h @@ -11,164 +11,7 @@ #include "uint256.h" #include "Serializer.h" #include "SerializedTypes.h" - -// master record types -static const int TMNEndOfMetadata = 0x00; -static const int TMNCreatedNode = 0x10; // This transaction created this node -static const int TMNDeletedNode = 0x11; -static const int TMNModifiedNode = 0x12; - -// sub record types - special -static const int TMSEndOfNode = 0x00; -static const int TMSThread = 0x01; // Holds previous TxID and LgrSeq for threading - -// sub record types - containing an amount -static const int TMSPrevBalance = 0x11; // Balances prior to the transaction -static const int TMSFinalBalance = 0x12; // deleted with non-zero balance -static const int TMSPrevTakerPays = 0x13; -static const int TMSPrevTakerGets = 0x14; -static const int TMSFinalTakerPays = 0x15; // Balances at node deletion time -static const int TMSFinalTakerGets = 0x16; - -// sub record types - containing an account (for example, for when a nickname is transferred) -static const int TMSPrevAccount = 0x20; -static const int TMSLowID = 0x21; -static const int TMSHighID = 0x22; - - -class TransactionMetaNodeEntry -{ // a way that a transaction has affected a node -public: - typedef boost::shared_ptr pointer; - -protected: - int mType; - -public: - TransactionMetaNodeEntry(int type) : mType(type) { ; } - virtual ~TransactionMetaNodeEntry() { ; } - - int getType() const { return mType; } - virtual Json::Value getJson(int) const = 0; - virtual void addRaw(Serializer&) const = 0; - - bool operator<(const TransactionMetaNodeEntry&) const; - bool operator<=(const TransactionMetaNodeEntry&) const; - bool operator>(const TransactionMetaNodeEntry&) const; - bool operator>=(const TransactionMetaNodeEntry&) const; - - virtual std::auto_ptr clone() const - { return std::auto_ptr(duplicate()); } - -protected: - virtual int compare(const TransactionMetaNodeEntry&) const = 0; - virtual TransactionMetaNodeEntry* duplicate(void) const = 0; -}; - -class TMNEThread : public TransactionMetaNodeEntry -{ -protected: - uint256 mPrevTxID; - uint32 mPrevLgrSeq; - -public: - TMNEThread() : TransactionMetaNodeEntry(TMSThread), mPrevLgrSeq(0) { ; } - TMNEThread(uint256 prevTx, uint32 prevLgrSeq) - : TransactionMetaNodeEntry(TMSThread), mPrevTxID(prevTx), mPrevLgrSeq(prevLgrSeq) - { ; } - TMNEThread(SerializerIterator&); - - virtual void addRaw(Serializer&) const; - virtual Json::Value getJson(int) const; - - const uint256& getPrevTxID() const { return mPrevTxID; } - uint32 getPrevLgr() const { return mPrevLgrSeq; } - -protected: - virtual TransactionMetaNodeEntry* duplicate(void) const { return new TMNEThread(*this); } - virtual int compare(const TransactionMetaNodeEntry&) const; -}; - -class TMNEAmount : public TransactionMetaNodeEntry -{ // a transaction affected the balance of a node -protected: - STAmount mAmount; - -public: - TMNEAmount(int type) : TransactionMetaNodeEntry(type) { ; } - TMNEAmount(int type, const STAmount &a) : TransactionMetaNodeEntry(type), mAmount(a) { ; } - - TMNEAmount(int type, SerializerIterator&); - virtual void addRaw(Serializer&) const; - - const STAmount& getAmount() const { return mAmount; } - void setAmount(const STAmount& a) { mAmount = a; } - - virtual Json::Value getJson(int) const; - -protected: - virtual TransactionMetaNodeEntry* duplicate(void) const { return new TMNEAmount(*this); } - virtual int compare(const TransactionMetaNodeEntry&) const; -}; - -class TMNEAccount : public TransactionMetaNodeEntry -{ // node was deleted because it was unfunded -protected: - NewcoinAddress mAccount; - -public: - TMNEAccount(int type, const NewcoinAddress& acct) : TransactionMetaNodeEntry(type), mAccount(acct) { ; } - TMNEAccount(int type, SerializerIterator&); - virtual void addRaw(Serializer&) const; - virtual Json::Value getJson(int) const; - - const NewcoinAddress& getAccount() const { return mAccount; } - void setAccount(const NewcoinAddress& a) { mAccount = a; } - -protected: - virtual TransactionMetaNodeEntry* duplicate(void) const { return new TMNEAccount(*this); } - virtual int compare(const TransactionMetaNodeEntry&) const; -}; - -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: - typedef boost::shared_ptr pointer; - -protected: - int mType; - uint256 mNode; - boost::ptr_vector mEntries; - -public: - TransactionMetaNode(const uint256 &node, int type) : mType(type), mNode(node) { ; } - - const uint256& getNode() const { return mNode; } - 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; } - bool operator>=(const TransactionMetaNode& n) const { return mNode >= n.mNode; } - - bool thread(const uint256& prevTx, uint32 prevLgr); - - TransactionMetaNode(int type, const uint256& node, SerializerIterator&); - void addRaw(Serializer&); - void setType(int t) { mType = t; } - Json::Value getJson(int) const; - - bool addAmount(int nodeType, const STAmount& amount); - bool addAccount(int nodeType, const NewcoinAddress& account); - TMNEAmount* findAmount(int nodeType); -}; - +#include "SerializedObject.h" class TransactionMetaSet { @@ -178,12 +21,13 @@ public: protected: uint256 mTransactionID; uint32 mLedger; - std::map mNodes; // must be an ordered set + + STArray mNodes; public: TransactionMetaSet() : mLedger(0) { ; } TransactionMetaSet(const uint256& txID, uint32 ledger) : mTransactionID(txID), mLedger(ledger) { ; } - TransactionMetaSet(uint32 ledger, const std::vector&); + TransactionMetaSet(const uint256& txID, uint32 ledger, const std::vector&); void init(const uint256& transactionID, uint32 ledger); void clear() { mNodes.clear(); } @@ -193,11 +37,13 @@ public: uint32 getLgrSeq() { return mLedger; } bool isNodeAffected(const uint256&) const; - TransactionMetaNode& getAffectedNode(const uint256&, int type, bool overrideType); - const TransactionMetaNode& peekAffectedNode(const uint256&) const; + STObject& getAffectedNode(const uint256&, SField::ref type, bool overrideType); + const STObject& peekAffectedNode(const uint256&) const; - Json::Value getJson(int) const; + Json::Value getJson(int p) const { return mNodes.getJson(p); } void addRaw(Serializer&); + + static bool thread(STObject& node, const uint256& prevTxID, uint32 prevLgrID); }; #endif