|
14 | 14 | // You should have received a copy of the GNU General Public License
|
15 | 15 | // along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16 | 16 | use std::collections::{BTreeMap, HashMap, HashSet};
|
| 17 | +use std::fs::File; |
17 | 18 | use std::ops::RangeBounds;
|
18 | 19 | use std::sync::atomic::{AtomicU64, Ordering};
|
19 | 20 | use std::sync::mpsc::{channel, Receiver, Sender};
|
@@ -10688,7 +10689,7 @@ fn test_tenure_extend_from_flashblocks() {
|
10688 | 10689 | (define-data-var my-var uint u0)
|
10689 | 10690 | (define-data-var my-counter uint u0)
|
10690 | 10691 |
|
10691 |
| -(define-public (f) |
| 10692 | +(define-public (f) |
10692 | 10693 | (begin
|
10693 | 10694 | (var-set my-var burn-block-height)
|
10694 | 10695 | (if (is-eq u0 (mod burn-block-height u2))
|
@@ -11089,3 +11090,140 @@ fn mine_invalid_principal_from_consensus_buff() {
|
11089 | 11090 |
|
11090 | 11091 | run_loop_thread.join().unwrap();
|
11091 | 11092 | }
|
| 11093 | + |
| 11094 | +/// Test hot-reloading of miner config |
| 11095 | +#[test] |
| 11096 | +#[ignore] |
| 11097 | +fn reload_miner_config() { |
| 11098 | + if env::var("BITCOIND_TEST") != Ok("1".into()) { |
| 11099 | + return; |
| 11100 | + } |
| 11101 | + |
| 11102 | + let (mut conf, _miner_account) = naka_neon_integration_conf(None); |
| 11103 | + let password = "12345".to_string(); |
| 11104 | + let _http_origin = format!("http://{}", &conf.node.rpc_bind); |
| 11105 | + conf.connection_options.auth_token = Some(password.clone()); |
| 11106 | + conf.miner.wait_on_interim_blocks = Duration::from_secs(1); |
| 11107 | + let stacker_sk = setup_stacker(&mut conf); |
| 11108 | + let signer_sk = Secp256k1PrivateKey::random(); |
| 11109 | + let signer_addr = tests::to_addr(&signer_sk); |
| 11110 | + let sender_sk = Secp256k1PrivateKey::random(); |
| 11111 | + // setup sender + recipient for some test stx transfers |
| 11112 | + // these are necessary for the interim blocks to get mined at all |
| 11113 | + let sender_addr = tests::to_addr(&sender_sk); |
| 11114 | + conf.add_initial_balance(PrincipalData::from(sender_addr).to_string(), 1000000); |
| 11115 | + conf.add_initial_balance(PrincipalData::from(signer_addr).to_string(), 100000); |
| 11116 | + |
| 11117 | + test_observer::spawn(); |
| 11118 | + test_observer::register(&mut conf, &[EventKeyType::AnyEvent]); |
| 11119 | + |
| 11120 | + let mut btcd_controller = BitcoinCoreController::new(conf.clone()); |
| 11121 | + btcd_controller |
| 11122 | + .start_bitcoind() |
| 11123 | + .expect("Failed starting bitcoind"); |
| 11124 | + let mut btc_regtest_controller = BitcoinRegtestController::new(conf.clone(), None); |
| 11125 | + btc_regtest_controller.bootstrap_chain(201); |
| 11126 | + |
| 11127 | + let conf_path = |
| 11128 | + std::env::temp_dir().join(format!("miner-config-test-{}.toml", rand::random::<u64>())); |
| 11129 | + conf.config_path = Some(conf_path.clone().to_str().unwrap().to_string()); |
| 11130 | + |
| 11131 | + // Make a minimum-viable config file |
| 11132 | + let update_config = |burn_fee_cap: u64, sats_vbyte: u64| { |
| 11133 | + use std::io::Write; |
| 11134 | + |
| 11135 | + let new_config = format!( |
| 11136 | + r#" |
| 11137 | + [burnchain] |
| 11138 | + burn_fee_cap = {} |
| 11139 | + satoshis_per_byte = {} |
| 11140 | + "#, |
| 11141 | + burn_fee_cap, sats_vbyte, |
| 11142 | + ); |
| 11143 | + // Write to a file |
| 11144 | + let mut file = File::create(&conf_path).unwrap(); |
| 11145 | + file.write_all(new_config.as_bytes()).unwrap(); |
| 11146 | + }; |
| 11147 | + |
| 11148 | + update_config(100000, 50); |
| 11149 | + |
| 11150 | + let mut run_loop = boot_nakamoto::BootRunLoop::new(conf.clone()).unwrap(); |
| 11151 | + let run_loop_stopper = run_loop.get_termination_switch(); |
| 11152 | + let counters = run_loop.counters(); |
| 11153 | + let Counters { |
| 11154 | + blocks_processed, |
| 11155 | + naka_submitted_commits: commits_submitted, |
| 11156 | + .. |
| 11157 | + } = run_loop.counters(); |
| 11158 | + |
| 11159 | + let coord_channel = run_loop.coordinator_channels(); |
| 11160 | + |
| 11161 | + let run_loop_thread = thread::spawn(move || run_loop.start(None, 0)); |
| 11162 | + let mut signers = TestSigners::new(vec![signer_sk]); |
| 11163 | + wait_for_runloop(&blocks_processed); |
| 11164 | + boot_to_epoch_3( |
| 11165 | + &conf, |
| 11166 | + &blocks_processed, |
| 11167 | + &[stacker_sk], |
| 11168 | + &[signer_sk], |
| 11169 | + &mut Some(&mut signers), |
| 11170 | + &mut btc_regtest_controller, |
| 11171 | + ); |
| 11172 | + |
| 11173 | + info!("------------------------- Reached Epoch 3.0 -------------------------"); |
| 11174 | + |
| 11175 | + blind_signer(&conf, &signers, &counters); |
| 11176 | + |
| 11177 | + wait_for_first_naka_block_commit(60, &commits_submitted); |
| 11178 | + |
| 11179 | + next_block_and_mine_commit(&mut btc_regtest_controller, 60, &conf, &counters).unwrap(); |
| 11180 | + |
| 11181 | + let burn_blocks = test_observer::get_burn_blocks(); |
| 11182 | + let burn_block = burn_blocks.last().unwrap(); |
| 11183 | + info!("Burn block: {:?}", &burn_block); |
| 11184 | + |
| 11185 | + let reward_amount = burn_block |
| 11186 | + .get("reward_recipients") |
| 11187 | + .unwrap() |
| 11188 | + .as_array() |
| 11189 | + .unwrap() |
| 11190 | + .iter() |
| 11191 | + .map(|r| r.get("amt").unwrap().as_u64().unwrap()) |
| 11192 | + .sum::<u64>(); |
| 11193 | + |
| 11194 | + assert_eq!(reward_amount, 200000); |
| 11195 | + |
| 11196 | + next_block_and_mine_commit(&mut btc_regtest_controller, 60, &conf, &counters).unwrap(); |
| 11197 | + |
| 11198 | + info!("---- Updating config ----"); |
| 11199 | + let new_amount = 150000; |
| 11200 | + update_config(new_amount, 55); |
| 11201 | + |
| 11202 | + // Due to timing of commits, just mine two blocks |
| 11203 | + |
| 11204 | + next_block_and_mine_commit(&mut btc_regtest_controller, 60, &conf, &counters).unwrap(); |
| 11205 | + next_block_and_mine_commit(&mut btc_regtest_controller, 60, &conf, &counters).unwrap(); |
| 11206 | + |
| 11207 | + let burn_blocks = test_observer::get_burn_blocks(); |
| 11208 | + let burn_block = burn_blocks.last().unwrap(); |
| 11209 | + info!("Burn block: {:?}", &burn_block); |
| 11210 | + |
| 11211 | + let reward_amount = burn_block |
| 11212 | + .get("reward_recipients") |
| 11213 | + .unwrap() |
| 11214 | + .as_array() |
| 11215 | + .unwrap() |
| 11216 | + .iter() |
| 11217 | + .map(|r| r.get("amt").unwrap().as_u64().unwrap()) |
| 11218 | + .sum::<u64>(); |
| 11219 | + |
| 11220 | + assert_eq!(reward_amount, new_amount); |
| 11221 | + |
| 11222 | + coord_channel |
| 11223 | + .lock() |
| 11224 | + .expect("Mutex poisoned") |
| 11225 | + .stop_chains_coordinator(); |
| 11226 | + run_loop_stopper.store(false, Ordering::SeqCst); |
| 11227 | + |
| 11228 | + run_loop_thread.join().unwrap(); |
| 11229 | +} |
0 commit comments