@@ -3211,3 +3211,61 @@ async def test_new_peak_deferred_ff_items() -> None:
32113211 latest_singleton_lineage2 = mi2 .bundle_coin_spends [singleton2_id ].latest_singleton_lineage
32123212 assert latest_singleton_lineage2 is not None
32133213 assert latest_singleton_lineage2 .coin_id == singleton2_new_latest .name ()
3214+
3215+
3216+ @pytest .mark .anyio
3217+ async def test_different_ff_versions () -> None :
3218+ """
3219+ Covers the case where we send an item with an older ff singleton version
3220+ while the mempool is aware of a newer lineage.
3221+ """
3222+ launcher_id = bytes32 ([1 ] * 32 )
3223+ singleton_spend1 = make_singleton_spend (launcher_id , bytes32 ([2 ] * 32 ))
3224+ version1_id = singleton_spend1 .coin .name ()
3225+ singleton_spend2 = make_singleton_spend (launcher_id , bytes32 ([3 ] * 32 ))
3226+ version2_id = singleton_spend2 .coin .name ()
3227+ singleton_ph = singleton_spend2 .coin .puzzle_hash
3228+ coins = TestCoins (
3229+ [singleton_spend1 .coin , singleton_spend2 .coin , TEST_COIN , TEST_COIN2 ], {singleton_ph : singleton_spend2 .coin }
3230+ )
3231+ mempool_manager = await setup_mempool (coins )
3232+ mempool_items : list [MempoolItem ] = []
3233+ for singleton_spend , regular_coin in [(singleton_spend1 , TEST_COIN ), (singleton_spend2 , TEST_COIN2 )]:
3234+ sb = SpendBundle ([singleton_spend , mk_coin_spend (regular_coin )], G2Element ())
3235+ sb_name = sb .name ()
3236+ await mempool_manager .add_spend_bundle (
3237+ sb ,
3238+ make_test_conds (spend_ids = [(singleton_spend .coin , ELIGIBLE_FOR_FF ), (regular_coin , 0 )], cost = 1337 ),
3239+ sb_name ,
3240+ uint32 (1 ),
3241+ )
3242+ mi = mempool_manager .get_mempool_item (sb_name )
3243+ assert mi is not None
3244+ mempool_items .append (mi )
3245+ [mi1 , mi2 ] = mempool_items
3246+ latest_lineage_id = version2_id
3247+ assert latest_lineage_id != version1_id
3248+ # Bundle coin spends key points to version 1 but the lineage is latest (v2)
3249+ latest_singleton_lineage1 = mi1 .bundle_coin_spends [version1_id ].latest_singleton_lineage
3250+ assert latest_singleton_lineage1 is not None
3251+ assert latest_singleton_lineage1 .coin_id == latest_lineage_id
3252+ # Both the bundle coin spends key and the lineage point to latest (v2)
3253+ latest_singleton_lineage2 = mi2 .bundle_coin_spends [version2_id ].latest_singleton_lineage
3254+ assert latest_singleton_lineage2 is not None
3255+ assert latest_singleton_lineage2 .coin_id == latest_lineage_id
3256+ # Let's update the lineage with a new version of the singleton
3257+ new_latest_lineage = Coin (version2_id , singleton_ph , singleton_spend2 .coin .amount )
3258+ new_latest_lineage_id = new_latest_lineage .name ()
3259+ coins .update_lineage (singleton_ph , new_latest_lineage )
3260+ await advance_mempool (mempool_manager , [version1_id , version2_id ], use_optimization = True )
3261+ # Both items should get updated with the latest lineage
3262+ new_mi1 = mempool_manager .get_mempool_item (mi1 .spend_bundle_name )
3263+ assert new_mi1 is not None
3264+ latest_singleton_lineage1 = new_mi1 .bundle_coin_spends [version1_id ].latest_singleton_lineage
3265+ assert latest_singleton_lineage1 is not None
3266+ assert latest_singleton_lineage1 .coin_id == new_latest_lineage_id
3267+ new_mi2 = mempool_manager .get_mempool_item (mi2 .spend_bundle_name )
3268+ assert new_mi2 is not None
3269+ latest_singleton_lineage2 = new_mi2 .bundle_coin_spends [version2_id ].latest_singleton_lineage
3270+ assert latest_singleton_lineage2 is not None
3271+ assert latest_singleton_lineage2 .coin_id == new_latest_lineage_id
0 commit comments