Skip to content

Commit

Permalink
Ledger: eliminate DB ops in getTxFeeRate()
Browse files Browse the repository at this point in the history
Which used tp slow down combineCandidates()
  • Loading branch information
omerfirmak authored and Geod24 committed Mar 23, 2022
1 parent 944d453 commit e1c8aa2
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 11 deletions.
5 changes: 1 addition & 4 deletions source/agora/consensus/Ledger.d
Original file line number Diff line number Diff line change
Expand Up @@ -368,10 +368,7 @@ public class NodeLedger : Ledger

public string getTxFeeRate (in Hash tx_hash, out Amount rate) nothrow @safe
{
auto tx = this.pool.getTransactionByHash(tx_hash);
if (tx == Transaction.init)
return InvalidConsensusDataReason.NotInPool;
return this.getTxFeeRate(tx, rate);
return this.pool.getTxFeeRate(tx_hash, rate) ? null : InvalidConsensusDataReason.NotInPool;
}

/***************************************************************************
Expand Down
49 changes: 42 additions & 7 deletions source/agora/consensus/pool/Transaction.d
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,18 @@ public class TransactionPool
/// Keeps track of which TXs spend which inputs
private Set!Hash[Hash] spenders;

/// Data associated with TXs in the pool for fast access
public struct KnownTx
{
/// Inputs
Set!Hash inputs;

/// Fee rate
Amount fee_rate;
}

/// Known TXs and their input set
private Set!Hash[Hash] known_txs;
private KnownTx[Hash] known_txs;

/// A delegate to select one of the double spent TXs
public DoubleSpentSelector selector;
Expand Down Expand Up @@ -125,7 +135,8 @@ public class TransactionPool
this.updateSpenderList(tx);
auto tx_hash = tx.hashFull();
iota(tx.outputs.length).each!(idx => utxo_set[UTXO.getHash(tx_hash, idx)] = tx.outputs[idx]);
this.known_txs[tx_hash] = Set!Hash.from(tx.inputs.map!(input => input.utxo));
Amount fee_rate = Amount(this.db.execute("SELECT fee FROM tx_pool WHERE key = ?", tx_hash).oneValue!ulong);
this.known_txs[tx_hash] = KnownTx(Set!Hash.from(tx.inputs.map!(input => input.utxo)), fee_rate);
}

// Set selector after rebuilding the spender list, so nothing gets
Expand Down Expand Up @@ -170,7 +181,7 @@ public class TransactionPool
db.execute("INSERT INTO tx_pool (key, val, fee) VALUES (?, ?, ?)",
hashFull(tx), buffer, fee);
}();
this.known_txs[tx_hash] = Set!Hash.from(tx.inputs.map!(input => input.utxo));
this.known_txs[tx_hash] = KnownTx(Set!Hash.from(tx.inputs.map!(input => input.utxo)), fee);

return true;
}
Expand Down Expand Up @@ -223,9 +234,9 @@ public class TransactionPool
break;
}

if (auto spending = tx_hash in this.known_txs)
if (auto known = tx_hash in this.known_txs)
{
foreach (input; *spending)
foreach (input; (*known).inputs)
if (auto list = input in this.spenders)
{
(*list).remove(tx_hash);
Expand Down Expand Up @@ -684,9 +695,9 @@ public class TransactionPool
{
foreach (hash; hashes)
{
if (auto spending = hash in this.known_txs)
if (auto known = hash in this.known_txs)
{
auto found_double_spent = (*spending)[].any!((utxo_hash) {
auto found_double_spent = (*known).inputs[].any!((utxo_hash) {
scope (exit) spent_utxos.put(utxo_hash);
return !(utxo_hash !in spent_utxos);
});
Expand All @@ -699,6 +710,30 @@ public class TransactionPool
}
return null;
}

/***************************************************************************
Looks up fee rate of the transaction with hash `tx_hash` from memory
Params:
tx_hash = hash of the TX to look up
rate = fee rate output
Returns:
false if tx not found
***************************************************************************/

public bool getTxFeeRate (in Hash tx_hash, out Amount rate) nothrow @safe
{
if (auto known = tx_hash in this.known_txs)
{
rate = (*known).fee_rate;
return true;
}

return false;
}
}

/// hasTransactionHash tests
Expand Down

0 comments on commit e1c8aa2

Please sign in to comment.