Don't create empty transactions when reading corrupted wallet

The current transaction loading code is not exception safe.
An exception during deserialization causes an empty transaction
to be left behind in the wallet.

Fix this by building the transaction separately and adding
it only to the wallet at the end.

Fixes #3333.

Rebased-from: 3127d6caf46e2e96fc701b2d44ca28c4b9d7717a 0.8.x
This commit is contained in:
Wladimir J. van der Laan 2013-12-16 17:17:39 +01:00 committed by Warren Togami
parent dab55190ec
commit 5860707b6c

View File

@ -202,16 +202,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
{
uint256 hash;
ssKey >> hash;
CWalletTx& wtx = pwallet->mapWallet[hash];
CWalletTx wtx;
ssValue >> wtx;
CValidationState state;
if (wtx.CheckTransaction(state) && (wtx.GetHash() == hash) && state.IsValid())
wtx.BindWallet(pwallet);
else
{
pwallet->mapWallet.erase(hash);
return false;
}
// Undo serialize changes in 31600
if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
@ -236,6 +233,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
if (wtx.nOrderPos == -1)
fAnyUnordered = true;
pwallet->mapWallet[hash] = wtx;
//// debug print
//printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str());
//printf(" %12"PRI64d" %s %s %s\n",