Do not store Merkle branches in the wallet.
Assume that when a wallet transaction has a valid block hash and transaction position in it, the transaction is actually there. We're already trusting wallet data in a much more fundamental way anyway. To prevent backward compatibility issues, a new record is used for storing the block locator in the wallet. Old wallets will see a wallet file synchronized up to the genesis block, and rescan automatically.
This commit is contained in:
@@ -702,9 +702,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD
|
||||
wtx.hashBlock = wtxIn.hashBlock;
|
||||
fUpdated = true;
|
||||
}
|
||||
if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
|
||||
if (wtxIn.nIndex != -1 && (wtxIn.nIndex != wtx.nIndex))
|
||||
{
|
||||
wtx.vMerkleBranch = wtxIn.vMerkleBranch;
|
||||
wtx.nIndex = wtxIn.nIndex;
|
||||
fUpdated = true;
|
||||
}
|
||||
@@ -2812,15 +2811,11 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block)
|
||||
break;
|
||||
if (nIndex == (int)block.vtx.size())
|
||||
{
|
||||
vMerkleBranch.clear();
|
||||
nIndex = -1;
|
||||
LogPrintf("ERROR: SetMerkleBranch(): couldn't find tx in block\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Fill in merkle branch
|
||||
vMerkleBranch = block.GetMerkleBranch(nIndex);
|
||||
|
||||
// Is the tx in a block that's in the main chain
|
||||
BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
|
||||
if (mi == mapBlockIndex.end())
|
||||
@@ -2846,14 +2841,6 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const
|
||||
if (!pindex || !chainActive.Contains(pindex))
|
||||
return 0;
|
||||
|
||||
// Make sure the merkle branch connects to this block
|
||||
if (!fMerkleVerified)
|
||||
{
|
||||
if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
|
||||
return 0;
|
||||
fMerkleVerified = true;
|
||||
}
|
||||
|
||||
pindexRet = pindex;
|
||||
return chainActive.Height() - pindex->nHeight + 1;
|
||||
}
|
||||
|
||||
@@ -151,13 +151,8 @@ private:
|
||||
|
||||
public:
|
||||
uint256 hashBlock;
|
||||
std::vector<uint256> vMerkleBranch;
|
||||
int nIndex;
|
||||
|
||||
// memory only
|
||||
mutable bool fMerkleVerified;
|
||||
|
||||
|
||||
CMerkleTx()
|
||||
{
|
||||
Init();
|
||||
@@ -172,13 +167,13 @@ public:
|
||||
{
|
||||
hashBlock = uint256();
|
||||
nIndex = -1;
|
||||
fMerkleVerified = false;
|
||||
}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
std::vector<uint256> vMerkleBranch; // For compatibility with older versions.
|
||||
READWRITE(*(CTransaction*)this);
|
||||
nVersion = this->nVersion;
|
||||
READWRITE(hashBlock);
|
||||
|
||||
@@ -131,12 +131,14 @@ bool CWalletDB::EraseWatchOnly(const CScript &dest)
|
||||
bool CWalletDB::WriteBestBlock(const CBlockLocator& locator)
|
||||
{
|
||||
nWalletDBUpdated++;
|
||||
return Write(std::string("bestblock"), locator);
|
||||
Write(std::string("bestblock"), CBlockLocator()); // Write empty block locator so versions that require a merkle branch automatically rescan
|
||||
return Write(std::string("bestblock_nomerkle"), locator);
|
||||
}
|
||||
|
||||
bool CWalletDB::ReadBestBlock(CBlockLocator& locator)
|
||||
{
|
||||
return Read(std::string("bestblock"), locator);
|
||||
if (Read(std::string("bestblock"), locator) && !locator.vHave.empty()) return true;
|
||||
return Read(std::string("bestblock_nomerkle"), locator);
|
||||
}
|
||||
|
||||
bool CWalletDB::WriteOrderPosNext(int64_t nOrderPosNext)
|
||||
|
||||
Reference in New Issue
Block a user