From d2336e3eea2d9d27e417d9aae1efef6c52d944ff Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Wed, 12 Sep 2012 18:40:16 -0700 Subject: [PATCH] Ledger functions to handle transaction metadata. --- src/Ledger.cpp | 49 +++++++++++++++++++++++++++++++++++++++++-- src/Ledger.h | 7 +++++-- src/SHAMap.cpp | 10 +++++++++ src/SHAMap.h | 1 + src/TransactionMeta.h | 3 +++ 5 files changed, 66 insertions(+), 4 deletions(-) diff --git a/src/Ledger.cpp b/src/Ledger.cpp index 1885439f2..00b647c8b 100644 --- a/src/Ledger.cpp +++ b/src/Ledger.cpp @@ -214,7 +214,18 @@ RippleState::pointer Ledger::accessRippleState(const uint256& uNode) bool Ledger::addTransaction(const uint256& txID, const Serializer& txn) { // low-level - just add to table SHAMapItem::pointer item = boost::make_shared(txID, txn.peekData()); - if (!mTransactionMap->addGiveItem(item, true, false)) // FIXME: TX metadata + if (!mTransactionMap->addGiveItem(item, true, false)) + return false; + return true; +} + +bool Ledger::addTransaction(const uint256& txID, const Serializer& txn, const Serializer& md) +{ // low-level - just add to table + Serializer s(txn.getDataLength() + md.getDataLength() + 64); + s.addVL(txn.peekData()); + s.addVL(md.peekData()); + SHAMapItem::pointer item = boost::make_shared(txID, s.peekData()); + if (!mTransactionMap->addGiveItem(item, true, true)) return false; return true; } @@ -225,7 +236,8 @@ Transaction::pointer Ledger::getTransaction(const uint256& transID) const if (!item) return Transaction::pointer(); Transaction::pointer txn = theApp->getMasterTransaction().fetch(transID, false); - if (txn) return txn; + if (txn) + return txn; txn = Transaction::sharedTransaction(item->getData(), true); if (txn->getStatus() == NEW) @@ -235,6 +247,39 @@ Transaction::pointer Ledger::getTransaction(const uint256& transID) const return txn; } +bool Ledger::getTransaction(const uint256& txID, Transaction::pointer& txn, TransactionMetaSet::pointer& meta) +{ + SHAMapTreeNode::TNType type; + SHAMapItem::pointer item = mTransactionMap->peekItem(txID, type); + if (!item) + return false; + + if (type == SHAMapTreeNode::tnTRANSACTION_NM) + { // in tree with no metadata + txn = theApp->getMasterTransaction().fetch(txID, false); + meta = TransactionMetaSet::pointer(); + if (!txn) + txn = Transaction::sharedTransaction(item->getData(), true); + } + else if (type == SHAMapTreeNode::tnTRANSACTION_MD) + { // in tree with metadata + SerializerIterator it(item->getData()); + txn = theApp->getMasterTransaction().fetch(txID, false); + if (!txn) + txn = Transaction::sharedTransaction(it.getVL(), true); + else + it.getVL(); // skip transaction + meta = boost::make_shared(mLedgerSeq, it.getVL()); + } + else + return false; + + if (txn->getStatus() == NEW) + txn->setStatus(mClosed ? COMMITTED : INCLUDED, mLedgerSeq); + theApp->getMasterTransaction().canonicalize(txn, false); + return true; +} + bool Ledger::unitTest() { return true; diff --git a/src/Ledger.h b/src/Ledger.h index a0a274e94..d059f0158 100644 --- a/src/Ledger.h +++ b/src/Ledger.h @@ -11,6 +11,7 @@ #include "../json/value.h" #include "Transaction.h" +#include "TransactionMeta.h" #include "AccountState.h" #include "RippleState.h" #include "NicknameState.h" @@ -56,7 +57,7 @@ public: TR_PASTASEQ = 6, // account is past this transaction TR_PREASEQ = 7, // account is missing transactions before this TR_BADLSEQ = 8, // ledger too early - TR_TOOSMALL = 9, // amount is less than Tx fee + TR_TOOSMALL = 9, // amount is less than Tx fee }; // ledger close flags @@ -82,7 +83,6 @@ private: protected: - bool addTransaction(const uint256& id, const Serializer& txn); static Ledger::pointer getSQL(const std::string& sqlStatement); @@ -151,8 +151,11 @@ public: bool isAcquiringAS(void); // Transaction Functions + bool addTransaction(const uint256& id, const Serializer& txn); + bool addTransaction(const uint256& id, const Serializer& txn, const Serializer& metaData); bool hasTransaction(const uint256& TransID) const { return mTransactionMap->hasItem(TransID); } Transaction::pointer getTransaction(const uint256& transID) const; + bool getTransaction(const uint256& transID, Transaction::pointer& txn, TransactionMetaSet::pointer& txMeta); // high-level functions AccountState::pointer getAccountState(const NewcoinAddress& acctID); diff --git a/src/SHAMap.cpp b/src/SHAMap.cpp index 8ae69c405..8a232ec54 100644 --- a/src/SHAMap.cpp +++ b/src/SHAMap.cpp @@ -421,6 +421,16 @@ SHAMapItem::pointer SHAMap::peekItem(const uint256& id) return leaf->peekItem(); } +SHAMapItem::pointer SHAMap::peekItem(const uint256& id, SHAMapTreeNode::TNType& type) +{ + boost::recursive_mutex::scoped_lock sl(mLock); + SHAMapTreeNode* leaf = walkToPointer(id); + if (!leaf) + return SHAMapItem::pointer(); + type = leaf->getType(); + return leaf->peekItem(); +} + bool SHAMap::hasItem(const uint256& id) { // does the tree have an item with this ID boost::recursive_mutex::scoped_lock sl(mLock); diff --git a/src/SHAMap.h b/src/SHAMap.h index b84dcb727..0f7061d71 100644 --- a/src/SHAMap.h +++ b/src/SHAMap.h @@ -318,6 +318,7 @@ public: // save a copy if you only need a temporary SHAMapItem::pointer peekItem(const uint256& id); + SHAMapItem::pointer peekItem(const uint256& id, SHAMapTreeNode::TNType& type); // traverse functions SHAMapItem::pointer peekFirstItem(); diff --git a/src/TransactionMeta.h b/src/TransactionMeta.h index b62f9f361..10423aeda 100644 --- a/src/TransactionMeta.h +++ b/src/TransactionMeta.h @@ -168,6 +168,9 @@ public: class TransactionMetaSet { +public: + typedef boost::shared_ptr pointer; + protected: uint256 mTransactionID; uint32 mLedger;