Merge #16451: Remove CMerkleTx
05b56d1c93
[wallet] Remove CMerkleTx serialization logic (John Newbery)783a76f23b
[wallet] Flatten CWalletTx class hierarchy (John Newbery)b3a9d179f2
[wallet] Move CMerkleTx functions into CWalletTx (John Newbery) Pull request description: CMerkleTx is only used as a base class for CWalletTx. It was previously also used for vtxPrev which was removed in93a18a3650
. This PR moves all of the CMerkleTx members and logic into CWalletTx. The CMerkleTx class is kept for deserialization and serialization of old wallet files. This makes the refactor in #15931 cleaner. ACKs for top commit: laanwj: ACK05b56d1c93
. Looks good to me. Tree-SHA512: 3d3a0069ebb536b12a328f1261e7dc55158a71088d445ae4b4ace4142c432dc296f58c8183b1922e54a60b8cc77e9d17c3dce7478294cd68693594baacf2bab3
This commit is contained in:
commit
8241b51504
2 changed files with 73 additions and 86 deletions
|
@ -228,7 +228,7 @@ WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString&
|
|||
|
||||
const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000;
|
||||
|
||||
const uint256 CMerkleTx::ABANDON_HASH(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
|
||||
const uint256 CWalletTx::ABANDON_HASH(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
|
||||
|
||||
/** @defgroup mapWallet
|
||||
*
|
||||
|
@ -4627,7 +4627,7 @@ CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn, bool internalIn)
|
|||
m_pre_split = false;
|
||||
}
|
||||
|
||||
void CMerkleTx::SetMerkleBranch(const uint256& block_hash, int posInBlock)
|
||||
void CWalletTx::SetMerkleBranch(const uint256& block_hash, int posInBlock)
|
||||
{
|
||||
// Update the tx's hashBlock
|
||||
hashBlock = block_hash;
|
||||
|
@ -4636,7 +4636,7 @@ void CMerkleTx::SetMerkleBranch(const uint256& block_hash, int posInBlock)
|
|||
nIndex = posInBlock;
|
||||
}
|
||||
|
||||
int CMerkleTx::GetDepthInMainChain(interfaces::Chain::Lock& locked_chain) const
|
||||
int CWalletTx::GetDepthInMainChain(interfaces::Chain::Lock& locked_chain) const
|
||||
{
|
||||
if (hashUnset())
|
||||
return 0;
|
||||
|
@ -4644,7 +4644,7 @@ int CMerkleTx::GetDepthInMainChain(interfaces::Chain::Lock& locked_chain) const
|
|||
return locked_chain.getBlockDepth(hashBlock) * (nIndex == -1 ? -1 : 1);
|
||||
}
|
||||
|
||||
int CMerkleTx::GetBlocksToMaturity(interfaces::Chain::Lock& locked_chain) const
|
||||
int CWalletTx::GetBlocksToMaturity(interfaces::Chain::Lock& locked_chain) const
|
||||
{
|
||||
if (!IsCoinBase())
|
||||
return 0;
|
||||
|
@ -4653,7 +4653,7 @@ int CMerkleTx::GetBlocksToMaturity(interfaces::Chain::Lock& locked_chain) const
|
|||
return std::max(0, (COINBASE_MATURITY+1) - chain_depth);
|
||||
}
|
||||
|
||||
bool CMerkleTx::IsImmatureCoinBase(interfaces::Chain::Lock& locked_chain) const
|
||||
bool CWalletTx::IsImmatureCoinBase(interfaces::Chain::Lock& locked_chain) const
|
||||
{
|
||||
// note GetBlocksToMaturity is 0 for non-coinbase tx
|
||||
return GetBlocksToMaturity(locked_chain) > 0;
|
||||
|
|
|
@ -364,82 +364,24 @@ struct COutputEntry
|
|||
int vout;
|
||||
};
|
||||
|
||||
/** A transaction with a merkle branch linking it to the block chain. */
|
||||
/** Legacy class used for deserializing vtxPrev for backwards compatibility.
|
||||
* vtxPrev was removed in commit 93a18a3650292afbb441a47d1fa1b94aeb0164e3,
|
||||
* but old wallet.dat files may still contain vtxPrev vectors of CMerkleTxs.
|
||||
* These need to get deserialized for field alignment when deserializing
|
||||
* a CWalletTx, but the deserialized values are discarded.**/
|
||||
class CMerkleTx
|
||||
{
|
||||
private:
|
||||
/** Constant used in hashBlock to indicate tx has been abandoned */
|
||||
static const uint256 ABANDON_HASH;
|
||||
|
||||
public:
|
||||
CTransactionRef tx;
|
||||
uint256 hashBlock;
|
||||
|
||||
/* An nIndex == -1 means that hashBlock (in nonzero) refers to the earliest
|
||||
* block in the chain we know this or any in-wallet dependency conflicts
|
||||
* with. Older clients interpret nIndex == -1 as unconfirmed for backward
|
||||
* compatibility.
|
||||
*/
|
||||
int nIndex;
|
||||
|
||||
CMerkleTx()
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s)
|
||||
{
|
||||
SetTx(MakeTransactionRef());
|
||||
Init();
|
||||
CTransactionRef tx;
|
||||
uint256 hashBlock;
|
||||
std::vector<uint256> vMerkleBranch;
|
||||
int nIndex;
|
||||
|
||||
s >> tx >> hashBlock >> vMerkleBranch >> nIndex;
|
||||
}
|
||||
|
||||
explicit CMerkleTx(CTransactionRef arg)
|
||||
{
|
||||
SetTx(std::move(arg));
|
||||
Init();
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
hashBlock = uint256();
|
||||
nIndex = -1;
|
||||
}
|
||||
|
||||
void SetTx(CTransactionRef arg)
|
||||
{
|
||||
tx = std::move(arg);
|
||||
}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
std::vector<uint256> vMerkleBranch; // For compatibility with older versions.
|
||||
READWRITE(tx);
|
||||
READWRITE(hashBlock);
|
||||
READWRITE(vMerkleBranch);
|
||||
READWRITE(nIndex);
|
||||
}
|
||||
|
||||
void SetMerkleBranch(const uint256& block_hash, int posInBlock);
|
||||
|
||||
/**
|
||||
* Return depth of transaction in blockchain:
|
||||
* <0 : conflicts with a transaction this deep in the blockchain
|
||||
* 0 : in memory pool, waiting to be included in a block
|
||||
* >=1 : this many blocks deep in the main chain
|
||||
*/
|
||||
int GetDepthInMainChain(interfaces::Chain::Lock& locked_chain) const;
|
||||
bool IsInMainChain(interfaces::Chain::Lock& locked_chain) const { return GetDepthInMainChain(locked_chain) > 0; }
|
||||
|
||||
/**
|
||||
* @return number of blocks to maturity for this transaction:
|
||||
* 0 : is not a coinbase transaction, or is a mature coinbase transaction
|
||||
* >0 : is a coinbase transaction which matures in this many blocks
|
||||
*/
|
||||
int GetBlocksToMaturity(interfaces::Chain::Lock& locked_chain) const;
|
||||
bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); }
|
||||
bool isAbandoned() const { return (hashBlock == ABANDON_HASH); }
|
||||
void setAbandoned() { hashBlock = ABANDON_HASH; }
|
||||
|
||||
const uint256& GetHash() const { return tx->GetHash(); }
|
||||
bool IsCoinBase() const { return tx->IsCoinBase(); }
|
||||
bool IsImmatureCoinBase(interfaces::Chain::Lock& locked_chain) const;
|
||||
};
|
||||
|
||||
//Get the marginal bytes of spending the specified output
|
||||
|
@ -449,11 +391,14 @@ int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* pwallet,
|
|||
* 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.
|
||||
*/
|
||||
class CWalletTx : public CMerkleTx
|
||||
class CWalletTx
|
||||
{
|
||||
private:
|
||||
const CWallet* pwallet;
|
||||
|
||||
/** Constant used in hashBlock to indicate tx has been abandoned */
|
||||
static const uint256 ABANDON_HASH;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Key/value map with information about the transaction.
|
||||
|
@ -511,7 +456,10 @@ public:
|
|||
mutable bool fInMempool;
|
||||
mutable CAmount nChangeCached;
|
||||
|
||||
CWalletTx(const CWallet* pwalletIn, CTransactionRef arg) : CMerkleTx(std::move(arg))
|
||||
CWalletTx(const CWallet* pwalletIn, CTransactionRef arg)
|
||||
: tx(std::move(arg)),
|
||||
hashBlock(uint256()),
|
||||
nIndex(-1)
|
||||
{
|
||||
Init(pwalletIn);
|
||||
}
|
||||
|
@ -531,10 +479,18 @@ public:
|
|||
nOrderPos = -1;
|
||||
}
|
||||
|
||||
CTransactionRef tx;
|
||||
uint256 hashBlock;
|
||||
/* An nIndex == -1 means that hashBlock (in nonzero) refers to the earliest
|
||||
* block in the chain we know this or any in-wallet dependency conflicts
|
||||
* with. Older clients interpret nIndex == -1 as unconfirmed for backward
|
||||
* compatibility.
|
||||
*/
|
||||
int nIndex;
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s) const
|
||||
{
|
||||
char fSpent = false;
|
||||
mapValue_t mapValueCopy = mapValue;
|
||||
|
||||
mapValueCopy["fromaccount"] = "";
|
||||
|
@ -543,20 +499,21 @@ public:
|
|||
mapValueCopy["timesmart"] = strprintf("%u", nTimeSmart);
|
||||
}
|
||||
|
||||
s << static_cast<const CMerkleTx&>(*this);
|
||||
std::vector<CMerkleTx> vUnused; //!< Used to be vtxPrev
|
||||
s << vUnused << mapValueCopy << vOrderForm << fTimeReceivedIsTxTime << nTimeReceived << fFromMe << fSpent;
|
||||
std::vector<char> dummy_vector1; //!< Used to be vMerkleBranch
|
||||
std::vector<char> dummy_vector2; //!< Used to be vtxPrev
|
||||
char dummy_char = false; //!< Used to be fSpent
|
||||
s << tx << hashBlock << dummy_vector1 << nIndex << dummy_vector2 << mapValueCopy << vOrderForm << fTimeReceivedIsTxTime << nTimeReceived << fFromMe << dummy_char;
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s)
|
||||
{
|
||||
Init(nullptr);
|
||||
char fSpent;
|
||||
|
||||
s >> static_cast<CMerkleTx&>(*this);
|
||||
std::vector<CMerkleTx> vUnused; //!< Used to be vtxPrev
|
||||
s >> vUnused >> mapValue >> vOrderForm >> fTimeReceivedIsTxTime >> nTimeReceived >> fFromMe >> fSpent;
|
||||
std::vector<uint256> dummy_vector1; //!< Used to be vMerkleBranch
|
||||
std::vector<CMerkleTx> dummy_vector2; //!< Used to be vtxPrev
|
||||
char dummy_char; //! Used to be fSpent
|
||||
s >> tx >> hashBlock >> dummy_vector1 >> nIndex >> dummy_vector2 >> mapValue >> vOrderForm >> fTimeReceivedIsTxTime >> nTimeReceived >> fFromMe >> dummy_char;
|
||||
|
||||
ReadOrderPos(nOrderPos, mapValue);
|
||||
nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(mapValue["timesmart"]) : 0;
|
||||
|
@ -567,6 +524,11 @@ public:
|
|||
mapValue.erase("timesmart");
|
||||
}
|
||||
|
||||
void SetTx(CTransactionRef arg)
|
||||
{
|
||||
tx = std::move(arg);
|
||||
}
|
||||
|
||||
//! make sure balances are recalculated
|
||||
void MarkDirty()
|
||||
{
|
||||
|
@ -630,6 +592,31 @@ public:
|
|||
// that we still have the runtime check "AssertLockHeld(pwallet->cs_wallet)"
|
||||
// in place.
|
||||
std::set<uint256> GetConflicts() const NO_THREAD_SAFETY_ANALYSIS;
|
||||
|
||||
void SetMerkleBranch(const uint256& block_hash, int posInBlock);
|
||||
|
||||
/**
|
||||
* Return depth of transaction in blockchain:
|
||||
* <0 : conflicts with a transaction this deep in the blockchain
|
||||
* 0 : in memory pool, waiting to be included in a block
|
||||
* >=1 : this many blocks deep in the main chain
|
||||
*/
|
||||
int GetDepthInMainChain(interfaces::Chain::Lock& locked_chain) const;
|
||||
bool IsInMainChain(interfaces::Chain::Lock& locked_chain) const { return GetDepthInMainChain(locked_chain) > 0; }
|
||||
|
||||
/**
|
||||
* @return number of blocks to maturity for this transaction:
|
||||
* 0 : is not a coinbase transaction, or is a mature coinbase transaction
|
||||
* >0 : is a coinbase transaction which matures in this many blocks
|
||||
*/
|
||||
int GetBlocksToMaturity(interfaces::Chain::Lock& locked_chain) const;
|
||||
bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); }
|
||||
bool isAbandoned() const { return (hashBlock == ABANDON_HASH); }
|
||||
void setAbandoned() { hashBlock = ABANDON_HASH; }
|
||||
|
||||
const uint256& GetHash() const { return tx->GetHash(); }
|
||||
bool IsCoinBase() const { return tx->IsCoinBase(); }
|
||||
bool IsImmatureCoinBase(interfaces::Chain::Lock& locked_chain) const;
|
||||
};
|
||||
|
||||
class COutput
|
||||
|
|
Loading…
Add table
Reference in a new issue