Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
Show First 20 Lines • Show All 1,207 Lines • ▼ Show 20 Lines | void CWallet::SyncTransaction(const CTransactionRef &ptx, | ||||
} | } | ||||
// If a transaction changes 'conflicted' state, that changes the balance | // If a transaction changes 'conflicted' state, that changes the balance | ||||
// available of the outputs it spends. So force those to be | // available of the outputs it spends. So force those to be | ||||
// recomputed, also: | // recomputed, also: | ||||
MarkInputsDirty(ptx); | MarkInputsDirty(ptx); | ||||
} | } | ||||
void CWallet::transactionAddedToMempool(const CTransactionRef &ptx) { | void CWallet::transactionAddedToMempool(const CTransactionRef &tx) { | ||||
LOCK(cs_wallet); | LOCK(cs_wallet); | ||||
CWalletTx::Confirmation confirm(CWalletTx::Status::UNCONFIRMED, | |||||
/* block_height */ 0, BlockHash(), | |||||
/* nIndex */ 0); | |||||
SyncTransaction(ptx, confirm); | |||||
auto it = mapWallet.find(ptx->GetId()); | SyncTransaction(tx, {CWalletTx::Status::UNCONFIRMED, /* block_height */ 0, | ||||
BlockHash(), /* nIndex */ 0}); | |||||
auto it = mapWallet.find(tx->GetId()); | |||||
if (it != mapWallet.end()) { | if (it != mapWallet.end()) { | ||||
it->second.fInMempool = true; | it->second.fInMempool = true; | ||||
} | } | ||||
} | } | ||||
void CWallet::transactionRemovedFromMempool(const CTransactionRef &ptx, | void CWallet::transactionRemovedFromMempool(const CTransactionRef &tx, | ||||
MemPoolRemovalReason reason) { | MemPoolRemovalReason reason) { | ||||
LOCK(cs_wallet); | LOCK(cs_wallet); | ||||
auto it = mapWallet.find(ptx->GetId()); | auto it = mapWallet.find(tx->GetId()); | ||||
if (it != mapWallet.end()) { | if (it != mapWallet.end()) { | ||||
it->second.fInMempool = false; | it->second.fInMempool = false; | ||||
} | } | ||||
// Handle transactions that were removed from the mempool because they | // Handle transactions that were removed from the mempool because they | ||||
// conflict with transactions in a newly connected block. | // conflict with transactions in a newly connected block. | ||||
if (reason == MemPoolRemovalReason::CONFLICT) { | if (reason == MemPoolRemovalReason::CONFLICT) { | ||||
// Call SyncNotifications, so external -walletnotify notifications will | // Call SyncNotifications, so external -walletnotify notifications will | ||||
// be triggered for these transactions. Set Status::UNCONFIRMED instead | // be triggered for these transactions. Set Status::UNCONFIRMED instead | ||||
Show All 15 Lines | if (reason == MemPoolRemovalReason::CONFLICT) { | ||||
// implementation before that was to mark these transactions | // implementation before that was to mark these transactions | ||||
// unconfirmed rather than conflicted. | // unconfirmed rather than conflicted. | ||||
// | // | ||||
// Nothing described above should be seen as an unchangeable requirement | // Nothing described above should be seen as an unchangeable requirement | ||||
// when improving this code in the future. The wallet's heuristics for | // when improving this code in the future. The wallet's heuristics for | ||||
// distinguishing between conflicted and unconfirmed transactions are | // distinguishing between conflicted and unconfirmed transactions are | ||||
// imperfect, and could be improved in general, see | // imperfect, and could be improved in general, see | ||||
// https://github.com/bitcoin-core/bitcoin-devwiki/wiki/Wallet-Transaction-Conflict-Tracking | // https://github.com/bitcoin-core/bitcoin-devwiki/wiki/Wallet-Transaction-Conflict-Tracking | ||||
SyncTransaction(ptx, | SyncTransaction(tx, | ||||
{CWalletTx::Status::UNCONFIRMED, /* block height */ 0, | {CWalletTx::Status::UNCONFIRMED, /* block height */ 0, | ||||
BlockHash(), /* index */ 0}); | BlockHash(), /* index */ 0}); | ||||
} | } | ||||
} | } | ||||
void CWallet::blockConnected(const CBlock &block, int height) { | void CWallet::blockConnected(const CBlock &block, int height) { | ||||
const BlockHash &block_hash = block.GetHash(); | const BlockHash &block_hash = block.GetHash(); | ||||
LOCK(cs_wallet); | LOCK(cs_wallet); | ||||
m_last_block_processed_height = height; | m_last_block_processed_height = height; | ||||
m_last_block_processed = block_hash; | m_last_block_processed = block_hash; | ||||
for (size_t index = 0; index < block.vtx.size(); index++) { | for (size_t index = 0; index < block.vtx.size(); index++) { | ||||
CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, height, | SyncTransaction(block.vtx[index], {CWalletTx::Status::CONFIRMED, height, | ||||
block_hash, index); | block_hash, int(index)}); | ||||
SyncTransaction(block.vtx[index], confirm); | |||||
transactionRemovedFromMempool(block.vtx[index], | transactionRemovedFromMempool(block.vtx[index], | ||||
MemPoolRemovalReason::BLOCK); | MemPoolRemovalReason::BLOCK); | ||||
} | } | ||||
} | } | ||||
void CWallet::blockDisconnected(const CBlock &block, int height) { | void CWallet::blockDisconnected(const CBlock &block, int height) { | ||||
LOCK(cs_wallet); | LOCK(cs_wallet); | ||||
// At block disconnection, this will change an abandoned transaction to | // At block disconnection, this will change an abandoned transaction to | ||||
// be unconfirmed, whether or not the transaction is added back to the | // be unconfirmed, whether or not the transaction is added back to the | ||||
// mempool. User may have to call abandontransaction again. It may be | // mempool. User may have to call abandontransaction again. It may be | ||||
// addressed in the future with a stickier abandoned state or even removing | // addressed in the future with a stickier abandoned state or even removing | ||||
// abandontransaction call. | // abandontransaction call. | ||||
m_last_block_processed_height = height - 1; | m_last_block_processed_height = height - 1; | ||||
m_last_block_processed = block.hashPrevBlock; | m_last_block_processed = block.hashPrevBlock; | ||||
for (const CTransactionRef &ptx : block.vtx) { | for (const CTransactionRef &ptx : block.vtx) { | ||||
CWalletTx::Confirmation confirm(CWalletTx::Status::UNCONFIRMED, | SyncTransaction(ptx, | ||||
/* block_height */ 0, BlockHash(), | {CWalletTx::Status::UNCONFIRMED, /* block_height */ 0, | ||||
/* nIndex */ 0); | BlockHash(), /* nIndex */ 0}); | ||||
SyncTransaction(ptx, confirm); | |||||
} | } | ||||
} | } | ||||
void CWallet::updatedBlockTip() { | void CWallet::updatedBlockTip() { | ||||
m_best_block_time = GetTime(); | m_best_block_time = GetTime(); | ||||
} | } | ||||
void CWallet::BlockUntilSyncedToCurrentChain() const { | void CWallet::BlockUntilSyncedToCurrentChain() const { | ||||
▲ Show 20 Lines • Show All 586 Lines • ▼ Show 20 Lines | while (!fAbortRescan && !chain().shutdownRequested()) { | ||||
result.status = ScanResult::FAILURE; | result.status = ScanResult::FAILURE; | ||||
break; | break; | ||||
} | } | ||||
for (size_t posInBlock = 0; posInBlock < block.vtx.size(); | for (size_t posInBlock = 0; posInBlock < block.vtx.size(); | ||||
++posInBlock) { | ++posInBlock) { | ||||
CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, | CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, | ||||
block_height, block_hash, | block_height, block_hash, | ||||
posInBlock); | posInBlock); | ||||
SyncTransaction(block.vtx[posInBlock], confirm, fUpdate); | SyncTransaction(block.vtx[posInBlock], | ||||
{CWalletTx::Status::CONFIRMED, block_height, | |||||
block_hash, int(posInBlock)}, | |||||
fUpdate); | |||||
} | } | ||||
// scan succeeded, record block as most recent successfully | // scan succeeded, record block as most recent successfully | ||||
// scanned | // scanned | ||||
result.last_scanned_block = block_hash; | result.last_scanned_block = block_hash; | ||||
result.last_scanned_height = block_height; | result.last_scanned_height = block_height; | ||||
} else { | } else { | ||||
// could not scan block, keep scanning but record this block as | // could not scan block, keep scanning but record this block as | ||||
// the most recent failure | // the most recent failure | ||||
▲ Show 20 Lines • Show All 3,203 Lines • Show Last 20 Lines |