@@ -2616,6 +2616,51 @@ fn tenure_extend_after_idle_signers() {
2616
2616
return ;
2617
2617
}
2618
2618
2619
+ tracing_subscriber:: registry ( )
2620
+ . with ( fmt:: layer ( ) )
2621
+ . with ( EnvFilter :: from_default_env ( ) )
2622
+ . init ( ) ;
2623
+
2624
+ info ! ( "------------------------- Test Setup -------------------------" ) ;
2625
+ let num_signers = 5 ;
2626
+ let idle_timeout = Duration :: from_secs ( 30 ) ;
2627
+ let mut signer_test: SignerTest < SpawnedSigner > = SignerTest :: new_with_config_modifications (
2628
+ num_signers,
2629
+ vec ! [ ] ,
2630
+ |config| {
2631
+ config. tenure_idle_timeout = idle_timeout;
2632
+ } ,
2633
+ |_| { } ,
2634
+ None ,
2635
+ None ,
2636
+ ) ;
2637
+
2638
+ signer_test. boot_to_epoch_3 ( ) ;
2639
+
2640
+ info ! ( "---- Nakamoto booted, starting test ----" ) ;
2641
+ signer_test. mine_nakamoto_block ( Duration :: from_secs ( 30 ) , true ) ;
2642
+
2643
+ info ! ( "---- Waiting for a tenure extend ----" ) ;
2644
+
2645
+ // Now, wait for a block with a tenure extend
2646
+ wait_for ( idle_timeout. as_secs ( ) + 10 , || {
2647
+ Ok ( last_block_contains_tenure_change_tx (
2648
+ TenureChangeCause :: Extended ,
2649
+ ) )
2650
+ } )
2651
+ . expect ( "Timed out waiting for a block with a tenure extend" ) ;
2652
+
2653
+ signer_test. shutdown ( ) ;
2654
+ }
2655
+
2656
+ #[ test]
2657
+ #[ ignore]
2658
+ /// This test verifies that a miner will include other transactions with a TenureExtend transaction.
2659
+ fn tenure_extend_with_other_transactions ( ) {
2660
+ if env:: var ( "BITCOIND_TEST" ) != Ok ( "1" . into ( ) ) {
2661
+ return ;
2662
+ }
2663
+
2619
2664
tracing_subscriber:: registry ( )
2620
2665
. with ( fmt:: layer ( ) )
2621
2666
. with ( EnvFilter :: from_default_env ( ) )
@@ -2627,7 +2672,7 @@ fn tenure_extend_after_idle_signers() {
2627
2672
let sender_addr = tests:: to_addr ( & sender_sk) ;
2628
2673
let send_amt = 100 ;
2629
2674
let send_fee = 180 ;
2630
- let _recipient = PrincipalData :: from ( StacksAddress :: burn_address ( false ) ) ;
2675
+ let recipient = PrincipalData :: from ( StacksAddress :: burn_address ( false ) ) ;
2631
2676
let idle_timeout = Duration :: from_secs ( 30 ) ;
2632
2677
let mut signer_test: SignerTest < SpawnedSigner > = SignerTest :: new_with_config_modifications (
2633
2678
num_signers,
@@ -2639,20 +2684,72 @@ fn tenure_extend_after_idle_signers() {
2639
2684
None ,
2640
2685
None ,
2641
2686
) ;
2642
- let _http_origin = format ! ( "http://{}" , & signer_test. running_nodes. conf. node. rpc_bind) ;
2687
+ let http_origin = format ! ( "http://{}" , & signer_test. running_nodes. conf. node. rpc_bind) ;
2643
2688
2644
2689
signer_test. boot_to_epoch_3 ( ) ;
2645
2690
2646
2691
info ! ( "---- Nakamoto booted, starting test ----" ) ;
2647
2692
signer_test. mine_nakamoto_block ( Duration :: from_secs ( 30 ) , true ) ;
2648
2693
2649
- info ! ( "---- Waiting for a tenure extend ----" ) ;
2694
+ info ! ( "Pause miner so it doesn't propose a block before the tenure extend" ) ;
2695
+ TEST_MINE_STALL . set ( true ) ;
2696
+
2697
+ // Submit a transaction to be included with the tenure extend
2698
+ let transfer_tx = make_stacks_transfer (
2699
+ & sender_sk,
2700
+ 0 ,
2701
+ send_fee,
2702
+ signer_test. running_nodes . conf . burnchain . chain_id ,
2703
+ & recipient,
2704
+ send_amt,
2705
+ ) ;
2706
+ let _tx = submit_tx ( & http_origin, & transfer_tx) ;
2707
+
2708
+ info ! ( "---- Wait for tenure extend timeout ----" ) ;
2709
+
2710
+ sleep_ms ( idle_timeout. as_millis ( ) as u64 + 1000 ) ;
2711
+
2712
+ info ! ( "---- Resume miner to propose a block with the tenure extend ----" ) ;
2713
+ TEST_MINE_STALL . set ( false ) ;
2650
2714
2651
2715
// Now, wait for a block with a tenure extend
2652
2716
wait_for ( idle_timeout. as_secs ( ) + 10 , || {
2653
- Ok ( last_block_contains_tenure_change_tx (
2654
- TenureChangeCause :: Extended ,
2655
- ) )
2717
+ let blocks = test_observer:: get_blocks ( ) ;
2718
+ let last_block = & blocks. last ( ) . unwrap ( ) ;
2719
+ let transactions = last_block[ "transactions" ] . as_array ( ) . unwrap ( ) ;
2720
+ let ( first_tx, other_txs) = transactions. split_first ( ) . unwrap ( ) ;
2721
+ let raw_tx = first_tx[ "raw_tx" ] . as_str ( ) . unwrap ( ) ;
2722
+ let tx_bytes = hex_bytes ( & raw_tx[ 2 ..] ) . unwrap ( ) ;
2723
+ let parsed = StacksTransaction :: consensus_deserialize ( & mut & tx_bytes[ ..] ) . unwrap ( ) ;
2724
+ let found_tenure_extend = match & parsed. payload {
2725
+ TransactionPayload :: TenureChange ( payload)
2726
+ if payload. cause == TenureChangeCause :: Extended =>
2727
+ {
2728
+ info ! ( "Found tenure extend transaction: {parsed:?}" ) ;
2729
+ true
2730
+ }
2731
+ _ => false ,
2732
+ } ;
2733
+ if found_tenure_extend {
2734
+ let found_transfer = other_txs. iter ( ) . any ( |tx| {
2735
+ let raw_tx = tx[ "raw_tx" ] . as_str ( ) . unwrap ( ) ;
2736
+ let tx_bytes = hex_bytes ( & raw_tx[ 2 ..] ) . unwrap ( ) ;
2737
+ let parsed = StacksTransaction :: consensus_deserialize ( & mut & tx_bytes[ ..] ) . unwrap ( ) ;
2738
+ match & parsed. payload {
2739
+ TransactionPayload :: TokenTransfer ( ..) => true ,
2740
+ _ => false ,
2741
+ }
2742
+ } ) ;
2743
+ if found_transfer {
2744
+ info ! ( "Found transfer transaction" ) ;
2745
+ Ok ( true )
2746
+ } else {
2747
+ Err ( "No transfer transaction found together with the tenure extend" . to_string ( ) )
2748
+ }
2749
+ } else {
2750
+ info ! ( "No tenure change transaction found" ) ;
2751
+ Ok ( false )
2752
+ }
2656
2753
} )
2657
2754
. expect ( "Timed out waiting for a block with a tenure extend" ) ;
2658
2755
@@ -6438,19 +6535,22 @@ fn miner_recovers_when_broadcast_block_delay_across_tenures_occurs() {
6438
6535
/// Mine 2 empty burn blocks (simulate fast blocks scenario)
6439
6536
/// Miner 2 proposes block N+1 with a TenureChangePayload
6440
6537
/// Signers accept and the stacks tip advances to N+1
6441
- /// Miner 2 proposes block N+2 with a TokenTransfer
6538
+ /// Miner 2 proposes block N+2 with a TenureExtend
6442
6539
/// Signers accept and the stacks tip advances to N+2
6540
+ /// Miner 2 proposes block N+3 with a TokenTransfer
6541
+ /// Signers accept and the stacks tip advances to N+3
6443
6542
/// Mine an empty burn block
6444
- /// Miner 2 proposes block N+3 with a TenureExtend
6445
- /// Signers accept and the chain advances to N+3
6446
- /// Miner 1 wins the next tenure and proposes a block N+4 with a TenureChangePayload
6543
+ /// Miner 2 proposes block N+4 with a TenureExtend
6447
6544
/// Signers accept and the chain advances to N+4
6545
+ /// Miner 1 wins the next tenure and proposes a block N+5 with a TenureChangePayload
6546
+ /// Signers accept and the chain advances to N+5
6448
6547
/// Asserts:
6449
6548
/// - Block N+1 contains the TenureChangePayload
6450
- /// - Block N+2 contains the TokenTransfer
6451
- /// - Block N+3 contains the TenureExtend
6452
- /// - Block N+4 contains the TenureChangePayload
6453
- /// - The stacks tip advances to N+4
6549
+ /// - Block N+2 contains the TenureExtend
6550
+ /// - Block N+3 contains the TokenTransfer
6551
+ /// - Block N+4 contains the TenureExtend
6552
+ /// - Block N+5 contains the TenureChangePayload
6553
+ /// - The stacks tip advances to N+5
6454
6554
#[ test]
6455
6555
#[ ignore]
6456
6556
fn continue_after_fast_block_no_sortition ( ) {
@@ -6811,7 +6911,7 @@ fn continue_after_fast_block_no_sortition() {
6811
6911
// Allow signers to respond to proposals again
6812
6912
TEST_REJECT_ALL_BLOCK_PROPOSAL . set ( Vec :: new ( ) ) ;
6813
6913
6814
- info ! ( "------------------------- Wait for Miner B's Block N -------------------------" ;
6914
+ info ! ( "------------------------- Wait for Miner B's Block N+1 -------------------------" ;
6815
6915
"blocks_processed_before_2" => %blocks_processed_before_2,
6816
6916
"stacks_height_before" => %stacks_height_before,
6817
6917
"nmb_old_blocks" => %nmb_old_blocks) ;
@@ -6826,7 +6926,7 @@ fn continue_after_fast_block_no_sortition() {
6826
6926
6827
6927
let blocks_mined1_val = blocks_mined1. load ( Ordering :: SeqCst ) ;
6828
6928
let blocks_mined2_val = blocks_mined2. load ( Ordering :: SeqCst ) ;
6829
- info ! ( "Waiting for Miner B's Block N" ;
6929
+ info ! ( "Waiting for Miner B's Block N+1 " ;
6830
6930
"blocks_mined1_val" => %blocks_mined1_val,
6831
6931
"blocks_mined2_val" => %blocks_mined2_val,
6832
6932
"stacks_height" => %stacks_height,
@@ -6841,11 +6941,11 @@ fn continue_after_fast_block_no_sortition() {
6841
6941
. expect ( "Timed out waiting for block to be mined and processed" ) ;
6842
6942
6843
6943
info ! (
6844
- "------------------------- Verify Tenure Change Tx in Miner B's Block N -------------------------"
6944
+ "------------------------- Verify Tenure Change Tx in Miner B's Block N+1 -------------------------"
6845
6945
) ;
6846
6946
verify_last_block_contains_tenure_change_tx ( TenureChangeCause :: BlockFound ) ;
6847
6947
6848
- info ! ( "------------------------- Wait for Miner B's Block N+1 -------------------------" ) ;
6948
+ info ! ( "------------------------- Wait for Miner B's Block N+2 -------------------------" ) ;
6849
6949
6850
6950
let nmb_old_blocks = test_observer:: get_blocks ( ) . len ( ) ;
6851
6951
let blocks_processed_before_2 = blocks_mined2. load ( Ordering :: SeqCst ) ;
@@ -6855,18 +6955,7 @@ fn continue_after_fast_block_no_sortition() {
6855
6955
. expect ( "Failed to get peer info" )
6856
6956
. stacks_tip_height ;
6857
6957
6858
- // submit a tx so that the miner will mine an extra block
6859
- let transfer_tx = make_stacks_transfer (
6860
- & sender_sk,
6861
- sender_nonce,
6862
- send_fee,
6863
- signer_test. running_nodes . conf . burnchain . chain_id ,
6864
- & recipient,
6865
- send_amt,
6866
- ) ;
6867
- submit_tx ( & http_origin, & transfer_tx) ;
6868
-
6869
- // wait for the tenure-extend block to be processed
6958
+ // wait for the transfer block to be processed
6870
6959
wait_for ( 30 , || {
6871
6960
let stacks_height = signer_test
6872
6961
. stacks_client
@@ -6881,8 +6970,12 @@ fn continue_after_fast_block_no_sortition() {
6881
6970
} )
6882
6971
. expect ( "Timed out waiting for block to be mined and processed" ) ;
6883
6972
6973
+ info ! ( "------------------------- Verify Miner B's Block N+2 -------------------------" ) ;
6974
+
6884
6975
verify_last_block_contains_tenure_change_tx ( TenureChangeCause :: Extended ) ;
6885
6976
6977
+ info ! ( "------------------------- Wait for Miner B's Block N+3 -------------------------" ) ;
6978
+
6886
6979
let nmb_old_blocks = test_observer:: get_blocks ( ) . len ( ) ;
6887
6980
let blocks_processed_before_2 = blocks_mined2. load ( Ordering :: SeqCst ) ;
6888
6981
let stacks_height_before = signer_test
@@ -6891,22 +6984,24 @@ fn continue_after_fast_block_no_sortition() {
6891
6984
. expect ( "Failed to get peer info" )
6892
6985
. stacks_tip_height ;
6893
6986
6894
- // wait for the new block with the STX transfer to be processed
6987
+ // submit a tx so that the miner will mine an extra block
6988
+ let transfer_tx = make_stacks_transfer (
6989
+ & sender_sk,
6990
+ sender_nonce,
6991
+ send_fee,
6992
+ signer_test. running_nodes . conf . burnchain . chain_id ,
6993
+ & recipient,
6994
+ send_amt,
6995
+ ) ;
6996
+ submit_tx ( & http_origin, & transfer_tx) ;
6997
+
6998
+ // wait for the transfer block to be processed
6895
6999
wait_for ( 30 , || {
6896
7000
let stacks_height = signer_test
6897
7001
. stacks_client
6898
7002
. get_peer_info ( )
6899
7003
. expect ( "Failed to get peer info" )
6900
7004
. stacks_tip_height ;
6901
-
6902
- let blocks_mined1_val = blocks_mined1. load ( Ordering :: SeqCst ) ;
6903
- let blocks_mined2_val = blocks_mined2. load ( Ordering :: SeqCst ) ;
6904
- info ! ( "Waiting for Miner B's Block N" ;
6905
- "blocks_mined1_val" => %blocks_mined1_val,
6906
- "blocks_mined2_val" => %blocks_mined2_val,
6907
- "stacks_height" => %stacks_height,
6908
- "observed_blocks" => %test_observer:: get_blocks( ) . len( ) ) ;
6909
-
6910
7005
Ok (
6911
7006
blocks_mined2. load ( Ordering :: SeqCst ) > blocks_processed_before_2
6912
7007
&& stacks_height > stacks_height_before
@@ -6915,7 +7010,7 @@ fn continue_after_fast_block_no_sortition() {
6915
7010
} )
6916
7011
. expect ( "Timed out waiting for block to be mined and processed" ) ;
6917
7012
6918
- info ! ( "------------------------- Verify Miner B's Block N+1 -------------------------" ) ;
7013
+ info ! ( "------------------------- Verify Miner B's Block N+3 -------------------------" ) ;
6919
7014
6920
7015
verify_last_block_contains_transfer_tx ( ) ;
6921
7016
@@ -6932,7 +7027,7 @@ fn continue_after_fast_block_no_sortition() {
6932
7027
. unwrap ( ) ;
6933
7028
btc_blocks_mined += 1 ;
6934
7029
6935
- info ! ( "------------------------- Verify Miner B's Issues a Tenure Change Extend in Block N+2 -------------------------" ) ;
7030
+ info ! ( "------------------------- Verify Miner B's Issues a Tenure Change Extend in Block N+4 -------------------------" ) ;
6936
7031
verify_last_block_contains_tenure_change_tx ( TenureChangeCause :: Extended ) ;
6937
7032
6938
7033
info ! ( "------------------------- Unpause Miner A's Block Commits -------------------------" ) ;
@@ -6967,7 +7062,7 @@ fn continue_after_fast_block_no_sortition() {
6967
7062
assert ! ( tip. sortition) ;
6968
7063
assert_eq ! ( tip. miner_pk_hash. unwrap( ) , mining_pkh_1) ;
6969
7064
6970
- info ! ( "------------------------- Verify Miner A's Issued a Tenure Change in Block N+4 -------------------------" ) ;
7065
+ info ! ( "------------------------- Verify Miner A's Issued a Tenure Change in Block N+5 -------------------------" ) ;
6971
7066
verify_last_block_contains_tenure_change_tx ( TenureChangeCause :: BlockFound ) ;
6972
7067
6973
7068
info ! (
0 commit comments