@@ -48,7 +48,10 @@ use stacks::chainstate::nakamoto::coordinator::{load_nakamoto_reward_set, TEST_C
48
48
use stacks:: chainstate:: nakamoto:: miner:: NakamotoBlockBuilder ;
49
49
use stacks:: chainstate:: nakamoto:: shadow:: shadow_chainstate_repair;
50
50
use stacks:: chainstate:: nakamoto:: test_signers:: TestSigners ;
51
- use stacks:: chainstate:: nakamoto:: { NakamotoBlock , NakamotoBlockHeader , NakamotoChainState } ;
51
+ use stacks:: chainstate:: nakamoto:: {
52
+ set_test_sip_031_emission_schedule, NakamotoBlock , NakamotoBlockHeader , NakamotoChainState ,
53
+ SIP031EmissionInterval ,
54
+ } ;
52
55
use stacks:: chainstate:: stacks:: address:: { PoxAddress , StacksAddressExtensions } ;
53
56
use stacks:: chainstate:: stacks:: boot:: {
54
57
MINERS_NAME , SIGNERS_VOTING_FUNCTION_NAME , SIGNERS_VOTING_NAME ,
@@ -3075,6 +3078,7 @@ fn block_proposal_api_endpoint() {
3075
3078
let mut miner_tenure_info = builder
3076
3079
. load_tenure_info ( & mut chainstate, & burn_dbconn, tenure_cause)
3077
3080
. unwrap ( ) ;
3081
+ let burn_chain_height = miner_tenure_info. burn_tip_height ;
3078
3082
let mut tenure_tx = builder
3079
3083
. tenure_begin ( & burn_dbconn, & mut miner_tenure_info)
3080
3084
. unwrap ( ) ;
@@ -3103,7 +3107,7 @@ fn block_proposal_api_endpoint() {
3103
3107
matches!( res, TransactionResult :: Success ( ..) ) ,
3104
3108
"Transaction failed"
3105
3109
) ;
3106
- builder. mine_nakamoto_block ( & mut tenure_tx)
3110
+ builder. mine_nakamoto_block ( & mut tenure_tx, burn_chain_height )
3107
3111
} ;
3108
3112
3109
3113
// Construct a valid proposal. Make alterations to this to test failure cases
@@ -12918,3 +12922,192 @@ fn test_sip_031_activation() {
12918
12922
12919
12923
run_loop_thread. join ( ) . unwrap ( ) ;
12920
12924
}
12925
+
12926
+ /// Test SIP-031 last phase per-tenure-mint-and-transfer
12927
+ ///
12928
+ /// - check epoch 3.2 is active
12929
+ /// - check minting event and boot contract transfer for the first (and only the first) block of a tenure
12930
+ #[ test]
12931
+ #[ ignore]
12932
+ fn test_sip_031_last_phase ( ) {
12933
+ if env:: var ( "BITCOIND_TEST" ) != Ok ( "1" . into ( ) ) {
12934
+ return ;
12935
+ }
12936
+
12937
+ let ( mut naka_conf, _miner_account) = naka_neon_integration_conf ( None ) ;
12938
+ naka_conf. node . pox_sync_sample_secs = 180 ;
12939
+ naka_conf. burnchain . max_rbf = 10_000_000 ;
12940
+
12941
+ let sender_sk = Secp256k1PrivateKey :: random ( ) ;
12942
+ let sender_signer_sk = Secp256k1PrivateKey :: random ( ) ;
12943
+ let sender_signer_addr = tests:: to_addr ( & sender_signer_sk) ;
12944
+ let mut signers = TestSigners :: new ( vec ! [ sender_signer_sk] ) ;
12945
+ let tenure_count = 5 ;
12946
+ let inter_blocks_per_tenure = 9 ;
12947
+ // setup sender + recipient for some test stx transfers
12948
+ // these are necessary for the interim blocks to get mined at all
12949
+ let sender_addr = tests:: to_addr ( & sender_sk) ;
12950
+ let send_amt = 100 ;
12951
+ let send_fee = 180 ;
12952
+ naka_conf. add_initial_balance (
12953
+ PrincipalData :: from ( sender_addr) . to_string ( ) ,
12954
+ ( send_amt + send_fee) * tenure_count * inter_blocks_per_tenure,
12955
+ ) ;
12956
+ naka_conf. add_initial_balance ( PrincipalData :: from ( sender_signer_addr) . to_string ( ) , 100000 ) ;
12957
+ let stacker_sk = setup_stacker ( & mut naka_conf) ;
12958
+
12959
+ let epoch32_start_height =
12960
+ naka_conf. burnchain . epochs . clone ( ) . unwrap ( ) [ StacksEpochId :: Epoch32 ] . start_height ;
12961
+
12962
+ set_test_sip_031_emission_schedule ( Some ( vec ! [
12963
+ SIP031EmissionInterval {
12964
+ amount: 0 ,
12965
+ start_height: epoch32_start_height + 40 ,
12966
+ } ,
12967
+ SIP031EmissionInterval {
12968
+ amount: 300_000 ,
12969
+ start_height: epoch32_start_height + 30 ,
12970
+ } ,
12971
+ SIP031EmissionInterval {
12972
+ amount: 200_000 ,
12973
+ start_height: epoch32_start_height + 20 ,
12974
+ } ,
12975
+ SIP031EmissionInterval {
12976
+ amount: 100_000 ,
12977
+ start_height: epoch32_start_height + 10 ,
12978
+ } ,
12979
+ ] ) ) ;
12980
+
12981
+ test_observer:: spawn ( ) ;
12982
+ test_observer:: register_any ( & mut naka_conf) ;
12983
+
12984
+ let mut btcd_controller = BitcoinCoreController :: new ( naka_conf. clone ( ) ) ;
12985
+ btcd_controller
12986
+ . start_bitcoind ( )
12987
+ . expect ( "Failed starting bitcoind" ) ;
12988
+ let mut btc_regtest_controller = BitcoinRegtestController :: new ( naka_conf. clone ( ) , None ) ;
12989
+ btc_regtest_controller. bootstrap_chain ( 201 ) ;
12990
+
12991
+ let mut run_loop = boot_nakamoto:: BootRunLoop :: new ( naka_conf. clone ( ) ) . unwrap ( ) ;
12992
+ let run_loop_stopper = run_loop. get_termination_switch ( ) ;
12993
+ let Counters {
12994
+ blocks_processed,
12995
+ naka_submitted_commits : commits_submitted,
12996
+ ..
12997
+ } = run_loop. counters ( ) ;
12998
+ let counters = run_loop. counters ( ) ;
12999
+
13000
+ let coord_channel = run_loop. coordinator_channels ( ) ;
13001
+
13002
+ let run_loop_thread = thread:: Builder :: new ( )
13003
+ . name ( "run_loop" . into ( ) )
13004
+ . spawn ( move || run_loop. start ( None , 0 ) )
13005
+ . unwrap ( ) ;
13006
+ wait_for_runloop ( & blocks_processed) ;
13007
+ boot_to_epoch_3 (
13008
+ & naka_conf,
13009
+ & blocks_processed,
13010
+ & [ stacker_sk] ,
13011
+ & [ sender_signer_sk] ,
13012
+ & mut Some ( & mut signers) ,
13013
+ & mut btc_regtest_controller,
13014
+ ) ;
13015
+
13016
+ info ! ( "Bootstrapped to Epoch-3.0 boundary, starting nakamoto miner" ) ;
13017
+
13018
+ let burnchain = naka_conf. get_burnchain ( ) ;
13019
+ let sortdb = burnchain. open_sortition_db ( true ) . unwrap ( ) ;
13020
+ let ( mut chainstate, _) = StacksChainState :: open (
13021
+ naka_conf. is_mainnet ( ) ,
13022
+ naka_conf. burnchain . chain_id ,
13023
+ & naka_conf. get_chainstate_path_str ( ) ,
13024
+ None ,
13025
+ )
13026
+ . unwrap ( ) ;
13027
+
13028
+ info ! ( "Nakamoto miner started..." ) ;
13029
+ blind_signer ( & naka_conf, & signers, & counters) ;
13030
+
13031
+ wait_for_first_naka_block_commit ( 60 , & commits_submitted) ;
13032
+
13033
+ // mine until epoch 3.2 height
13034
+ loop {
13035
+ let commits_before = commits_submitted. load ( Ordering :: SeqCst ) ;
13036
+ next_block_and_process_new_stacks_block ( & mut btc_regtest_controller, 60 , & coord_channel)
13037
+ . unwrap ( ) ;
13038
+ wait_for ( 20 , || {
13039
+ Ok ( commits_submitted. load ( Ordering :: SeqCst ) > commits_before)
13040
+ } )
13041
+ . unwrap ( ) ;
13042
+
13043
+ let node_info = get_chain_info_opt ( & naka_conf) . unwrap ( ) ;
13044
+ if node_info. burn_block_height >= epoch32_start_height {
13045
+ break ;
13046
+ }
13047
+ }
13048
+
13049
+ info ! (
13050
+ "Nakamoto miner has advanced to bitcoin height {}" ,
13051
+ get_chain_info_opt( & naka_conf) . unwrap( ) . burn_block_height
13052
+ ) ;
13053
+
13054
+ let latest_stacks_block_id = get_latest_block_proposal ( & naka_conf, & sortdb)
13055
+ . unwrap ( )
13056
+ . 0
13057
+ . block_id ( ) ;
13058
+
13059
+ // check if sip-031 boot contract has a balance of 200_000_000 STX
13060
+ let sip_031_boot_contract_balance = chainstate. with_read_only_clarity_tx (
13061
+ & sortdb
13062
+ . index_handle_at_block ( & chainstate, & latest_stacks_block_id)
13063
+ . unwrap ( ) ,
13064
+ & latest_stacks_block_id,
13065
+ |conn| {
13066
+ conn. with_clarity_db_readonly ( |db| {
13067
+ db. get_account_stx_balance ( & PrincipalData :: Contract ( boot_code_id (
13068
+ SIP_031_NAME ,
13069
+ naka_conf. is_mainnet ( ) ,
13070
+ ) ) )
13071
+ } )
13072
+ } ,
13073
+ ) ;
13074
+
13075
+ assert_eq ! (
13076
+ sip_031_boot_contract_balance,
13077
+ Some ( Ok ( STXBalance :: Unlocked {
13078
+ amount: SIP_031_INITIAL_MINT
13079
+ } ) )
13080
+ ) ;
13081
+
13082
+ // get current liquidity
13083
+ let sip_031_current_liquid_ustx = chainstate
13084
+ . with_read_only_clarity_tx (
13085
+ & sortdb
13086
+ . index_handle_at_block ( & chainstate, & latest_stacks_block_id)
13087
+ . unwrap ( ) ,
13088
+ & latest_stacks_block_id,
13089
+ |conn| conn. with_clarity_db_readonly ( |db| db. get_total_liquid_ustx ( ) . unwrap ( ) ) ,
13090
+ )
13091
+ . unwrap ( ) ;
13092
+
13093
+ // 50 more tenures...
13094
+ for _ in 0 ..50 {
13095
+ let commits_before = commits_submitted. load ( Ordering :: SeqCst ) ;
13096
+ next_block_and_process_new_stacks_block ( & mut btc_regtest_controller, 60 , & coord_channel)
13097
+ . unwrap ( ) ;
13098
+ wait_for ( 20 , || {
13099
+ Ok ( commits_submitted. load ( Ordering :: SeqCst ) > commits_before)
13100
+ } )
13101
+ . unwrap ( ) ;
13102
+
13103
+ let node_info = get_chain_info_opt ( & naka_conf) . unwrap ( ) ;
13104
+ }
13105
+
13106
+ coord_channel
13107
+ . lock ( )
13108
+ . expect ( "Mutex poisoned" )
13109
+ . stop_chains_coordinator ( ) ;
13110
+ run_loop_stopper. store ( false , Ordering :: SeqCst ) ;
13111
+
13112
+ run_loop_thread. join ( ) . unwrap ( ) ;
13113
+ }
0 commit comments