Skip to content

Commit 46bc14b

Browse files
authored
[CHIA-2827] simplify MempoolManager by removing EligibilityAndAdditions (#19801)
* simplify MempoolManager by removing EligibilityAndAdditions * review comment * review comments
1 parent d01758f commit 46bc14b

File tree

3 files changed

+43
-68
lines changed

3 files changed

+43
-68
lines changed

chia/_tests/core/mempool/test_mempool_manager.py

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
from chia.consensus.default_constants import DEFAULT_CONSTANTS
3333
from chia.full_node.eligible_coin_spends import (
3434
DedupCoinSpend,
35-
EligibilityAndAdditions,
3635
IdenticalSpendDedup,
3736
SkipDedup,
3837
run_for_cost,
@@ -559,33 +558,29 @@ def make_bundle_spends_map_and_fee(
559558
spend_bundle: SpendBundle, conds: SpendBundleConditions
560559
) -> tuple[dict[bytes32, BundleCoinSpend], uint64]:
561560
bundle_coin_spends: dict[bytes32, BundleCoinSpend] = {}
562-
eligibility_and_additions: dict[bytes32, EligibilityAndAdditions] = {}
561+
562+
spend_conditions = {bytes32(spend.coin_id): spend for spend in conds.spends}
563+
563564
removals_amount = 0
564565
additions_amount = 0
565-
for spend in conds.spends:
566-
coin_id = bytes32(spend.coin_id)
567-
spend_additions = []
568-
for puzzle_hash, amount, _ in spend.create_coin:
569-
spend_additions.append(Coin(coin_id, puzzle_hash, uint64(amount)))
570-
additions_amount += amount
571-
eligibility_and_additions[coin_id] = EligibilityAndAdditions(
572-
is_eligible_for_dedup=bool(spend.flags & ELIGIBLE_FOR_DEDUP),
573-
spend_additions=spend_additions,
574-
ff_puzzle_hash=bytes32(spend.puzzle_hash) if bool(spend.flags & ELIGIBLE_FOR_FF) else None,
575-
)
576566
for coin_spend in spend_bundle.coin_spends:
577567
coin_id = coin_spend.coin.name()
578568
removals_amount += coin_spend.coin.amount
579-
eligibility_info = eligibility_and_additions.get(
580-
coin_id, EligibilityAndAdditions(is_eligible_for_dedup=False, spend_additions=[], ff_puzzle_hash=None)
581-
)
569+
spend_conds = spend_conditions.pop(coin_id)
570+
571+
additions_amount += coin_spend.coin.amount
572+
573+
additions = []
574+
for puzzle_hash, amount, _ in spend_conds.create_coin:
575+
additions.append(Coin(coin_id, puzzle_hash, uint64(amount)))
576+
582577
bundle_coin_spends[coin_id] = BundleCoinSpend(
583578
coin_spend=coin_spend,
584-
eligible_for_dedup=eligibility_info.is_eligible_for_dedup,
585-
eligible_for_fast_forward=eligibility_info.ff_puzzle_hash is not None,
586-
additions=eligibility_info.spend_additions,
579+
eligible_for_dedup=bool(spend_conds.flags & ELIGIBLE_FOR_DEDUP),
580+
eligible_for_fast_forward=bool(spend_conds.flags & ELIGIBLE_FOR_FF),
581+
additions=additions,
587582
latest_singleton_lineage=UnspentLineageInfo(coin_id, coin_spend.coin.parent_coin_info, bytes32([0] * 32))
588-
if eligibility_info.ff_puzzle_hash is not None
583+
if bool(spend_conds.flags & ELIGIBLE_FOR_FF)
589584
else None,
590585
)
591586
fee = uint64(removals_amount - additions_amount)

chia/full_node/eligible_coin_spends.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,6 @@
1616
from chia.util.errors import Err
1717

1818

19-
@dataclasses.dataclass(frozen=True)
20-
class EligibilityAndAdditions:
21-
is_eligible_for_dedup: bool
22-
spend_additions: list[Coin]
23-
# This is the spend puzzle hash. It's set to `None` if the spend is not
24-
# eligible for fast forward. When the spend is eligible, we use its puzzle
25-
# hash to check if the singleton has an unspent coin or not.
26-
ff_puzzle_hash: Optional[bytes32] = None
27-
28-
2919
def run_for_cost(
3020
puzzle_reveal: SerializedProgram, solution: SerializedProgram, additions_count: int, max_cost: int
3121
) -> uint64:

chia/full_node/mempool_manager.py

Lines changed: 28 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
from chia.consensus.check_time_locks import check_time_locks
2727
from chia.consensus.cost_calculator import NPCResult
2828
from chia.full_node.bitcoin_fee_estimator import create_bitcoin_fee_estimator
29-
from chia.full_node.eligible_coin_spends import EligibilityAndAdditions
3029
from chia.full_node.fee_estimation import FeeBlockInfo, MempoolInfo, MempoolItemInfo
3130
from chia.full_node.fee_estimator_interface import FeeEstimatorInterface
3231
from chia.full_node.mempool import MEMPOOL_ITEM_FEE_LIMIT, Mempool, MempoolRemoveInfo, MempoolRemoveReason
@@ -584,60 +583,51 @@ async def validate_spend_bundle(
584583
removal_names: set[bytes32] = set()
585584
additions_dict: dict[bytes32, Coin] = {}
586585
addition_amount: int = 0
587-
# Map of coin ID to eligibility information
588-
eligibility_and_additions: dict[bytes32, EligibilityAndAdditions] = {}
589-
for spend in conds.spends:
590-
coin_id = bytes32(spend.coin_id)
591-
removal_names.add(coin_id)
592-
spend_additions = []
593-
for puzzle_hash, amount, _ in spend.create_coin:
594-
child_coin = Coin(coin_id, puzzle_hash, uint64(amount))
595-
spend_additions.append(child_coin)
596-
additions_dict[child_coin.name()] = child_coin
597-
addition_amount += child_coin.amount
598-
is_eligible_for_dedup = bool(spend.flags & ELIGIBLE_FOR_DEDUP)
599-
is_eligible_for_ff = bool(spend.flags & ELIGIBLE_FOR_FF)
600-
eligibility_and_additions[coin_id] = EligibilityAndAdditions(
601-
is_eligible_for_dedup=is_eligible_for_dedup,
602-
spend_additions=spend_additions,
603-
ff_puzzle_hash=bytes32(spend.puzzle_hash) if is_eligible_for_ff else None,
604-
)
605-
removal_names_from_coin_spends: set[bytes32] = set()
586+
587+
# Map of coin ID to SpendConditions
588+
spend_conditions = {bytes32(spend.coin_id): spend for spend in conds.spends}
589+
590+
# if this happens, the SpendBundle doesn't match the
591+
# SpendBundleConditions.
592+
assert len(new_spend.coin_spends) == len(spend_conditions)
593+
606594
bundle_coin_spends: dict[bytes32, BundleCoinSpend] = {}
607595
for coin_spend in new_spend.coin_spends:
608596
coin_id = coin_spend.coin.name()
609-
removal_names_from_coin_spends.add(coin_id)
610-
eligibility_info = eligibility_and_additions.get(
611-
coin_id,
612-
EligibilityAndAdditions(is_eligible_for_dedup=False, spend_additions=[], ff_puzzle_hash=None),
613-
)
597+
removal_names.add(coin_id)
598+
599+
# if this coin_id isn't found, the SpendBundle doesn't match the
600+
# SpendBundleConditions.
601+
spend_conds = spend_conditions.pop(coin_id)
614602

615-
supports_dedup = eligibility_info.is_eligible_for_dedup
616-
if supports_dedup and not is_clvm_canonical(bytes(coin_spend.solution)):
603+
if bool(spend_conds.flags & ELIGIBLE_FOR_DEDUP) and not is_clvm_canonical(bytes(coin_spend.solution)):
617604
return Err.INVALID_COIN_SOLUTION, None, []
618605

619-
mark_as_fast_forward = eligibility_info.ff_puzzle_hash is not None and supports_fast_forward(coin_spend)
620606
lineage_info = None
621-
if mark_as_fast_forward:
607+
eligible_for_ff = bool(spend_conds.flags & ELIGIBLE_FOR_FF) and supports_fast_forward(coin_spend)
608+
if eligible_for_ff:
622609
# Make sure the fast forward spend still has a version that is
623610
# still unspent, because if the singleton has been melted, the
624611
# fast forward spend will never become valid.
625-
assert eligibility_info.ff_puzzle_hash is not None
626-
lineage_info = await get_unspent_lineage_info_for_puzzle_hash(eligibility_info.ff_puzzle_hash)
612+
lineage_info = await get_unspent_lineage_info_for_puzzle_hash(bytes32(spend_conds.puzzle_hash))
627613
if lineage_info is None:
628614
return Err.DOUBLE_SPEND, None, []
615+
616+
spend_additions = []
617+
for puzzle_hash, amount, _ in spend_conds.create_coin:
618+
child_coin = Coin(coin_id, puzzle_hash, uint64(amount))
619+
spend_additions.append(child_coin)
620+
additions_dict[child_coin.name()] = child_coin
621+
addition_amount += amount
622+
629623
bundle_coin_spends[coin_id] = BundleCoinSpend(
630624
coin_spend=coin_spend,
631-
eligible_for_dedup=supports_dedup,
632-
eligible_for_fast_forward=mark_as_fast_forward,
633-
additions=eligibility_info.spend_additions,
625+
eligible_for_dedup=bool(spend_conds.flags & ELIGIBLE_FOR_DEDUP),
626+
eligible_for_fast_forward=eligible_for_ff,
627+
additions=spend_additions,
634628
latest_singleton_lineage=lineage_info,
635629
)
636630

637-
if removal_names != removal_names_from_coin_spends:
638-
# If you reach here it's probably because your program reveal doesn't match the coin's puzzle hash
639-
return Err.INVALID_SPEND_BUNDLE, None, []
640-
641631
# fast forward spends are only allowed when bundled with other, non-FF, spends
642632
# in order to evict an FF spend, it must be associated with a normal
643633
# spend that can be included in a block or invalidated some other way

0 commit comments

Comments
 (0)