@@ -3294,3 +3294,65 @@ def compare_unfinished_blocks(block1: UnfinishedBlock, block2: UnfinishedBlock)
3294
3294
# Final assertion to check the entire block
3295
3295
assert block1 == block2 , "The entire block objects are not identical"
3296
3296
return True
3297
+
3298
+
3299
+ @pytest .mark .anyio
3300
+ @pytest .mark .parametrize (
3301
+ "condition_and_error" ,
3302
+ [
3303
+ (ConditionOpcode .ASSERT_HEIGHT_RELATIVE , "ASSERT_HEIGHT_RELATIVE_FAILED" ),
3304
+ (ConditionOpcode .ASSERT_HEIGHT_ABSOLUTE , "ASSERT_HEIGHT_ABSOLUTE_FAILED" ),
3305
+ ],
3306
+ )
3307
+ async def test_peak_post_processing_added_tx (
3308
+ condition_and_error : tuple [ConditionOpcode , str ],
3309
+ blockchain_constants : ConsensusConstants ,
3310
+ caplog : pytest .LogCaptureFixture ,
3311
+ ) -> None :
3312
+ """
3313
+ Tests peak post processing with regards to pending transactions due of
3314
+ time-lock to make sure they get retried once the time-lock allows them to
3315
+ be reconsidered.
3316
+ """
3317
+ async with setup_simulators_and_wallets (1 , 0 , blockchain_constants ) as new :
3318
+ full_node_api = new .simulators [0 ].peer_api
3319
+ bt = new .bt
3320
+ wallet = WalletTool (test_constants )
3321
+ ph = wallet .get_new_puzzlehash ()
3322
+ blocks = bt .get_consecutive_blocks (
3323
+ 3 , guarantee_transaction_block = True , farmer_reward_puzzle_hash = ph , pool_reward_puzzle_hash = ph
3324
+ )
3325
+ for block in blocks :
3326
+ await full_node_api .full_node .add_block (block )
3327
+ peak = full_node_api .full_node .blockchain .get_peak ()
3328
+ assert peak is not None
3329
+ current_height = peak .height
3330
+ # Create a transaction with a height condition that makes it pending
3331
+ coin = blocks [- 1 ].get_included_reward_coins ()[0 ]
3332
+ condition , expected_error = condition_and_error
3333
+ if condition == ConditionOpcode .ASSERT_HEIGHT_RELATIVE :
3334
+ condition_height = 1
3335
+ else :
3336
+ condition_height = current_height + 1
3337
+ condition_dic = {condition : [ConditionWithArgs (condition , [int_to_bytes (condition_height )])]}
3338
+ sb = wallet .generate_signed_transaction (uint64 (42 ), ph , coin , condition_dic )
3339
+ sb_name = sb .name ()
3340
+ # Send the transaction
3341
+ res = await full_node_api .send_transaction (SendTransaction (sb ))
3342
+ assert res is not None
3343
+ assert ProtocolMessageTypes (res .type ) == ProtocolMessageTypes .transaction_ack
3344
+ transaction_ack = TransactionAck .from_bytes (res .data )
3345
+ assert transaction_ack .status == MempoolInclusionStatus .PENDING .value
3346
+ assert transaction_ack .error == expected_error
3347
+ # Make sure it ends up in the pending cache, not the mempool
3348
+ assert full_node_api .full_node .mempool_manager .get_mempool_item (sb_name , include_pending = False ) is None
3349
+ assert full_node_api .full_node .mempool_manager .get_mempool_item (sb_name , include_pending = True ) is not None
3350
+ # Advance to meet the condition
3351
+ with caplog .at_level (logging .DEBUG ):
3352
+ blocks = bt .get_consecutive_blocks (2 , block_list_input = blocks , guarantee_transaction_block = True )
3353
+ for block in blocks :
3354
+ await full_node_api .full_node .add_block (block )
3355
+ # This should trigger peak post processing with the added transaction
3356
+ assert f"Added transaction to mempool: { sb_name } \n " in caplog .text
3357
+ # Make sure the transaction was retried and got added to the mempool
3358
+ assert full_node_api .full_node .mempool_manager .get_mempool_item (sb_name , include_pending = False ) is not None
0 commit comments