|
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};
|
@@ -10764,7 +10765,7 @@ fn test_tenure_extend_from_flashblocks() {
|
10764 | 10765 | (define-data-var my-var uint u0)
|
10765 | 10766 | (define-data-var my-counter uint u0)
|
10766 | 10767 |
|
10767 |
| -(define-public (f) |
| 10768 | +(define-public (f) |
10768 | 10769 | (begin
|
10769 | 10770 | (var-set my-var burn-block-height)
|
10770 | 10771 | (if (is-eq u0 (mod burn-block-height u2))
|
@@ -11165,3 +11166,146 @@ fn mine_invalid_principal_from_consensus_buff() {
|
11165 | 11166 |
|
11166 | 11167 | run_loop_thread.join().unwrap();
|
11167 | 11168 | }
|
| 11169 | + |
| 11170 | +/// Test hot-reloading of miner config |
| 11171 | +#[test] |
| 11172 | +#[ignore] |
| 11173 | +fn reload_miner_config() { |
| 11174 | + if env::var("BITCOIND_TEST") != Ok("1".into()) { |
| 11175 | + return; |
| 11176 | + } |
| 11177 | + |
| 11178 | + let (mut conf, _miner_account) = naka_neon_integration_conf(None); |
| 11179 | + let password = "12345".to_string(); |
| 11180 | + let _http_origin = format!("http://{}", &conf.node.rpc_bind); |
| 11181 | + conf.connection_options.auth_token = Some(password.clone()); |
| 11182 | + conf.miner.wait_on_interim_blocks = Duration::from_secs(1); |
| 11183 | + let stacker_sk = setup_stacker(&mut conf); |
| 11184 | + let signer_sk = Secp256k1PrivateKey::random(); |
| 11185 | + let signer_addr = tests::to_addr(&signer_sk); |
| 11186 | + let sender_sk = Secp256k1PrivateKey::random(); |
| 11187 | + // setup sender + recipient for some test stx transfers |
| 11188 | + // these are necessary for the interim blocks to get mined at all |
| 11189 | + let sender_addr = tests::to_addr(&sender_sk); |
| 11190 | + conf.add_initial_balance(PrincipalData::from(sender_addr).to_string(), 1000000); |
| 11191 | + conf.add_initial_balance(PrincipalData::from(signer_addr).to_string(), 100000); |
| 11192 | + |
| 11193 | + test_observer::spawn(); |
| 11194 | + test_observer::register(&mut conf, &[EventKeyType::AnyEvent]); |
| 11195 | + |
| 11196 | + let mut btcd_controller = BitcoinCoreController::new(conf.clone()); |
| 11197 | + btcd_controller |
| 11198 | + .start_bitcoind() |
| 11199 | + .expect("Failed starting bitcoind"); |
| 11200 | + let mut btc_regtest_controller = BitcoinRegtestController::new(conf.clone(), None); |
| 11201 | + btc_regtest_controller.bootstrap_chain(201); |
| 11202 | + |
| 11203 | + let conf_path = |
| 11204 | + std::env::temp_dir().join(format!("miner-config-test-{}.toml", rand::random::<u64>())); |
| 11205 | + conf.config_path = Some(conf_path.clone().to_str().unwrap().to_string()); |
| 11206 | + |
| 11207 | + // Make a minimum-viable config file |
| 11208 | + let update_config = |burn_fee_cap: u64, sats_vbyte: u64| { |
| 11209 | + use std::io::Write; |
| 11210 | + |
| 11211 | + let new_config = format!( |
| 11212 | + r#" |
| 11213 | + [burnchain] |
| 11214 | + burn_fee_cap = {} |
| 11215 | + satoshis_per_byte = {} |
| 11216 | + "#, |
| 11217 | + burn_fee_cap, sats_vbyte, |
| 11218 | + ); |
| 11219 | + // Write to a file |
| 11220 | + let mut file = File::create(&conf_path).unwrap(); |
| 11221 | + file.write_all(new_config.as_bytes()).unwrap(); |
| 11222 | + }; |
| 11223 | + |
| 11224 | + update_config(100000, 50); |
| 11225 | + |
| 11226 | + let mut run_loop = boot_nakamoto::BootRunLoop::new(conf.clone()).unwrap(); |
| 11227 | + let run_loop_stopper = run_loop.get_termination_switch(); |
| 11228 | + let counters = run_loop.counters(); |
| 11229 | + let Counters { |
| 11230 | + blocks_processed, |
| 11231 | + naka_submitted_commits: commits_submitted, |
| 11232 | + naka_proposed_blocks: proposals_submitted, |
| 11233 | + .. |
| 11234 | + } = run_loop.counters(); |
| 11235 | + |
| 11236 | + let coord_channel = run_loop.coordinator_channels(); |
| 11237 | + |
| 11238 | + let run_loop_thread = thread::spawn(move || run_loop.start(None, 0)); |
| 11239 | + let mut signers = TestSigners::new(vec![signer_sk]); |
| 11240 | + wait_for_runloop(&blocks_processed); |
| 11241 | + boot_to_epoch_3( |
| 11242 | + &conf, |
| 11243 | + &blocks_processed, |
| 11244 | + &[stacker_sk], |
| 11245 | + &[signer_sk], |
| 11246 | + &mut Some(&mut signers), |
| 11247 | + &mut btc_regtest_controller, |
| 11248 | + ); |
| 11249 | + |
| 11250 | + info!("------------------------- Reached Epoch 3.0 -------------------------"); |
| 11251 | + |
| 11252 | + blind_signer(&conf, &signers, proposals_submitted); |
| 11253 | + |
| 11254 | + wait_for_first_naka_block_commit(60, &commits_submitted); |
| 11255 | + |
| 11256 | + next_block_and_mine_commit(&mut btc_regtest_controller, 60, &conf, &counters).unwrap(); |
| 11257 | + |
| 11258 | + let burn_blocks = test_observer::get_burn_blocks(); |
| 11259 | + let burn_block = burn_blocks.last().unwrap(); |
| 11260 | + info!("Burn block: {:?}", &burn_block); |
| 11261 | + |
| 11262 | + let reward_amount = burn_block |
| 11263 | + .get("reward_recipients") |
| 11264 | + .unwrap() |
| 11265 | + .as_array() |
| 11266 | + .unwrap() |
| 11267 | + .get(0) |
| 11268 | + .unwrap() |
| 11269 | + .get("amt") |
| 11270 | + .unwrap() |
| 11271 | + .as_u64() |
| 11272 | + .unwrap(); |
| 11273 | + |
| 11274 | + assert_eq!(reward_amount, 200000); |
| 11275 | + |
| 11276 | + next_block_and_mine_commit(&mut btc_regtest_controller, 60, &conf, &counters).unwrap(); |
| 11277 | + |
| 11278 | + info!("---- Updating config ----"); |
| 11279 | + update_config(100010, 55); |
| 11280 | + |
| 11281 | + // Due to timing of commits, just mine two blocks |
| 11282 | + |
| 11283 | + next_block_and_mine_commit(&mut btc_regtest_controller, 60, &conf, &counters).unwrap(); |
| 11284 | + next_block_and_mine_commit(&mut btc_regtest_controller, 60, &conf, &counters).unwrap(); |
| 11285 | + |
| 11286 | + let burn_blocks = test_observer::get_burn_blocks(); |
| 11287 | + let burn_block = burn_blocks.last().unwrap(); |
| 11288 | + info!("Burn block: {:?}", &burn_block); |
| 11289 | + |
| 11290 | + let reward_amount = burn_block |
| 11291 | + .get("reward_recipients") |
| 11292 | + .unwrap() |
| 11293 | + .as_array() |
| 11294 | + .unwrap() |
| 11295 | + .get(0) |
| 11296 | + .unwrap() |
| 11297 | + .get("amt") |
| 11298 | + .unwrap() |
| 11299 | + .as_u64() |
| 11300 | + .unwrap(); |
| 11301 | + |
| 11302 | + assert_eq!(reward_amount, 100010); |
| 11303 | + |
| 11304 | + coord_channel |
| 11305 | + .lock() |
| 11306 | + .expect("Mutex poisoned") |
| 11307 | + .stop_chains_coordinator(); |
| 11308 | + run_loop_stopper.store(false, Ordering::SeqCst); |
| 11309 | + |
| 11310 | + run_loop_thread.join().unwrap(); |
| 11311 | +} |
0 commit comments