Skip to content

Commit

Permalink
Bare txid for GetTransaction / GetWalletTx.
Browse files Browse the repository at this point in the history
This extends the two functions GetWalletTx and GetTransaction to (also)
find transactions by bare txid, not just by the normal txid.

These methods are mainly used in places where we need to look up e.g.
the previous transaction to a spend, so that we can know the address
that is being spent or the value of the input.

The change is fine to do (won't cause any extra consensus changes)
because all it does is make those methods return the correct previous
transaction (for after the fork) in cases where they would have
failed otherwise (since both are SHA-256d hashes and thus cannot have
collisions).  Also actual checks that some spent coin actually exists
are the explicitly on the consensus-level anyway.
  • Loading branch information
domob1812 committed Mar 16, 2021
1 parent afa2ab6 commit 0ff7d85
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 14 deletions.
11 changes: 6 additions & 5 deletions divi/src/TransactionDiskAccessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ bool GetTransaction(const uint256& hash, CTransaction& txOut, uint256& hashBlock
{
LOCK(cs_main);
{
if (mempool.lookup(hash, txOut)) {
if (mempool.lookup(hash, txOut) || mempool.lookupBareTxid(hash, txOut)) {
return true;
}
}
Expand All @@ -49,8 +49,9 @@ bool GetTransaction(const uint256& hash, CTransaction& txOut, uint256& hashBlock
return true;
}

// transaction not found in the index, nothing more can be done
return false;
// The index only keys by txid. So even if we did not find the
// transaction here, it could be that the lookup is by bare txid
// and can be found through UTXO lookup.
}

if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
Expand All @@ -70,7 +71,7 @@ bool GetTransaction(const uint256& hash, CTransaction& txOut, uint256& hashBlock
CBlock block;
if (ReadBlockFromDisk(block, pindexSlow)) {
BOOST_FOREACH (const CTransaction& tx, block.vtx) {
if (tx.GetHash() == hash) {
if (tx.GetHash() == hash || tx.GetBareTxid() == hash) {
txOut = tx;
hashBlock = pindexSlow->GetBlockHash();
return true;
Expand Down Expand Up @@ -101,4 +102,4 @@ bool CollateralIsExpectedAmount(const COutPoint &outpoint, int64_t expectedAmoun
return true;
}
assert(false);
}
}
26 changes: 21 additions & 5 deletions divi/src/WalletTransactionRecord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,22 @@ WalletTransactionRecord::WalletTransactionRecord(
const CWalletTx* WalletTransactionRecord::GetWalletTx(const uint256& hash) const
{
AssertLockHeld(cs_walletTxRecord);
std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash);
if (it == mapWallet.end())
return NULL;
return &(it->second);

{
const auto mit = mapWallet.find(hash);
if (mit != mapWallet.end())
return &mit->second;
}

{
const auto mit = mapBareTxid.find(hash);
if (mit != mapBareTxid.end())
return mit->second;
}

return nullptr;
}

std::vector<const CWalletTx*> WalletTransactionRecord::GetWalletTransactionReferences() const
{
AssertLockHeld(cs_walletTxRecord);
Expand All @@ -50,7 +61,12 @@ std::vector<const CWalletTx*> WalletTransactionRecord::GetWalletTransactionRefer
std::pair<std::map<uint256, CWalletTx>::iterator, bool> WalletTransactionRecord::AddTransaction(const CWalletTx& newlyAddedTransaction)
{
AssertLockHeld(cs_walletTxRecord);
return mapWallet.insert(std::make_pair(newlyAddedTransaction.GetHash(), newlyAddedTransaction));

auto res = mapWallet.emplace(newlyAddedTransaction.GetHash(), newlyAddedTransaction);
if (res.second)
mapBareTxid.emplace(newlyAddedTransaction.GetBareTxid(), &res.first->second);

return res;
};

void WalletTransactionRecord::UpdateMetadata(
Expand Down
10 changes: 9 additions & 1 deletion divi/src/WalletTransactionRecord.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,23 @@ struct WalletTransactionRecord
CCriticalSection& cs_walletTxRecord;
const std::string walletFilename_;
const bool databaseWritesAreDisallowed_;

/** Map from the bare txid of transactions in the wallet to the matching
* transactions themselves. */
std::map<uint256, const CWalletTx*> mapBareTxid;

public:
std::map<uint256, CWalletTx> mapWallet;

WalletTransactionRecord(CCriticalSection& requiredWalletLock,const std::string& walletFilename);
WalletTransactionRecord(CCriticalSection& requiredWalletLock);
const CWalletTx* GetWalletTx(const uint256& hash) const;

/** Tries to look up a transaction in the wallet, either by hash (txid) or
* the bare txid that is used after segwit-light to identify outputs. */
std::vector<const CWalletTx*> GetWalletTransactionReferences() const;
std::pair<std::map<uint256, CWalletTx>::iterator, bool> AddTransaction(const CWalletTx& newlyAddedTransaction);
void UpdateMetadata(const uint256& hashOfTransactionToUpdate, const CWalletTx& updatedTransaction, bool updateDiskAndTimestamp,bool writeToWalletDb=false);
};

#endif// WALLET_TRANSACTION_RECORD_H
#endif// WALLET_TRANSACTION_RECORD_H
6 changes: 3 additions & 3 deletions divi/src/rpcmasternode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Value allocatefunds(const Array& params, bool fHelp)
" <future> (numeric, required) amount of divi funded will also be accepted for partially funding master nodes and other purposes.\n"

"\nResult:\n"
"\"vin\" (string) funding transaction id necessary for next step.\n");
"\"vin\" (string) funding transaction id or bare txid necessary for next step.\n");

if (params[0].get_str() != "masternode")
{
Expand Down Expand Up @@ -114,7 +114,7 @@ Value fundmasternode(const Array& params, bool fHelp)
"1. alias (string, required) helpful identifier to recognize this allocation later.\n"
"2. amount (diamond, platinum, gold, silver, copper) tier of masternode. \n"
" <future> (numeric, required) amount of divi funded will also be accepted for partially funding master nodes and other purposes.\n"
"3. TxID (string, required) funding transaction id .\n"
"3. TxID (string, required) funding transaction id or bare txid.\n"
"4. masternode (string, required) ip address of masternode.\n"
"(use an empty string for the pay wallet if the same as the funding wallet and you wish to assign a different voting wallet).\n"

Expand Down Expand Up @@ -229,7 +229,7 @@ Value setupmasternode(const Array& params, bool fHelp)

"\nArguments:\n"
"1. alias (string, required) Helpful identifier to recognize this masternode later. \n"
"2. txHash (string, required) Funding transaction. \n"
"2. txHash (string, required) Funding transaction hash or bare txid. \n"
"3. outputIndex (string, required) Output index transaction. \n"
"4. collateralPubkey (string, required) collateral pubkey. \n"
"5. ip_address (string, required) Local ip address of this node\n"
Expand Down

0 comments on commit 0ff7d85

Please sign in to comment.