slight simplification to get_min_fee_rate() (#17092)

This commit is contained in:
Arvid Norberg 2023-12-19 19:08:54 +01:00 committed by GitHub
parent ccdc5891f0
commit 2022d6e95e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 24 deletions

View File

@ -184,32 +184,33 @@ class Mempool:
items.extend(self._row_to_item(row) for row in cursor)
return items
def get_min_fee_rate(self, cost: int) -> float:
def get_min_fee_rate(self, cost: int) -> Optional[float]:
"""
Gets the minimum fpc rate that a transaction with specified cost will need in order to get included.
"""
if self.at_full_capacity(cost):
# TODO: make MempoolItem.cost be CLVMCost
current_cost = int(self.total_mempool_cost())
if not self.at_full_capacity(cost):
return 0
# Iterates through all spends in increasing fee per cost
with self._db_conn:
cursor = self._db_conn.execute("SELECT cost,fee_per_cost FROM tx ORDER BY fee_per_cost ASC, seq DESC")
# TODO: make MempoolItem.cost be CLVMCost
current_cost = int(self.total_mempool_cost())
item_cost: int
fee_per_cost: float
for item_cost, fee_per_cost in cursor:
current_cost -= item_cost
# Removing one at a time, until our transaction of size cost fits
if current_cost + cost <= self.mempool_info.max_size_in_cost:
return fee_per_cost
# Iterates through all spends in increasing fee per cost
with self._db_conn:
cursor = self._db_conn.execute("SELECT cost,fee_per_cost FROM tx ORDER BY fee_per_cost ASC, seq DESC")
raise ValueError(
item_cost: int
fee_per_cost: float
for item_cost, fee_per_cost in cursor:
current_cost -= item_cost
# Removing one at a time, until our transaction of size cost fits
if current_cost + cost <= self.mempool_info.max_size_in_cost:
return fee_per_cost
log.info(
f"Transaction with cost {cost} does not fit in mempool of max cost {self.mempool_info.max_size_in_cost}"
)
else:
return 0
return None
def new_tx_block(self, block_height: uint32, timestamp: uint64) -> None:
"""

View File

@ -244,11 +244,12 @@ class MempoolManager:
if cost == 0:
return False
fees_per_cost = fees / cost
if not self.mempool.at_full_capacity(cost) or (
fees_per_cost >= self.nonzero_fee_minimum_fpc and fees_per_cost > self.mempool.get_min_fee_rate(cost)
):
if not self.mempool.at_full_capacity(cost):
return True
return False
if fees_per_cost < self.nonzero_fee_minimum_fpc:
return False
min_fee_rate = self.mempool.get_min_fee_rate(cost)
return min_fee_rate is not None and fees_per_cost > min_fee_rate
def add_and_maybe_pop_seen(self, spend_name: bytes32) -> None:
self.seen_bundle_hashes[spend_name] = spend_name
@ -465,8 +466,12 @@ class MempoolManager:
if self.mempool.at_full_capacity(cost):
if fees_per_cost < self.nonzero_fee_minimum_fpc:
return Err.INVALID_FEE_TOO_CLOSE_TO_ZERO, None, []
if fees_per_cost <= self.mempool.get_min_fee_rate(cost):
min_fee_rate = self.mempool.get_min_fee_rate(cost)
if min_fee_rate is None:
return Err.INVALID_COST_RESULT, None, []
if fees_per_cost <= min_fee_rate:
return Err.INVALID_FEE_LOW_FEE, None, []
# Check removals against UnspentDB + DiffStore + Mempool + SpendBundle
# Use this information later when constructing a block
fail_reason, conflicts = self.check_removals(non_eligible_coin_ids, removal_record_dict)

View File

@ -310,8 +310,7 @@ class TestMempool:
mempool = Mempool(mempool_info, fee_estimator)
assert mempool.get_min_fee_rate(104000) == 0
with pytest.raises(ValueError):
mempool.get_min_fee_rate(max_mempool_cost + 1)
assert mempool.get_min_fee_rate(max_mempool_cost + 1) is None
coin = await next_block(full_node_1, wallet_a, bt)
spend_bundle = generate_test_spend_bundle(wallet_a, coin)