Skip to content

Commit

Permalink
multi-colored wallets
Browse files Browse the repository at this point in the history
Now coins of all colors can be kept in one wallet which would
select coins of relevant color when doing queries and operations.
(Currently selecting different color requires a restart, but that's
just user interface problem.)
Almost completely untested, I've only checked that GetBalance
returns correct value depending on color selected.
  • Loading branch information
killerstorm committed Sep 7, 2012
1 parent 73b8747 commit cc062e4
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 18 deletions.
4 changes: 0 additions & 4 deletions src/db.h
Expand Up @@ -291,10 +291,6 @@ class CDB
};


#define COLOR_UNKNOWN -2
#define COLOR_MIXED -1
#define COLOR_DEFAULT 0

/** Access to the transaction database (blkindex.dat) */
class CTxDB : public CDB
{
Expand Down
2 changes: 1 addition & 1 deletion src/init.cpp
Expand Up @@ -651,7 +651,7 @@ bool AppInit2()
int wallet_color = GetArg("-walletcolor", 0);

pwalletMain = new CWallet(wallet_name);
pwalletMain->SetColor(wallet_color);
pwalletMain->SetCurrentColor(wallet_color);
int nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun);
if (nLoadWalletRet != DB_LOAD_OK)
{
Expand Down
9 changes: 9 additions & 0 deletions src/main.h
Expand Up @@ -380,6 +380,15 @@ enum GetMinFee_mode
GMF_SEND,
};

typedef int txcolor_t;

enum TxColor
{
COLOR_UNKNOWN = -2,
COLOR_MIXED = -1,
COLOR_DEFAULT = 0
};

typedef std::map<uint256, std::pair<CTxIndex, CTransaction> > MapPrevTx;

/** The basic transaction that is broadcasted on the network and contained in
Expand Down
41 changes: 33 additions & 8 deletions src/wallet.cpp
Expand Up @@ -303,6 +303,7 @@ CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries,
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{
CWalletTx* wtx = &((*it).second);
if (!wtx->MatchesCurrentColor()) continue;
txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
}
acentries.clear();
Expand Down Expand Up @@ -431,6 +432,11 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
wtx.fFromMe = wtxIn.fFromMe;
fUpdated = true;
}
if (wtxIn.color != wtx.color)
{
wtx.color = wtxIn.color;
fUpdated = true;
}
fUpdated |= wtx.UpdateSpent(wtxIn.vfSpent);
}

Expand Down Expand Up @@ -481,19 +487,22 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl
bool CWallet::AddToWalletIfInvolvingMe(CTxDB& txdb, const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock)
{
uint256 hash = tx.GetHash();

{
LOCK(cs_wallet);
bool fExisted = mapWallet.count(hash);

if (fExisted && !fUpdate) return false;
if (fExisted || IsMine(tx) || IsFromMe(tx))
{
int txcolor = tx.GetColor(txdb);

if (!((txcolor == color) || ((txcolor == COLOR_MIXED) && (color == 0))))
return false; // wrong color

CWalletTx wtx(this,tx);

// we do it manually since reading color requires txdb
// and transaction has no access to it
// (or rather, reading color via its own txdb causes deadlock)
txcolor_t color = tx.GetColor(txdb);
wtx.SetColor(color);

// Get merkle branch if transaction was found in a block
if (pblock)
wtx.SetMerkleBranch(pblock);
Expand Down Expand Up @@ -570,6 +579,15 @@ bool CWallet::IsChange(const CTxOut& txout) const
return false;
}

bool CWalletTx::MatchesCurrentColor(txcolor_t currentColor) const
{
return (color == currentColor)
|| ((currentColor == COLOR_DEFAULT) && (color == COLOR_MIXED))
|| (currentColor == COLOR_MIXED)
|| (currentColor == COLOR_UNKNOWN);

}

int64 CWalletTx::GetTxTime() const
{
int64 n = nTimeSmart;
Expand Down Expand Up @@ -936,7 +954,7 @@ int64 CWallet::GetBalance() const
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{
const CWalletTx* pcoin = &(*it).second;
if (pcoin->IsFinal() && pcoin->IsConfirmed())
if (pcoin->MatchesCurrentColor() && pcoin->IsFinal() && pcoin->IsConfirmed())
nTotal += pcoin->GetAvailableCredit();
}
}
Expand All @@ -952,7 +970,7 @@ int64 CWallet::GetUnconfirmedBalance() const
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{
const CWalletTx* pcoin = &(*it).second;
if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
if (pcoin->MatchesCurrentColor() && (!pcoin->IsFinal() || !pcoin->IsConfirmed()))
nTotal += pcoin->GetAvailableCredit();
}
}
Expand Down Expand Up @@ -994,6 +1012,9 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed) const
if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
continue;

if (!pcoin->MatchesCurrentColor())
continue;

for (unsigned int i = 0; i < pcoin->vout.size(); i++)
if (!(pcoin->IsSpent(i)) && IsMine(pcoin->vout[i]) && pcoin->vout[i].nValue > 0)
vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain()));
Expand Down Expand Up @@ -1164,6 +1185,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW
return false;

wtxNew.BindWallet(this);
wtxNew.SetColor(currentColor);

{
LOCK2(cs_main, cs_wallet);
Expand Down Expand Up @@ -1638,6 +1660,9 @@ std::map<CTxDestination, int64> CWallet::GetAddressBalances()
if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
continue;

if (!pcoin->MatchesCurrentColor())
continue;

int nDepth = pcoin->GetDepthInMainChain();
if (nDepth < (pcoin->IsFromMe() ? 0 : 1))
continue;
Expand Down
24 changes: 19 additions & 5 deletions src/wallet.h
Expand Up @@ -86,8 +86,7 @@ class CWallet : public CCryptoKeyStore

std::set<int64> setKeyPool;

int color;

txcolor_t currentColor;

typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
MasterKeyMap mapMasterKeys;
Expand All @@ -100,7 +99,7 @@ class CWallet : public CCryptoKeyStore
fFileBacked = false;
nMasterKeyMaxID = 0;
pwalletdbEncryption = NULL;
color = 0;
currentColor = COLOR_UNKNOWN;
}
CWallet(std::string strWalletFileIn)
{
Expand All @@ -110,7 +109,7 @@ class CWallet : public CCryptoKeyStore
fFileBacked = true;
nMasterKeyMaxID = 0;
pwalletdbEncryption = NULL;
color = 0;
currentColor = COLOR_UNKNOWN;
}

std::map<uint256, CWalletTx> mapWallet;
Expand Down Expand Up @@ -293,7 +292,7 @@ class CWallet : public CCryptoKeyStore
// get the current wallet format (the oldest client version guaranteed to understand this wallet)
int GetVersion() { return nWalletVersion; }

void SetColor(int color) { this->color = color; }
void SetCurrentColor(int color) { this->currentColor = color; }

/** Address book entry changed.
* @note called with lock cs_wallet held.
Expand Down Expand Up @@ -373,6 +372,9 @@ class CWalletTx : public CMerkleTx
std::string strFromAccount;
std::vector<char> vfSpent; // which outputs are already spent
int64 nOrderPos; // position in ordered transaction list
txcolor_t color;



// memory only
mutable bool fDebitCached;
Expand Down Expand Up @@ -425,6 +427,7 @@ class CWalletTx : public CMerkleTx
nAvailableCreditCached = 0;
nChangeCached = 0;
nOrderPos = -1;
color = COLOR_UNKNOWN;
}

IMPLEMENT_SERIALIZE
Expand All @@ -437,6 +440,7 @@ class CWalletTx : public CMerkleTx
if (!fRead)
{
pthis->mapValue["fromaccount"] = pthis->strFromAccount;
pthis->mapValue["color"] = i64tostr(pthis->color);

std::string str;
BOOST_FOREACH(char f, vfSpent)
Expand Down Expand Up @@ -465,6 +469,7 @@ class CWalletTx : public CMerkleTx
if (fRead)
{
pthis->strFromAccount = pthis->mapValue["fromaccount"];
pthis->color = atoi64(pthis->mapValue["color"].c_str());

if (mapValue.count("spent"))
BOOST_FOREACH(char c, pthis->mapValue["spent"])
Expand All @@ -481,6 +486,7 @@ class CWalletTx : public CMerkleTx
pthis->mapValue.erase("version");
pthis->mapValue.erase("spent");
pthis->mapValue.erase("n");
pthis->mapValue.erase("color");
pthis->mapValue.erase("timesmart");
)

Expand Down Expand Up @@ -655,6 +661,14 @@ class CWalletTx : public CMerkleTx
return true;
}

void SetColor(txcolor_t color) { this->color = color; }
bool MatchesCurrentColor(txcolor_t currentColor) const;
bool MatchesCurrentColor() const
{
return MatchesCurrentColor(pwallet->currentColor);
}


bool WriteToDisk();

int64 GetTxTime() const;
Expand Down

0 comments on commit cc062e4

Please sign in to comment.