@@ -1118,22 +1118,14 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose)
11181118 bool fUpdated = false ;
11191119 if (!fInsertedNew )
11201120 {
1121- // Merge
1122- if (!wtxIn.hashUnset () && wtxIn.hashBlock != wtx.hashBlock )
1123- {
1124- wtx.hashBlock = wtxIn.hashBlock ;
1125- fUpdated = true ;
1126- }
1127- // If no longer abandoned, update
1128- if (wtxIn.hashBlock .IsNull () && wtx.isAbandoned ())
1129- {
1130- wtx.hashBlock = wtxIn.hashBlock ;
1131- fUpdated = true ;
1132- }
1133- if (wtxIn.nIndex != -1 && (wtxIn.nIndex != wtx.nIndex ))
1134- {
1135- wtx.nIndex = wtxIn.nIndex ;
1121+ if (wtxIn.m_confirm .status != wtx.m_confirm .status ) {
1122+ wtx.m_confirm .status = wtxIn.m_confirm .status ;
1123+ wtx.m_confirm .nIndex = wtxIn.m_confirm .nIndex ;
1124+ wtx.m_confirm .hashBlock = wtxIn.m_confirm .hashBlock ;
11361125 fUpdated = true ;
1126+ } else {
1127+ assert (wtx.m_confirm .nIndex == wtxIn.m_confirm .nIndex );
1128+ assert (wtx.m_confirm .hashBlock == wtxIn.m_confirm .hashBlock );
11371129 }
11381130 if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe )
11391131 {
@@ -1194,14 +1186,14 @@ void CWallet::LoadToWallet(const CWalletTx& wtxIn)
11941186 auto it = mapWallet.find (txin.prevout .hash );
11951187 if (it != mapWallet.end ()) {
11961188 CWalletTx& prevtx = it->second ;
1197- if (prevtx.nIndex == - 1 && !prevtx. hashUnset ()) {
1198- MarkConflicted (prevtx.hashBlock , wtx.GetHash ());
1189+ if (prevtx.isConflicted ()) {
1190+ MarkConflicted (prevtx.m_confirm . hashBlock , wtx.GetHash ());
11991191 }
12001192 }
12011193 }
12021194}
12031195
1204- bool CWallet::AddToWalletIfInvolvingMe (const CTransactionRef& ptx, const uint256& block_hash, int posInBlock, bool fUpdate )
1196+ bool CWallet::AddToWalletIfInvolvingMe (const CTransactionRef& ptx, CWalletTx::Status status, const uint256& block_hash, int posInBlock, bool fUpdate )
12051197{
12061198 const CTransaction& tx = *ptx;
12071199 {
@@ -1248,9 +1240,9 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, const uint256
12481240
12491241 CWalletTx wtx (this , ptx);
12501242
1251- // Get merkle branch if transaction was found in a block
1252- if (!block_hash. IsNull ())
1253- wtx.SetMerkleBranch ( block_hash, posInBlock);
1243+ // Block disconnection override an abandoned tx as unconfirmed
1244+ // which means user may have to call abandontransaction again
1245+ wtx.SetConf (status, block_hash, posInBlock);
12541246
12551247 return AddToWallet (wtx, false );
12561248 }
@@ -1310,7 +1302,7 @@ bool CWallet::AbandonTransaction(interfaces::Chain::Lock& locked_chain, const ui
13101302 if (currentconfirm == 0 && !wtx.isAbandoned ()) {
13111303 // If the orig tx was not in block/mempool, none of its spends can be in mempool
13121304 assert (!wtx.InMempool ());
1313- wtx.nIndex = - 1 ;
1305+ wtx.m_confirm . nIndex = 0 ;
13141306 wtx.setAbandoned ();
13151307 wtx.MarkDirty ();
13161308 batch.WriteTx (wtx);
@@ -1364,8 +1356,9 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx)
13641356 if (conflictconfirms < currentconfirm) {
13651357 // Block is 'more conflicted' than current confirm; update.
13661358 // Mark transaction as conflicted with this block.
1367- wtx.nIndex = -1 ;
1368- wtx.hashBlock = hashBlock;
1359+ wtx.m_confirm .nIndex = 0 ;
1360+ wtx.m_confirm .hashBlock = hashBlock;
1361+ wtx.setConflicted ();
13691362 wtx.MarkDirty ();
13701363 batch.WriteTx (wtx);
13711364 // Iterate over all its outputs, and mark transactions in the wallet that spend them conflicted too
@@ -1383,8 +1376,9 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx)
13831376 }
13841377}
13851378
1386- void CWallet::SyncTransaction (const CTransactionRef& ptx, const uint256& block_hash, int posInBlock, bool update_tx) {
1387- if (!AddToWalletIfInvolvingMe (ptx, block_hash, posInBlock, update_tx))
1379+ void CWallet::SyncTransaction (const CTransactionRef& ptx, CWalletTx::Status status, const uint256& block_hash, int posInBlock, bool update_tx)
1380+ {
1381+ if (!AddToWalletIfInvolvingMe (ptx, status, block_hash, posInBlock, update_tx))
13881382 return ; // Not one of ours
13891383
13901384 // If a transaction changes 'conflicted' state, that changes the balance
@@ -1396,7 +1390,7 @@ void CWallet::SyncTransaction(const CTransactionRef& ptx, const uint256& block_h
13961390void CWallet::TransactionAddedToMempool (const CTransactionRef& ptx) {
13971391 auto locked_chain = chain ().lock ();
13981392 LOCK (cs_wallet);
1399- SyncTransaction (ptx, {} /* block hash */ , 0 /* position in block */ );
1393+ SyncTransaction (ptx, CWalletTx::Status::UNCONFIRMED, {} /* block hash */ , 0 /* position in block */ );
14001394
14011395 auto it = mapWallet.find (ptx->GetHash ());
14021396 if (it != mapWallet.end ()) {
@@ -1425,11 +1419,11 @@ void CWallet::BlockConnected(const CBlock& block, const std::vector<CTransaction
14251419 // the notification that the conflicted transaction was evicted.
14261420
14271421 for (const CTransactionRef& ptx : vtxConflicted) {
1428- SyncTransaction (ptx, {} /* block hash */ , 0 /* position in block */ );
1422+ SyncTransaction (ptx, CWalletTx::Status::CONFLICTED, {} /* block hash */ , 0 /* position in block */ );
14291423 TransactionRemovedFromMempool (ptx);
14301424 }
14311425 for (size_t i = 0 ; i < block.vtx .size (); i++) {
1432- SyncTransaction (block.vtx [i], block_hash, i);
1426+ SyncTransaction (block.vtx [i], CWalletTx::Status::CONFIRMED, block_hash, i);
14331427 TransactionRemovedFromMempool (block.vtx [i]);
14341428 }
14351429
@@ -1440,8 +1434,12 @@ void CWallet::BlockDisconnected(const CBlock& block) {
14401434 auto locked_chain = chain ().lock ();
14411435 LOCK (cs_wallet);
14421436
1437+ // At block disconnection, this will change an abandoned transaction to
1438+ // be unconfirmed, whether or not the transaction is added back to the mempool.
1439+ // User may have to call abandontransaction again. It may be addressed in the
1440+ // future with a stickier abandoned state or even removing abandontransaction call.
14431441 for (const CTransactionRef& ptx : block.vtx ) {
1444- SyncTransaction (ptx, {} /* block hash */ , 0 /* position in block */ );
1442+ SyncTransaction (ptx, CWalletTx::Status::UNCONFIRMED, {} /* block hash */ , 0 /* position in block */ );
14451443 }
14461444}
14471445
@@ -2078,7 +2076,7 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
20782076 break ;
20792077 }
20802078 for (size_t posInBlock = 0 ; posInBlock < block.vtx .size (); ++posInBlock) {
2081- SyncTransaction (block.vtx [posInBlock], block_hash, posInBlock, fUpdate );
2079+ SyncTransaction (block.vtx [posInBlock], CWalletTx::Status::CONFIRMED, block_hash, posInBlock, fUpdate );
20822080 }
20832081 // scan succeeded, record block as most recent successfully scanned
20842082 result.last_scanned_block = block_hash;
@@ -4050,7 +4048,7 @@ void CWallet::GetKeyBirthTimes(interfaces::Chain::Lock& locked_chain, std::map<C
40504048 for (const auto & entry : mapWallet) {
40514049 // iterate over all wallet transactions...
40524050 const CWalletTx &wtx = entry.second ;
4053- if (Optional<int > height = locked_chain.getBlockHeight (wtx.hashBlock )) {
4051+ if (Optional<int > height = locked_chain.getBlockHeight (wtx.m_confirm . hashBlock )) {
40544052 // ... which are already in a block
40554053 for (const CTxOut &txout : wtx.tx ->vout ) {
40564054 // iterate over all their outputs
@@ -4093,9 +4091,9 @@ void CWallet::GetKeyBirthTimes(interfaces::Chain::Lock& locked_chain, std::map<C
40934091unsigned int CWallet::ComputeTimeSmart (const CWalletTx& wtx) const
40944092{
40954093 unsigned int nTimeSmart = wtx.nTimeReceived ;
4096- if (!wtx.hashUnset ()) {
4094+ if (!wtx.isUnconfirmed () && !wtx. isAbandoned ()) {
40974095 int64_t blocktime;
4098- if (chain ().findBlock (wtx.hashBlock , nullptr /* block */ , &blocktime)) {
4096+ if (chain ().findBlock (wtx.m_confirm . hashBlock , nullptr /* block */ , &blocktime)) {
40994097 int64_t latestNow = wtx.nTimeReceived ;
41004098 int64_t latestEntry = 0 ;
41014099
@@ -4123,7 +4121,7 @@ unsigned int CWallet::ComputeTimeSmart(const CWalletTx& wtx) const
41234121
41244122 nTimeSmart = std::max (latestEntry, std::min (blocktime, latestNow));
41254123 } else {
4126- WalletLogPrintf (" %s: found %s in block %s not in index\n " , __func__, wtx.GetHash ().ToString (), wtx.hashBlock .ToString ());
4124+ WalletLogPrintf (" %s: found %s in block %s not in index\n " , __func__, wtx.GetHash ().ToString (), wtx.m_confirm . hashBlock .ToString ());
41274125 }
41284126 }
41294127 return nTimeSmart;
@@ -4634,21 +4632,23 @@ CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn, bool internalIn)
46344632 m_pre_split = false ;
46354633}
46364634
4637- void CWalletTx::SetMerkleBranch ( const uint256& block_hash, int posInBlock)
4635+ void CWalletTx::SetConf (Status status, const uint256& block_hash, int posInBlock)
46384636{
4637+ // Update tx status
4638+ m_confirm.status = status;
4639+
46394640 // Update the tx's hashBlock
4640- hashBlock = block_hash;
4641+ m_confirm. hashBlock = block_hash;
46414642
46424643 // set the position of the transaction in the block
4643- nIndex = posInBlock;
4644+ m_confirm. nIndex = posInBlock;
46444645}
46454646
46464647int CWalletTx::GetDepthInMainChain (interfaces::Chain::Lock& locked_chain) const
46474648{
4648- if (hashUnset ())
4649- return 0 ;
4649+ if (isUnconfirmed () || isAbandoned ()) return 0 ;
46504650
4651- return locked_chain.getBlockDepth (hashBlock) * (nIndex == - 1 ? -1 : 1 );
4651+ return locked_chain.getBlockDepth (m_confirm. hashBlock ) * (isConflicted () ? -1 : 1 );
46524652}
46534653
46544654int CWalletTx::GetBlocksToMaturity (interfaces::Chain::Lock& locked_chain) const
0 commit comments