Skip to content

Commit d2e9df3

Browse files
authored
CHIA-3286 Fix rebasing fast forward spends on new peak (#19857)
Fix rebasing fast forward spends on new peak.
1 parent a5640a8 commit d2e9df3

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

chia/_tests/core/mempool/test_mempool_manager.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3161,3 +3161,53 @@ def test_get_items_by_coin_ids(coin_ids: list[bytes32]) -> list[MempoolItem]:
31613161
assert err == expected_err
31623162
assert len(conflicts) == len(expected_conflicts)
31633163
assert set(conflicts) == set(expected_conflicts)
3164+
3165+
3166+
@pytest.mark.anyio
3167+
async def test_new_peak_deferred_ff_items() -> None:
3168+
"""
3169+
Covers the case where we update lineage info for multiple fast forward
3170+
singletons at new peak.
3171+
"""
3172+
singleton_spend1 = make_singleton_spend(bytes32([1] * 32))
3173+
singleton1_id = singleton_spend1.coin.name()
3174+
singleton_spend2 = make_singleton_spend(bytes32([2] * 32))
3175+
singleton2_id = singleton_spend2.coin.name()
3176+
coins = TestCoins(
3177+
[singleton_spend1.coin, singleton_spend2.coin, TEST_COIN, TEST_COIN2],
3178+
{
3179+
singleton_spend1.coin.puzzle_hash: singleton_spend1.coin,
3180+
singleton_spend2.coin.puzzle_hash: singleton_spend2.coin,
3181+
},
3182+
)
3183+
mempool_manager = await setup_mempool(coins)
3184+
# Let's submit the two singletons transactions to the mempool
3185+
sb_names = []
3186+
for singleton_spend, regular_coin in [(singleton_spend1, TEST_COIN), (singleton_spend2, TEST_COIN2)]:
3187+
sb = SpendBundle([singleton_spend, mk_coin_spend(regular_coin)], G2Element())
3188+
sb_name = sb.name()
3189+
await mempool_manager.add_spend_bundle(
3190+
sb,
3191+
make_test_conds(spend_ids=[(singleton_spend.coin, ELIGIBLE_FOR_FF), (regular_coin, 0)], cost=1337),
3192+
sb_name,
3193+
uint32(1),
3194+
)
3195+
assert mempool_manager.get_mempool_item(sb_name) is not None
3196+
sb_names.append(sb_name)
3197+
# Let's advance the mempool by spending these singletons into new lineages
3198+
singleton1_new_latest = Coin(singleton1_id, singleton_spend1.coin.puzzle_hash, singleton_spend1.coin.amount)
3199+
coins.update_lineage(singleton_spend1.coin.puzzle_hash, singleton1_new_latest)
3200+
singleton2_new_latest = Coin(singleton2_id, singleton_spend2.coin.puzzle_hash, singleton_spend2.coin.amount)
3201+
coins.update_lineage(singleton_spend2.coin.puzzle_hash, singleton2_new_latest)
3202+
await advance_mempool(mempool_manager, [singleton1_id, singleton2_id], use_optimization=True)
3203+
# Both items should get updated with their related latest lineages
3204+
mi1 = mempool_manager.get_mempool_item(sb_names[0])
3205+
assert mi1 is not None
3206+
latest_singleton_lineage1 = mi1.bundle_coin_spends[singleton1_id].latest_singleton_lineage
3207+
assert latest_singleton_lineage1 is not None
3208+
assert latest_singleton_lineage1.coin_id == singleton1_new_latest.name()
3209+
mi2 = mempool_manager.get_mempool_item(sb_names[1])
3210+
assert mi2 is not None
3211+
latest_singleton_lineage2 = mi2.bundle_coin_spends[singleton2_id].latest_singleton_lineage
3212+
assert latest_singleton_lineage2 is not None
3213+
assert latest_singleton_lineage2.coin_id == singleton2_new_latest.name()

chia/full_node/mempool_manager.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ async def new_peak(
843843
# rebasing a fast forward spend is more expensive than to just
844844
# evict the item. So, any FF spend we may need to rebase, defer
845845
# them until after we've gone through all spends
846-
deferred_ff_items: set[tuple[bytes32, bytes32]] = set()
846+
deferred_ff_items: set[tuple[bytes32, MempoolItem]] = set()
847847

848848
for spend in spent_coins:
849849
items = self.mempool.get_items_by_coin_id(spend)
@@ -866,15 +866,16 @@ async def new_peak(
866866
spendbundle_ids_to_remove.add(item_name)
867867
continue
868868

869-
deferred_ff_items.add((spend, item_name))
869+
deferred_ff_items.add((spend, item))
870870

871871
# fast forward spends are indexed under the latest singleton coin ID
872872
# if it's spent, we need to update the index in the mempool. This
873873
# list lets us perform a bulk update
874874
# new_coin_id, current_coin_id, mempool item name
875875
spends_to_update: list[tuple[bytes32, bytes32, bytes32]] = []
876876

877-
for spend, item_name in deferred_ff_items:
877+
for spend, item in deferred_ff_items:
878+
item_name = item.spend_bundle_name
878879
if item_name in spendbundle_ids_to_remove:
879880
continue
880881
# there may be multiple matching spends in the mempool

0 commit comments

Comments
 (0)