mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 23:18:14 +01:00
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.
This commit is contained in:
83
src/wallet.h
83
src/wallet.h
@@ -5,11 +5,17 @@
|
||||
#ifndef BITCOIN_WALLET_H
|
||||
#define BITCOIN_WALLET_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#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<uint256, CWalletTx> mapWallet;
|
||||
int64 nOrderPosNext;
|
||||
std::map<uint256, int> mapRequestCount;
|
||||
|
||||
std::map<CTxDestination, std::string> mapAddressBook;
|
||||
@@ -304,6 +311,32 @@ public:
|
||||
};
|
||||
|
||||
|
||||
typedef std::map<std::string, std::string> 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<CMerkleTx> vtxPrev;
|
||||
std::map<std::string, std::string> mapValue;
|
||||
mapValue_t mapValue;
|
||||
std::vector<std::pair<std::string, std::string> > vOrderForm;
|
||||
unsigned int fTimeReceivedIsTxTime;
|
||||
unsigned int nTimeReceived; // time received by this node
|
||||
char fFromMe;
|
||||
std::string strFromAccount;
|
||||
std::vector<char> 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<CAccountingEntry*>(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<char>(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion);
|
||||
ss >> me.mapValue;
|
||||
me._ssExtra = std::vector<char>(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<char> _ssExtra;
|
||||
};
|
||||
|
||||
bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
|
||||
|
||||
Reference in New Issue
Block a user