@@ -3213,6 +3213,97 @@ def test_get_puzzle_and_solution_for_coin_failure() -> None:
32133213 raise ValueError (f"Failed to get puzzle and solution for coin { TEST_COIN } , error: { e } " ) from e
32143214
32153215
3216+ # this puzzle just creates coins, however many are requested by the solution
3217+ # (mod (A)
3218+ # (defun loop (n)
3219+ # (if (= n 1)
3220+ # (list)
3221+ # (c (list 51 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff n) (loop (- n 1))))
3222+ # )
3223+ # (loop A)
3224+ # )
3225+ create_coins_loop : str = (
3226+ "ff02ffff01ff02ff02ffff04ff02ffff04ff05ff80808080ffff04ffff01ff02"
3227+ "ffff03ffff09ff05ffff010180ff80ffff01ff04ffff04ffff0133ffff04ffff"
3228+ "01a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
3229+ "ffffffff04ff05ff80808080ffff02ff02ffff04ff02ffff04ffff11ff05ffff"
3230+ "010180ff808080808080ff0180ff018080"
3231+ )
3232+
3233+
3234+ # this test uses artificial puzzles just to exercise the block creation. These
3235+ # spends are expected not to verify any signatures
3236+ # This is to keep the test simple.
3237+ @pytest .mark .parametrize (
3238+ "puzzle, solution" ,
3239+ [
3240+ # create 2000 coins
3241+ (create_coins_loop , "ff8207d180" ),
3242+ # create 1000 coins
3243+ (create_coins_loop , "ff8203e980" ),
3244+ # create 500 coins
3245+ (create_coins_loop , "ff8201f580" ),
3246+ ],
3247+ )
3248+ @pytest .mark .parametrize ("old" , [True , False ])
3249+ def test_create_block_generator_custom_spend (puzzle : str , solution : str , old : bool ) -> None :
3250+ mempool_info = MempoolInfo (
3251+ CLVMCost (uint64 (11000000000 * 3 )),
3252+ FeeRate (uint64 (1000000 )),
3253+ CLVMCost (uint64 (11000000000 )),
3254+ )
3255+
3256+ fee_estimator = create_bitcoin_fee_estimator (test_constants .MAX_BLOCK_COST_CLVM )
3257+ solution_str = SerializedProgram .fromhex (solution )
3258+ puzzle_reveal = SerializedProgram .fromhex (puzzle )
3259+ puzzle_hash = puzzle_reveal .get_tree_hash ()
3260+ mempool = Mempool (mempool_info , fee_estimator )
3261+ coins = [Coin (bytes32 .random (), puzzle_hash , uint64 (amount )) for amount in range (100000000 , 100000022 )]
3262+
3263+ spend_bundles = [
3264+ SpendBundle (
3265+ coin_spends = [CoinSpend (coin , puzzle_reveal = puzzle_reveal , solution = solution_str )],
3266+ aggregated_signature = G2Element (),
3267+ )
3268+ for coin in coins
3269+ ]
3270+
3271+ for sb in spend_bundles :
3272+ mi = mempool_item_from_spendbundle (sb )
3273+ mempool .add_to_pool (mi )
3274+ invariant_check_mempool (mempool )
3275+
3276+ create_block = mempool .create_block_generator if old else mempool .create_block_generator2
3277+ generator = create_block (test_constants , test_constants .HARD_FORK2_HEIGHT , 10.0 )
3278+ assert generator is not None
3279+
3280+ assert generator .signature == G2Element ()
3281+
3282+ removals = set (generator .removals )
3283+
3284+ err , conds = run_block_generator2 (
3285+ bytes (generator .program ),
3286+ generator .generator_refs ,
3287+ test_constants .MAX_BLOCK_COST_CLVM ,
3288+ 0 ,
3289+ generator .signature ,
3290+ None ,
3291+ test_constants ,
3292+ )
3293+
3294+ assert err is None
3295+ assert conds is not None
3296+
3297+ assert len (conds .spends ) == len (removals )
3298+
3299+ for spend in conds .spends :
3300+ removal = Coin (spend .parent_id , spend .puzzle_hash , uint64 (spend .coin_amount ))
3301+ assert removal in coins
3302+ assert removal in removals
3303+
3304+ invariant_check_mempool (mempool )
3305+
3306+
32163307@pytest .mark .parametrize ("old" , [True , False ])
32173308def test_create_block_generator (old : bool ) -> None :
32183309 mempool = construct_mempool ()
0 commit comments