From 9c7722b7c5ce49130bd978b932f73b629ce5cebe Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 27 May 2012 23:06:09 +0000 Subject: Store a fixed order of transactions (and accounting) in the wallet For backward compatibility, new accounting data is stored after a \0 in the comment string. This way, old versions and third-party software should load and store them, but all actual use (listtransactions, for example) ignores it. --- src/wallet.h | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) (limited to 'src/wallet.h') diff --git a/src/wallet.h b/src/wallet.h index 5bf38699ef..b32face5bf 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -5,11 +5,17 @@ #ifndef BITCOIN_WALLET_H #define BITCOIN_WALLET_H +#include +#include + +#include + #include "main.h" #include "key.h" #include "keystore.h" #include "script.h" #include "ui_interface.h" +#include "util.h" class CWalletTx; class CReserveKey; @@ -103,6 +109,7 @@ public: } std::map mapWallet; + int64 nOrderPosNext; std::map mapRequestCount; std::map mapAddressBook; @@ -304,6 +311,32 @@ public: }; +typedef std::map mapValue_t; + + +static +void +ReadOrderPos(int64& nOrderPos, mapValue_t& mapValue) +{ + if (!mapValue.count("n")) + { + nOrderPos = -1; // TODO: calculate elsewhere + return; + } + nOrderPos = atoi64(mapValue["n"].c_str()); +} + + +static +void +WriteOrderPos(const int64& nOrderPos, mapValue_t& mapValue) +{ + if (nOrderPos == -1) + return; + mapValue["n"] = i64tostr(nOrderPos); +} + + /** A transaction with a bunch of additional info that only the owner cares about. * It includes any unrecorded transactions needed to link it back to the block chain. */ @@ -314,13 +347,14 @@ private: public: std::vector vtxPrev; - std::map mapValue; + mapValue_t mapValue; std::vector > vOrderForm; unsigned int fTimeReceivedIsTxTime; unsigned int nTimeReceived; // time received by this node char fFromMe; std::string strFromAccount; std::vector vfSpent; // which outputs are already spent + int64 nOrderPos; // position in ordered transaction list // memory only mutable bool fDebitCached; @@ -371,6 +405,7 @@ public: nCreditCached = 0; nAvailableCreditCached = 0; nChangeCached = 0; + nOrderPos = -1; } IMPLEMENT_SERIALIZE @@ -392,6 +427,8 @@ public: fSpent = true; } pthis->mapValue["spent"] = str; + + WriteOrderPos(pthis->nOrderPos, pthis->mapValue); } nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action); @@ -414,9 +451,13 @@ public: pthis->vfSpent.assign(vout.size(), fSpent); } + if (fRead) + ReadOrderPos(pthis->nOrderPos, pthis->mapValue); + pthis->mapValue.erase("fromaccount"); pthis->mapValue.erase("version"); pthis->mapValue.erase("spent"); + pthis->mapValue.erase("n"); ) // marks certain txout's as spent @@ -705,6 +746,9 @@ public: int64 nTime; std::string strOtherAccount; std::string strComment; + mapValue_t mapValue; + int64 nOrderPos; // position in ordered transaction list + uint64 nEntryNo; CAccountingEntry() { @@ -718,18 +762,55 @@ public: strAccount.clear(); strOtherAccount.clear(); strComment.clear(); + nOrderPos = -1; } IMPLEMENT_SERIALIZE ( + CAccountingEntry& me = *const_cast(this); if (!(nType & SER_GETHASH)) READWRITE(nVersion); // Note: strAccount is serialized as part of the key, not here. READWRITE(nCreditDebit); READWRITE(nTime); READWRITE(strOtherAccount); + + if (!fRead) + { + WriteOrderPos(nOrderPos, me.mapValue); + + if (!(mapValue.empty() && _ssExtra.empty())) + { + CDataStream ss(nType, nVersion); + ss.insert(ss.begin(), '\0'); + ss << mapValue; + ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end()); + me.strComment.append(ss.str()); + } + } + READWRITE(strComment); + + size_t nSepPos = strComment.find("\0", 0, 1); + if (fRead) + { + me.mapValue.clear(); + if (std::string::npos != nSepPos) + { + CDataStream ss(std::vector(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion); + ss >> me.mapValue; + me._ssExtra = std::vector(ss.begin(), ss.end()); + } + ReadOrderPos(me.nOrderPos, me.mapValue); + } + if (std::string::npos != nSepPos) + me.strComment.erase(nSepPos); + + me.mapValue.erase("n"); ) + +private: + std::vector _ssExtra; }; bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut); -- cgit v1.2.3