mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-05-29 23:43:02 +08:00
chore: remove self_signing mode
* remove self_signing mode from nakamoto-node * update integration tests that used self_signing to have a blind signing thread which reads/writes through stackerdb
This commit is contained in:
committed by
Brice Dobry
parent
90e36dfab4
commit
83ac3276dc
@@ -12,7 +12,6 @@ use rand::RngCore;
|
||||
use stacks::burnchains::bitcoin::BitcoinNetworkType;
|
||||
use stacks::burnchains::{Burnchain, MagicBytes, BLOCKSTACK_MAGIC_MAINNET};
|
||||
use stacks::chainstate::nakamoto::signer_set::NakamotoSigners;
|
||||
use stacks::chainstate::nakamoto::test_signers::TestSigners;
|
||||
use stacks::chainstate::stacks::boot::MINERS_NAME;
|
||||
use stacks::chainstate::stacks::index::marf::MARFOpenOpts;
|
||||
use stacks::chainstate::stacks::index::storage::TrieHashCalculationMode;
|
||||
@@ -505,19 +504,6 @@ lazy_static! {
|
||||
}
|
||||
|
||||
impl Config {
|
||||
#[cfg(any(test, feature = "testing"))]
|
||||
pub fn self_signing(&self) -> Option<TestSigners> {
|
||||
if !(self.burnchain.mode == "nakamoto-neon" || self.burnchain.mode == "mockamoto") {
|
||||
return None;
|
||||
}
|
||||
self.miner.self_signing_key.clone()
|
||||
}
|
||||
|
||||
#[cfg(not(any(test, feature = "testing")))]
|
||||
pub fn self_signing(&self) -> Option<TestSigners> {
|
||||
return None;
|
||||
}
|
||||
|
||||
/// get the up-to-date burnchain options from the config.
|
||||
/// If the config file can't be loaded, then return the existing config
|
||||
pub fn get_burnchain_config(&self) -> BurnchainConfig {
|
||||
@@ -1998,7 +1984,6 @@ pub struct MinerConfig {
|
||||
pub candidate_retry_cache_size: u64,
|
||||
pub unprocessed_block_deadline_secs: u64,
|
||||
pub mining_key: Option<Secp256k1PrivateKey>,
|
||||
pub self_signing_key: Option<TestSigners>,
|
||||
/// Amount of time while mining in nakamoto to wait in between mining interim blocks
|
||||
pub wait_on_interim_blocks: Duration,
|
||||
/// minimum number of transactions that must be in a block if we're going to replace a pending
|
||||
@@ -2046,7 +2031,6 @@ impl Default for MinerConfig {
|
||||
candidate_retry_cache_size: 1024 * 1024,
|
||||
unprocessed_block_deadline_secs: 30,
|
||||
mining_key: None,
|
||||
self_signing_key: None,
|
||||
wait_on_interim_blocks: Duration::from_millis(2_500),
|
||||
min_tx_count: 0,
|
||||
only_increase_tx_count: false,
|
||||
@@ -2430,7 +2414,6 @@ impl MinerConfigFile {
|
||||
.as_ref()
|
||||
.map(|x| Secp256k1PrivateKey::from_hex(x))
|
||||
.transpose()?,
|
||||
self_signing_key: Some(TestSigners::default()),
|
||||
wait_on_interim_blocks: self
|
||||
.wait_on_interim_blocks_ms
|
||||
.map(Duration::from_millis)
|
||||
|
||||
@@ -31,7 +31,6 @@ use stacks::chainstate::burn::db::sortdb::SortitionDB;
|
||||
use stacks::chainstate::burn::{BlockSnapshot, ConsensusHash};
|
||||
use stacks::chainstate::nakamoto::miner::{NakamotoBlockBuilder, NakamotoTenureInfo};
|
||||
use stacks::chainstate::nakamoto::signer_set::NakamotoSigners;
|
||||
use stacks::chainstate::nakamoto::test_signers::TestSigners;
|
||||
use stacks::chainstate::nakamoto::{NakamotoBlock, NakamotoBlockVote, NakamotoChainState};
|
||||
use stacks::chainstate::stacks::boot::MINERS_NAME;
|
||||
use stacks::chainstate::stacks::db::{StacksChainState, StacksHeaderInfo};
|
||||
@@ -223,21 +222,14 @@ impl BlockMinerThread {
|
||||
warn!("Failed to propose block to stackerdb: {e:?}");
|
||||
}
|
||||
}
|
||||
self.globals.counters.bump_naka_proposed_blocks();
|
||||
|
||||
if let Some(self_signer) = self.config.self_signing() {
|
||||
if let Err(e) = self.self_sign_and_broadcast(self_signer, new_block.clone()) {
|
||||
warn!("Error self-signing block: {e:?}");
|
||||
} else {
|
||||
self.globals.coord().announce_new_stacks_block();
|
||||
}
|
||||
if let Err(e) =
|
||||
self.wait_for_signer_signature_and_broadcast(&stackerdbs, new_block.clone())
|
||||
{
|
||||
warn!("Error broadcasting block: {e:?}");
|
||||
} else {
|
||||
if let Err(e) =
|
||||
self.wait_for_signer_signature_and_broadcast(&stackerdbs, new_block.clone())
|
||||
{
|
||||
warn!("Error broadcasting block: {e:?}");
|
||||
} else {
|
||||
self.globals.coord().announce_new_stacks_block();
|
||||
}
|
||||
self.globals.coord().announce_new_stacks_block();
|
||||
}
|
||||
|
||||
self.globals.counters.bump_naka_mined_blocks();
|
||||
@@ -548,54 +540,6 @@ impl BlockMinerThread {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn self_sign_and_broadcast(
|
||||
&self,
|
||||
mut signer: TestSigners,
|
||||
mut block: NakamotoBlock,
|
||||
) -> Result<(), ChainstateError> {
|
||||
let mut chain_state = neon_node::open_chainstate_with_faults(&self.config)
|
||||
.expect("FATAL: could not open chainstate DB");
|
||||
let chainstate_config = chain_state.config();
|
||||
let sort_db = SortitionDB::open(
|
||||
&self.config.get_burn_db_file_path(),
|
||||
true,
|
||||
self.burnchain.pox_constants.clone(),
|
||||
)
|
||||
.expect("FATAL: could not open sortition DB");
|
||||
|
||||
let burn_height = self.burn_block.block_height;
|
||||
let cycle = self
|
||||
.burnchain
|
||||
.block_height_to_reward_cycle(burn_height)
|
||||
.expect("FATAL: no reward cycle for burn block");
|
||||
signer.sign_nakamoto_block(&mut block, cycle);
|
||||
|
||||
let mut sortition_handle = sort_db.index_handle_at_tip();
|
||||
let aggregate_public_key = if block.header.chain_length <= 1 {
|
||||
signer.aggregate_public_key.clone()
|
||||
} else {
|
||||
let aggregate_public_key = NakamotoChainState::get_aggregate_public_key(
|
||||
&mut chain_state,
|
||||
&sort_db,
|
||||
&sortition_handle,
|
||||
&block,
|
||||
)?;
|
||||
aggregate_public_key
|
||||
};
|
||||
|
||||
let (headers_conn, staging_tx) = chain_state.headers_conn_and_staging_tx_begin()?;
|
||||
NakamotoChainState::accept_block(
|
||||
&chainstate_config,
|
||||
block,
|
||||
&mut sortition_handle,
|
||||
&staging_tx,
|
||||
headers_conn,
|
||||
&aggregate_public_key,
|
||||
)?;
|
||||
staging_tx.commit()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get the coinbase recipient address, if set in the config and if allowed in this epoch
|
||||
fn get_coinbase_recipient(&self, epoch_id: StacksEpochId) -> Option<PrincipalData> {
|
||||
if epoch_id < StacksEpochId::Epoch21 && self.config.miner.block_reward_recipient.is_some() {
|
||||
|
||||
@@ -17,8 +17,7 @@ use stacks::chainstate::coordinator::{
|
||||
static_get_heaviest_affirmation_map, static_get_stacks_tip_affirmation_map, ChainsCoordinator,
|
||||
ChainsCoordinatorConfig, CoordinatorCommunication, Error as coord_error,
|
||||
};
|
||||
use stacks::chainstate::nakamoto::NakamotoChainState;
|
||||
use stacks::chainstate::stacks::db::{ChainStateBootData, ClarityTx, StacksChainState};
|
||||
use stacks::chainstate::stacks::db::{ChainStateBootData, StacksChainState};
|
||||
use stacks::chainstate::stacks::miner::{signal_mining_blocked, signal_mining_ready, MinerStatus};
|
||||
use stacks::core::StacksEpochId;
|
||||
use stacks::net::atlas::{AtlasConfig, AtlasDB, Attachment};
|
||||
@@ -26,7 +25,7 @@ use stacks::util_lib::db::Error as db_error;
|
||||
use stacks_common::deps_common::ctrlc as termination;
|
||||
use stacks_common::deps_common::ctrlc::SignalId;
|
||||
use stacks_common::types::PublicKey;
|
||||
use stacks_common::util::hash::{to_hex, Hash160};
|
||||
use stacks_common::util::hash::Hash160;
|
||||
use stacks_common::util::{get_epoch_time_secs, sleep_ms};
|
||||
use stx_genesis::GenesisData;
|
||||
|
||||
@@ -47,10 +46,12 @@ use crate::{
|
||||
pub const STDERR: i32 = 2;
|
||||
|
||||
#[cfg(test)]
|
||||
pub type RunLoopCounter = Arc<AtomicU64>;
|
||||
#[derive(Clone)]
|
||||
pub struct RunLoopCounter(pub Arc<AtomicU64>);
|
||||
|
||||
#[cfg(not(test))]
|
||||
pub type RunLoopCounter = ();
|
||||
#[derive(Clone)]
|
||||
pub struct RunLoopCounter();
|
||||
|
||||
#[cfg(test)]
|
||||
const UNCONDITIONAL_CHAIN_LIVENESS_CHECK: u64 = 30;
|
||||
@@ -58,7 +59,27 @@ const UNCONDITIONAL_CHAIN_LIVENESS_CHECK: u64 = 30;
|
||||
#[cfg(not(test))]
|
||||
const UNCONDITIONAL_CHAIN_LIVENESS_CHECK: u64 = 300;
|
||||
|
||||
#[derive(Clone)]
|
||||
impl Default for RunLoopCounter {
|
||||
#[cfg(test)]
|
||||
fn default() -> Self {
|
||||
RunLoopCounter(Arc::new(AtomicU64::new(0)))
|
||||
}
|
||||
#[cfg(not(test))]
|
||||
fn default() -> Self {
|
||||
Self()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl std::ops::Deref for RunLoopCounter {
|
||||
type Target = Arc<AtomicU64>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct Counters {
|
||||
pub blocks_processed: RunLoopCounter,
|
||||
pub microblocks_processed: RunLoopCounter,
|
||||
@@ -69,43 +90,18 @@ pub struct Counters {
|
||||
pub naka_submitted_vrfs: RunLoopCounter,
|
||||
pub naka_submitted_commits: RunLoopCounter,
|
||||
pub naka_mined_blocks: RunLoopCounter,
|
||||
pub naka_proposed_blocks: RunLoopCounter,
|
||||
pub naka_mined_tenures: RunLoopCounter,
|
||||
}
|
||||
|
||||
impl Counters {
|
||||
#[cfg(test)]
|
||||
pub fn new() -> Counters {
|
||||
Counters {
|
||||
blocks_processed: RunLoopCounter::new(AtomicU64::new(0)),
|
||||
microblocks_processed: RunLoopCounter::new(AtomicU64::new(0)),
|
||||
missed_tenures: RunLoopCounter::new(AtomicU64::new(0)),
|
||||
missed_microblock_tenures: RunLoopCounter::new(AtomicU64::new(0)),
|
||||
cancelled_commits: RunLoopCounter::new(AtomicU64::new(0)),
|
||||
naka_submitted_vrfs: RunLoopCounter::new(AtomicU64::new(0)),
|
||||
naka_submitted_commits: RunLoopCounter::new(AtomicU64::new(0)),
|
||||
naka_mined_blocks: RunLoopCounter::new(AtomicU64::new(0)),
|
||||
naka_mined_tenures: RunLoopCounter::new(AtomicU64::new(0)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
pub fn new() -> Counters {
|
||||
Counters {
|
||||
blocks_processed: (),
|
||||
microblocks_processed: (),
|
||||
missed_tenures: (),
|
||||
missed_microblock_tenures: (),
|
||||
cancelled_commits: (),
|
||||
naka_submitted_vrfs: (),
|
||||
naka_submitted_commits: (),
|
||||
naka_mined_blocks: (),
|
||||
naka_mined_tenures: (),
|
||||
}
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn inc(ctr: &RunLoopCounter) {
|
||||
ctr.fetch_add(1, Ordering::SeqCst);
|
||||
ctr.0.fetch_add(1, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
@@ -113,7 +109,7 @@ impl Counters {
|
||||
|
||||
#[cfg(test)]
|
||||
fn set(ctr: &RunLoopCounter, value: u64) {
|
||||
ctr.store(value, Ordering::SeqCst);
|
||||
ctr.0.store(value, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
@@ -151,6 +147,10 @@ impl Counters {
|
||||
Counters::inc(&self.naka_mined_blocks);
|
||||
}
|
||||
|
||||
pub fn bump_naka_proposed_blocks(&self) {
|
||||
Counters::inc(&self.naka_proposed_blocks);
|
||||
}
|
||||
|
||||
pub fn bump_naka_mined_tenures(&self) {
|
||||
Counters::inc(&self.naka_mined_tenures);
|
||||
}
|
||||
@@ -217,7 +217,7 @@ impl RunLoop {
|
||||
globals: None,
|
||||
coordinator_channels: Some(channels),
|
||||
callbacks: RunLoopCallbacks::new(),
|
||||
counters: Counters::new(),
|
||||
counters: Counters::default(),
|
||||
should_keep_running,
|
||||
event_dispatcher,
|
||||
pox_watchdog: None,
|
||||
@@ -481,23 +481,10 @@ impl RunLoop {
|
||||
.map(|e| (e.address.clone(), e.amount))
|
||||
.collect();
|
||||
|
||||
// TODO: delete this once aggregate public key voting is working
|
||||
let agg_pubkey_boot_callback = if let Some(self_signer) = self.config.self_signing() {
|
||||
let agg_pub_key = self_signer.aggregate_public_key.clone();
|
||||
info!("Neon node setting agg public key"; "agg_pub_key" => %to_hex(&agg_pub_key.compress().data));
|
||||
let callback = Box::new(move |clarity_tx: &mut ClarityTx| {
|
||||
NakamotoChainState::aggregate_public_key_bootcode(clarity_tx, &agg_pub_key)
|
||||
}) as Box<dyn FnOnce(&mut ClarityTx)>;
|
||||
Some(callback)
|
||||
} else {
|
||||
debug!("Neon node booting with no aggregate public key. Must have signers available to sign blocks.");
|
||||
None
|
||||
};
|
||||
|
||||
// instantiate chainstate
|
||||
let mut boot_data = ChainStateBootData {
|
||||
initial_balances,
|
||||
post_flight_callback: agg_pubkey_boot_callback,
|
||||
post_flight_callback: None,
|
||||
first_burnchain_block_hash: burnchain_config.first_block_hash,
|
||||
first_burnchain_block_height: burnchain_config.first_block_height as u32,
|
||||
first_burnchain_block_timestamp: burnchain_config.first_block_timestamp,
|
||||
|
||||
@@ -13,20 +13,23 @@
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread::JoinHandle;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::{env, thread};
|
||||
|
||||
use clarity::vm::ast::ASTRules;
|
||||
use clarity::vm::costs::ExecutionCost;
|
||||
use clarity::vm::types::PrincipalData;
|
||||
use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier};
|
||||
use lazy_static::lazy_static;
|
||||
use libsigner::{SignerSession, StackerDBSession};
|
||||
use libsigner::{BlockResponse, SignerMessage, SignerSession, StackerDBSession};
|
||||
use stacks::burnchains::MagicBytes;
|
||||
use stacks::chainstate::burn::db::sortdb::SortitionDB;
|
||||
use stacks::chainstate::coordinator::comm::CoordinatorChannels;
|
||||
use stacks::chainstate::nakamoto::miner::NakamotoBlockBuilder;
|
||||
use stacks::chainstate::nakamoto::signer_set::NakamotoSigners;
|
||||
use stacks::chainstate::nakamoto::test_signers::TestSigners;
|
||||
use stacks::chainstate::nakamoto::{NakamotoBlock, NakamotoChainState};
|
||||
use stacks::chainstate::stacks::address::PoxAddress;
|
||||
@@ -40,6 +43,7 @@ use stacks::core::{
|
||||
PEER_VERSION_EPOCH_2_1, PEER_VERSION_EPOCH_2_2, PEER_VERSION_EPOCH_2_3, PEER_VERSION_EPOCH_2_4,
|
||||
PEER_VERSION_EPOCH_2_5, PEER_VERSION_EPOCH_3_0,
|
||||
};
|
||||
use stacks::libstackerdb::{SlotMetadata, StackerDBChunkData};
|
||||
use stacks::net::api::callreadonly::CallReadOnlyRequestBody;
|
||||
use stacks::net::api::getstackers::GetStackersResponse;
|
||||
use stacks::net::api::postblock_proposal::{
|
||||
@@ -55,8 +59,8 @@ use stacks_common::consts::{CHAIN_ID_TESTNET, STACKS_EPOCH_MAX};
|
||||
use stacks_common::types::chainstate::{
|
||||
BlockHeaderHash, StacksAddress, StacksPrivateKey, StacksPublicKey,
|
||||
};
|
||||
use stacks_common::util::hash::to_hex;
|
||||
use stacks_common::util::secp256k1::{MessageSignature, Secp256k1PrivateKey};
|
||||
use stacks_common::util::hash::{to_hex, Sha512Trunc256Sum};
|
||||
use stacks_common::util::secp256k1::{MessageSignature, Secp256k1PrivateKey, Secp256k1PublicKey};
|
||||
|
||||
use super::bitcoin_regtest::BitcoinCoreController;
|
||||
use crate::config::{EventKeyType, EventObserverConfig, InitialBalance};
|
||||
@@ -154,6 +158,32 @@ pub fn get_stacker_set(http_origin: &str, cycle: u64) -> GetStackersResponse {
|
||||
res
|
||||
}
|
||||
|
||||
pub fn get_stackerdb_slot_version(
|
||||
http_origin: &str,
|
||||
contract: &QualifiedContractIdentifier,
|
||||
slot_id: u64,
|
||||
) -> Option<u32> {
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let path = format!(
|
||||
"{http_origin}/v2/stackerdb/{}/{}",
|
||||
&contract.issuer, &contract.name
|
||||
);
|
||||
let res = client
|
||||
.get(&path)
|
||||
.send()
|
||||
.unwrap()
|
||||
.json::<Vec<SlotMetadata>>()
|
||||
.unwrap();
|
||||
debug!("StackerDB metadata response: {res:?}");
|
||||
res.iter().find_map(|slot| {
|
||||
if u64::from(slot.slot_id) == slot_id {
|
||||
Some(slot.slot_version)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn add_initial_balances(
|
||||
conf: &mut Config,
|
||||
accounts: usize,
|
||||
@@ -171,6 +201,120 @@ pub fn add_initial_balances(
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Spawn a blind signing thread. `signer` is the private key
|
||||
/// of the individual signer who broadcasts the response to the StackerDB
|
||||
pub fn blind_signer(
|
||||
conf: &Config,
|
||||
signers: &TestSigners,
|
||||
signer: &Secp256k1PrivateKey,
|
||||
proposals_count: RunLoopCounter,
|
||||
) -> JoinHandle<()> {
|
||||
let mut signed_blocks = HashSet::new();
|
||||
let conf = conf.clone();
|
||||
let signers = signers.clone();
|
||||
let signer = signer.clone();
|
||||
let mut last_count = proposals_count.load(Ordering::SeqCst);
|
||||
thread::spawn(move || loop {
|
||||
thread::sleep(Duration::from_millis(100));
|
||||
let cur_count = proposals_count.load(Ordering::SeqCst);
|
||||
if cur_count <= last_count {
|
||||
continue;
|
||||
}
|
||||
last_count = cur_count;
|
||||
match read_and_sign_block_proposal(&conf, &signers, &signer, &signed_blocks) {
|
||||
Ok(signed_block) => {
|
||||
if signed_blocks.contains(&signed_block) {
|
||||
continue;
|
||||
}
|
||||
info!("Signed block"; "signer_sig_hash" => signed_block.to_hex());
|
||||
signed_blocks.insert(signed_block);
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Error reading and signing block proposal: {e}");
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn read_and_sign_block_proposal(
|
||||
conf: &Config,
|
||||
signers: &TestSigners,
|
||||
signer: &Secp256k1PrivateKey,
|
||||
signed_blocks: &HashSet<Sha512Trunc256Sum>,
|
||||
) -> Result<Sha512Trunc256Sum, String> {
|
||||
let burnchain = conf.get_burnchain();
|
||||
let sortdb = burnchain.open_sortition_db(true).unwrap();
|
||||
let tip = SortitionDB::get_canonical_burn_chain_tip(sortdb.conn()).unwrap();
|
||||
let miner_pubkey = StacksPublicKey::from_private(&conf.get_miner_config().mining_key.unwrap());
|
||||
let miner_slot_id = NakamotoChainState::get_miner_slot(&sortdb, &tip, &miner_pubkey)
|
||||
.map_err(|_| "Unable to get miner slot")?
|
||||
.ok_or("No miner slot exists")?;
|
||||
let reward_cycle = burnchain
|
||||
.block_height_to_reward_cycle(tip.block_height)
|
||||
.unwrap();
|
||||
let rpc_sock = conf
|
||||
.node
|
||||
.rpc_bind
|
||||
.clone()
|
||||
.parse()
|
||||
.expect("Failed to parse socket");
|
||||
|
||||
let mut proposed_block: NakamotoBlock = {
|
||||
let miner_contract_id = boot_code_id(MINERS_NAME, false);
|
||||
let mut miners_stackerdb = StackerDBSession::new(rpc_sock, miner_contract_id);
|
||||
miners_stackerdb
|
||||
.get_latest(miner_slot_id)
|
||||
.map_err(|_| "Failed to get latest chunk from the miner slot ID")?
|
||||
.ok_or("No chunk found")?
|
||||
};
|
||||
let proposed_block_hash = format!("0x{}", proposed_block.header.block_hash());
|
||||
let signer_sig_hash = proposed_block.header.signer_signature_hash();
|
||||
if signed_blocks.contains(&signer_sig_hash) {
|
||||
// already signed off on this block, don't sign again.
|
||||
return Ok(signer_sig_hash);
|
||||
}
|
||||
|
||||
info!(
|
||||
"Fetched proposed block from .miners StackerDB";
|
||||
"proposed_block_hash" => &proposed_block_hash,
|
||||
"signer_sig_hash" => &signer_sig_hash.to_hex(),
|
||||
);
|
||||
|
||||
signers
|
||||
.clone()
|
||||
.sign_nakamoto_block(&mut proposed_block, reward_cycle);
|
||||
|
||||
let signer_message = SignerMessage::BlockResponse(BlockResponse::Accepted((
|
||||
signer_sig_hash.clone(),
|
||||
proposed_block.header.signer_signature.clone(),
|
||||
)));
|
||||
|
||||
let signers_contract_id =
|
||||
NakamotoSigners::make_signers_db_contract_id(reward_cycle, libsigner::BLOCK_MSG_ID, false);
|
||||
|
||||
let http_origin = format!("http://{}", &conf.node.rpc_bind);
|
||||
let signers_info = get_stacker_set(&http_origin, reward_cycle);
|
||||
let signer_index = get_signer_index(&signers_info, &Secp256k1PublicKey::from_private(signer))
|
||||
.unwrap()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
|
||||
let next_version = get_stackerdb_slot_version(&http_origin, &signers_contract_id, signer_index)
|
||||
.map(|x| x + 1)
|
||||
.unwrap_or(0);
|
||||
let mut signers_contract_sess = StackerDBSession::new(rpc_sock, signers_contract_id);
|
||||
let mut chunk_to_put = StackerDBChunkData::new(
|
||||
u32::try_from(signer_index).unwrap(),
|
||||
next_version,
|
||||
signer_message.serialize_to_vec(),
|
||||
);
|
||||
chunk_to_put.sign(signer).unwrap();
|
||||
signers_contract_sess
|
||||
.put_chunk(&chunk_to_put)
|
||||
.map_err(|e| e.to_string())?;
|
||||
Ok(signer_sig_hash)
|
||||
}
|
||||
|
||||
/// Return a working nakamoto-neon config and the miner's bitcoin address to fund
|
||||
pub fn naka_neon_integration_conf(seed: Option<&[u8]>) -> (Config, StacksAddress) {
|
||||
let mut conf = super::new_test_conf();
|
||||
@@ -189,7 +333,6 @@ pub fn naka_neon_integration_conf(seed: Option<&[u8]>) -> (Config, StacksAddress
|
||||
|
||||
let mining_key = Secp256k1PrivateKey::from_seed(&[1]);
|
||||
conf.miner.mining_key = Some(mining_key);
|
||||
conf.miner.self_signing_key = Some(TestSigners::default());
|
||||
|
||||
conf.node.miner = true;
|
||||
conf.node.wait_time_for_microblocks = 500;
|
||||
@@ -355,9 +498,10 @@ pub fn setup_stacker(naka_conf: &mut Config) -> Secp256k1PrivateKey {
|
||||
/// for pox-4 to activate
|
||||
pub fn boot_to_epoch_3(
|
||||
naka_conf: &Config,
|
||||
blocks_processed: &RunLoopCounter,
|
||||
blocks_processed: &Arc<AtomicU64>,
|
||||
stacker_sks: &[StacksPrivateKey],
|
||||
signer_sks: &[StacksPrivateKey],
|
||||
self_signing: Option<&TestSigners>,
|
||||
btc_regtest_controller: &mut BitcoinRegtestController,
|
||||
) {
|
||||
assert_eq!(stacker_sks.len(), signer_sks.len());
|
||||
@@ -439,25 +583,29 @@ pub fn boot_to_epoch_3(
|
||||
&naka_conf,
|
||||
);
|
||||
|
||||
// If we are self-signing, then we need to vote on the aggregate public key
|
||||
if let Some(mut signers) = naka_conf.self_signing() {
|
||||
// We need to vote on the aggregate public key if this test is self signing
|
||||
if let Some(signers) = self_signing {
|
||||
// Get the aggregate key
|
||||
let aggregate_key = signers.generate_aggregate_key(reward_cycle + 1);
|
||||
let aggregate_key = signers.clone().generate_aggregate_key(reward_cycle + 1);
|
||||
let aggregate_public_key =
|
||||
clarity::vm::Value::buff_from(aggregate_key.compress().data.to_vec())
|
||||
.expect("Failed to serialize aggregate public key");
|
||||
|
||||
let signer_sks_unique: HashMap<_, _> = signer_sks.iter().map(|x| (x.to_hex(), x)).collect();
|
||||
let signer_set = get_stacker_set(&http_origin, reward_cycle + 1);
|
||||
// Vote on the aggregate public key
|
||||
for (i, signer_sk) in signer_sks.iter().enumerate() {
|
||||
for signer_sk in signer_sks_unique.values() {
|
||||
let signer_index =
|
||||
get_signer_index(&signer_set, &Secp256k1PublicKey::from_private(signer_sk))
|
||||
.unwrap();
|
||||
let voting_tx = tests::make_contract_call(
|
||||
&signer_sk,
|
||||
signer_sk,
|
||||
0,
|
||||
300,
|
||||
&StacksAddress::burn_address(false),
|
||||
SIGNERS_VOTING_NAME,
|
||||
"vote-for-aggregate-public-key",
|
||||
&[
|
||||
clarity::vm::Value::UInt(i as u128),
|
||||
clarity::vm::Value::UInt(u128::try_from(signer_index).unwrap()),
|
||||
aggregate_public_key.clone(),
|
||||
clarity::vm::Value::UInt(0),
|
||||
clarity::vm::Value::UInt(reward_cycle as u128 + 1),
|
||||
@@ -477,6 +625,32 @@ pub fn boot_to_epoch_3(
|
||||
info!("Bootstrapped to Epoch-3.0 boundary, Epoch2x miner should stop");
|
||||
}
|
||||
|
||||
fn get_signer_index(
|
||||
stacker_set: &GetStackersResponse,
|
||||
signer_key: &Secp256k1PublicKey,
|
||||
) -> Result<usize, String> {
|
||||
let Some(ref signer_set) = stacker_set.stacker_set.signers else {
|
||||
return Err("Empty signer set for reward cycle".into());
|
||||
};
|
||||
let signer_key_bytes = signer_key.to_bytes_compressed();
|
||||
signer_set
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(ix, entry)| {
|
||||
if entry.signing_key.as_slice() == signer_key_bytes.as_slice() {
|
||||
Some(ix)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
format!(
|
||||
"Signing key not found. {} not found.",
|
||||
to_hex(&signer_key_bytes)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn is_key_set_for_cycle(
|
||||
reward_cycle: u64,
|
||||
is_mainnet: bool,
|
||||
@@ -517,63 +691,62 @@ fn signer_vote_if_needed(
|
||||
btc_regtest_controller: &BitcoinRegtestController,
|
||||
naka_conf: &Config,
|
||||
signer_sks: &[StacksPrivateKey], // TODO: Is there some way to get this from the TestSigners?
|
||||
signers: &TestSigners,
|
||||
) {
|
||||
if let Some(mut signers) = naka_conf.self_signing() {
|
||||
// When we reach the next prepare phase, submit new voting transactions
|
||||
let block_height = btc_regtest_controller.get_headers_height();
|
||||
let reward_cycle = btc_regtest_controller
|
||||
.get_burnchain()
|
||||
.block_height_to_reward_cycle(block_height)
|
||||
.unwrap();
|
||||
let prepare_phase_start = btc_regtest_controller
|
||||
.get_burnchain()
|
||||
.pox_constants
|
||||
.prepare_phase_start(
|
||||
btc_regtest_controller.get_burnchain().first_block_height,
|
||||
reward_cycle,
|
||||
// When we reach the next prepare phase, submit new voting transactions
|
||||
let block_height = btc_regtest_controller.get_headers_height();
|
||||
let reward_cycle = btc_regtest_controller
|
||||
.get_burnchain()
|
||||
.block_height_to_reward_cycle(block_height)
|
||||
.unwrap();
|
||||
let prepare_phase_start = btc_regtest_controller
|
||||
.get_burnchain()
|
||||
.pox_constants
|
||||
.prepare_phase_start(
|
||||
btc_regtest_controller.get_burnchain().first_block_height,
|
||||
reward_cycle,
|
||||
);
|
||||
|
||||
if block_height >= prepare_phase_start {
|
||||
// If the key is already set, do nothing.
|
||||
if is_key_set_for_cycle(
|
||||
reward_cycle + 1,
|
||||
naka_conf.is_mainnet(),
|
||||
&naka_conf.node.rpc_bind,
|
||||
)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are self-signing, then we need to vote on the aggregate public key
|
||||
let http_origin = format!("http://{}", &naka_conf.node.rpc_bind);
|
||||
|
||||
// Get the aggregate key
|
||||
let aggregate_key = signers.clone().generate_aggregate_key(reward_cycle + 1);
|
||||
let aggregate_public_key =
|
||||
clarity::vm::Value::buff_from(aggregate_key.compress().data.to_vec())
|
||||
.expect("Failed to serialize aggregate public key");
|
||||
|
||||
for (i, signer_sk) in signer_sks.iter().enumerate() {
|
||||
let signer_nonce = get_account(&http_origin, &to_addr(signer_sk)).nonce;
|
||||
|
||||
// Vote on the aggregate public key
|
||||
let voting_tx = tests::make_contract_call(
|
||||
&signer_sk,
|
||||
signer_nonce,
|
||||
300,
|
||||
&StacksAddress::burn_address(false),
|
||||
SIGNERS_VOTING_NAME,
|
||||
"vote-for-aggregate-public-key",
|
||||
&[
|
||||
clarity::vm::Value::UInt(i as u128),
|
||||
aggregate_public_key.clone(),
|
||||
clarity::vm::Value::UInt(0),
|
||||
clarity::vm::Value::UInt(reward_cycle as u128 + 1),
|
||||
],
|
||||
);
|
||||
|
||||
if block_height >= prepare_phase_start {
|
||||
// If the key is already set, do nothing.
|
||||
if is_key_set_for_cycle(
|
||||
reward_cycle + 1,
|
||||
naka_conf.is_mainnet(),
|
||||
&naka_conf.node.rpc_bind,
|
||||
)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are self-signing, then we need to vote on the aggregate public key
|
||||
let http_origin = format!("http://{}", &naka_conf.node.rpc_bind);
|
||||
|
||||
// Get the aggregate key
|
||||
let aggregate_key = signers.generate_aggregate_key(reward_cycle + 1);
|
||||
let aggregate_public_key =
|
||||
clarity::vm::Value::buff_from(aggregate_key.compress().data.to_vec())
|
||||
.expect("Failed to serialize aggregate public key");
|
||||
|
||||
for (i, signer_sk) in signer_sks.iter().enumerate() {
|
||||
let signer_nonce = get_account(&http_origin, &to_addr(signer_sk)).nonce;
|
||||
|
||||
// Vote on the aggregate public key
|
||||
let voting_tx = tests::make_contract_call(
|
||||
&signer_sk,
|
||||
signer_nonce,
|
||||
300,
|
||||
&StacksAddress::burn_address(false),
|
||||
SIGNERS_VOTING_NAME,
|
||||
"vote-for-aggregate-public-key",
|
||||
&[
|
||||
clarity::vm::Value::UInt(i as u128),
|
||||
aggregate_public_key.clone(),
|
||||
clarity::vm::Value::UInt(0),
|
||||
clarity::vm::Value::UInt(reward_cycle as u128 + 1),
|
||||
],
|
||||
);
|
||||
submit_tx(&http_origin, &voting_tx);
|
||||
}
|
||||
submit_tx(&http_origin, &voting_tx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -584,7 +757,7 @@ fn signer_vote_if_needed(
|
||||
/// * `signer_pks` - must be the same size as `stacker_sks`
|
||||
pub fn boot_to_epoch_3_reward_set(
|
||||
naka_conf: &Config,
|
||||
blocks_processed: &RunLoopCounter,
|
||||
blocks_processed: &Arc<AtomicU64>,
|
||||
stacker_sks: &[StacksPrivateKey],
|
||||
signer_sks: &[StacksPrivateKey],
|
||||
btc_regtest_controller: &mut BitcoinRegtestController,
|
||||
@@ -692,6 +865,7 @@ fn simple_neon_integration() {
|
||||
return;
|
||||
}
|
||||
|
||||
let signers = TestSigners::default();
|
||||
let (mut naka_conf, _miner_account) = naka_neon_integration_conf(None);
|
||||
let prom_bind = format!("{}:{}", "127.0.0.1", 6000);
|
||||
naka_conf.node.prometheus_bind = Some(prom_bind.clone());
|
||||
@@ -734,6 +908,7 @@ fn simple_neon_integration() {
|
||||
blocks_processed,
|
||||
naka_submitted_vrfs: vrfs_submitted,
|
||||
naka_submitted_commits: commits_submitted,
|
||||
naka_proposed_blocks: proposals_submitted,
|
||||
..
|
||||
} = run_loop.counters();
|
||||
|
||||
@@ -746,6 +921,7 @@ fn simple_neon_integration() {
|
||||
&blocks_processed,
|
||||
&[stacker_sk],
|
||||
&[sender_signer_sk],
|
||||
Some(&signers),
|
||||
&mut btc_regtest_controller,
|
||||
);
|
||||
|
||||
@@ -783,6 +959,8 @@ fn simple_neon_integration() {
|
||||
}
|
||||
|
||||
info!("Nakamoto miner started...");
|
||||
blind_signer(&naka_conf, &signers, &sender_signer_sk, proposals_submitted);
|
||||
|
||||
// first block wakes up the run loop, wait until a key registration has been submitted.
|
||||
next_block_and(&mut btc_regtest_controller, 60, || {
|
||||
let vrf_count = vrfs_submitted.load(Ordering::SeqCst);
|
||||
@@ -807,7 +985,12 @@ fn simple_neon_integration() {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
signer_vote_if_needed(&btc_regtest_controller, &naka_conf, &[sender_signer_sk]);
|
||||
signer_vote_if_needed(
|
||||
&btc_regtest_controller,
|
||||
&naka_conf,
|
||||
&[sender_signer_sk],
|
||||
&signers,
|
||||
);
|
||||
}
|
||||
|
||||
// Submit a TX
|
||||
@@ -844,7 +1027,12 @@ fn simple_neon_integration() {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
signer_vote_if_needed(&btc_regtest_controller, &naka_conf, &[sender_signer_sk]);
|
||||
signer_vote_if_needed(
|
||||
&btc_regtest_controller,
|
||||
&naka_conf,
|
||||
&[sender_signer_sk],
|
||||
&signers,
|
||||
);
|
||||
}
|
||||
|
||||
// load the chain tip, and assert that it is a nakamoto block and at least 30 blocks have advanced in epoch 3
|
||||
@@ -916,6 +1104,7 @@ fn mine_multiple_per_tenure_integration() {
|
||||
return;
|
||||
}
|
||||
|
||||
let signers = TestSigners::default();
|
||||
let (mut naka_conf, _miner_account) = naka_neon_integration_conf(None);
|
||||
let http_origin = format!("http://{}", &naka_conf.node.rpc_bind);
|
||||
naka_conf.miner.wait_on_interim_blocks = Duration::from_secs(1);
|
||||
@@ -960,6 +1149,7 @@ fn mine_multiple_per_tenure_integration() {
|
||||
blocks_processed,
|
||||
naka_submitted_vrfs: vrfs_submitted,
|
||||
naka_submitted_commits: commits_submitted,
|
||||
naka_proposed_blocks: proposals_submitted,
|
||||
..
|
||||
} = run_loop.counters();
|
||||
|
||||
@@ -975,6 +1165,7 @@ fn mine_multiple_per_tenure_integration() {
|
||||
&blocks_processed,
|
||||
&[stacker_sk],
|
||||
&[sender_signer_sk],
|
||||
Some(&signers),
|
||||
&mut btc_regtest_controller,
|
||||
);
|
||||
|
||||
@@ -997,6 +1188,8 @@ fn mine_multiple_per_tenure_integration() {
|
||||
.stacks_block_height;
|
||||
|
||||
info!("Nakamoto miner started...");
|
||||
blind_signer(&naka_conf, &signers, &sender_signer_sk, proposals_submitted);
|
||||
|
||||
// first block wakes up the run loop, wait until a key registration has been submitted.
|
||||
next_block_and(&mut btc_regtest_controller, 60, || {
|
||||
let vrf_count = vrfs_submitted.load(Ordering::SeqCst);
|
||||
@@ -1093,6 +1286,7 @@ fn correct_burn_outs() {
|
||||
return;
|
||||
}
|
||||
|
||||
let signers = TestSigners::default();
|
||||
let (mut naka_conf, _miner_account) = naka_neon_integration_conf(None);
|
||||
naka_conf.burnchain.pox_reward_length = Some(10);
|
||||
naka_conf.burnchain.pox_prepare_length = Some(3);
|
||||
@@ -1149,6 +1343,7 @@ fn correct_burn_outs() {
|
||||
blocks_processed,
|
||||
naka_submitted_vrfs: vrfs_submitted,
|
||||
naka_submitted_commits: commits_submitted,
|
||||
naka_proposed_blocks: proposals_submitted,
|
||||
..
|
||||
} = run_loop.counters();
|
||||
|
||||
@@ -1280,7 +1475,12 @@ fn correct_burn_outs() {
|
||||
&naka_conf,
|
||||
);
|
||||
|
||||
signer_vote_if_needed(&btc_regtest_controller, &naka_conf, &[sender_signer_sk]);
|
||||
signer_vote_if_needed(
|
||||
&btc_regtest_controller,
|
||||
&naka_conf,
|
||||
&[sender_signer_sk],
|
||||
&signers,
|
||||
);
|
||||
|
||||
run_until_burnchain_height(
|
||||
&mut btc_regtest_controller,
|
||||
@@ -1290,6 +1490,7 @@ fn correct_burn_outs() {
|
||||
);
|
||||
|
||||
info!("Bootstrapped to Epoch-3.0 boundary, Epoch2x miner should stop");
|
||||
blind_signer(&naka_conf, &signers, &sender_signer_sk, proposals_submitted);
|
||||
|
||||
// we should already be able to query the stacker set via RPC
|
||||
let burnchain = naka_conf.get_burnchain();
|
||||
@@ -1351,7 +1552,12 @@ fn correct_burn_outs() {
|
||||
"The new burnchain tip must have been processed"
|
||||
);
|
||||
|
||||
signer_vote_if_needed(&btc_regtest_controller, &naka_conf, &[sender_signer_sk]);
|
||||
signer_vote_if_needed(
|
||||
&btc_regtest_controller,
|
||||
&naka_conf,
|
||||
&[sender_signer_sk],
|
||||
&signers,
|
||||
);
|
||||
}
|
||||
|
||||
coord_channel
|
||||
@@ -1399,6 +1605,7 @@ fn block_proposal_api_endpoint() {
|
||||
return;
|
||||
}
|
||||
|
||||
let signers = TestSigners::default();
|
||||
let (mut conf, _miner_account) = naka_neon_integration_conf(None);
|
||||
let account_keys = add_initial_balances(&mut conf, 10, 1_000_000);
|
||||
let stacker_sk = setup_stacker(&mut conf);
|
||||
@@ -1430,6 +1637,7 @@ fn block_proposal_api_endpoint() {
|
||||
blocks_processed,
|
||||
naka_submitted_vrfs: vrfs_submitted,
|
||||
naka_submitted_commits: commits_submitted,
|
||||
naka_proposed_blocks: proposals_submitted,
|
||||
..
|
||||
} = run_loop.counters();
|
||||
|
||||
@@ -1442,10 +1650,12 @@ fn block_proposal_api_endpoint() {
|
||||
&blocks_processed,
|
||||
&[stacker_sk],
|
||||
&[sender_signer_sk],
|
||||
Some(&signers),
|
||||
&mut btc_regtest_controller,
|
||||
);
|
||||
|
||||
info!("Bootstrapped to Epoch-3.0 boundary, starting nakamoto miner");
|
||||
blind_signer(&conf, &signers, &sender_signer_sk, proposals_submitted);
|
||||
|
||||
let burnchain = conf.get_burnchain();
|
||||
let sortdb = burnchain.open_sortition_db(true).unwrap();
|
||||
@@ -1493,9 +1703,6 @@ fn block_proposal_api_endpoint() {
|
||||
// TODO (hack) instantiate the sortdb in the burnchain
|
||||
_ = btc_regtest_controller.sortdb_mut();
|
||||
|
||||
// Set up test signer
|
||||
let signer = conf.miner.self_signing_key.as_mut().unwrap();
|
||||
|
||||
// ----- Setup boilerplate finished, test block proposal API endpoint -----
|
||||
|
||||
let tip = NakamotoChainState::get_canonical_block_header(chainstate.db(), &sortdb)
|
||||
@@ -1524,19 +1731,13 @@ fn block_proposal_api_endpoint() {
|
||||
_ => None,
|
||||
});
|
||||
|
||||
// Apply both miner/stacker signatures
|
||||
let mut sign = |mut p: NakamotoBlockProposal| {
|
||||
// Apply miner signature
|
||||
let sign = |p: &NakamotoBlockProposal| {
|
||||
let mut p = p.clone();
|
||||
p.block
|
||||
.header
|
||||
.sign_miner(&privk)
|
||||
.expect("Miner failed to sign");
|
||||
let burn_height = burnchain
|
||||
.get_highest_burnchain_block()
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.block_height;
|
||||
let cycle = burnchain.block_height_to_reward_cycle(burn_height).unwrap();
|
||||
signer.sign_nakamoto_block(&mut p.block, cycle);
|
||||
p
|
||||
};
|
||||
|
||||
@@ -1594,15 +1795,15 @@ fn block_proposal_api_endpoint() {
|
||||
let test_cases = [
|
||||
(
|
||||
"Valid Nakamoto block proposal",
|
||||
sign(proposal.clone()),
|
||||
sign(&proposal),
|
||||
HTTP_ACCEPTED,
|
||||
Some(Ok(())),
|
||||
),
|
||||
("Must wait", sign(proposal.clone()), HTTP_TOO_MANY, None),
|
||||
("Must wait", sign(&proposal), HTTP_TOO_MANY, None),
|
||||
(
|
||||
"Corrupted (bit flipped after signing)",
|
||||
(|| {
|
||||
let mut sp = sign(proposal.clone());
|
||||
let mut sp = sign(&proposal);
|
||||
sp.block.header.consensus_hash.0[3] ^= 0x07;
|
||||
sp
|
||||
})(),
|
||||
@@ -1614,7 +1815,7 @@ fn block_proposal_api_endpoint() {
|
||||
(|| {
|
||||
let mut p = proposal.clone();
|
||||
p.chain_id ^= 0xFFFFFFFF;
|
||||
sign(p)
|
||||
sign(&p)
|
||||
})(),
|
||||
HTTP_ACCEPTED,
|
||||
Some(Err(ValidateRejectCode::InvalidBlock)),
|
||||
@@ -1622,7 +1823,7 @@ fn block_proposal_api_endpoint() {
|
||||
(
|
||||
"Invalid `miner_signature`",
|
||||
(|| {
|
||||
let mut sp = sign(proposal.clone());
|
||||
let mut sp = sign(&proposal);
|
||||
sp.block.header.miner_signature.0[1] ^= 0x80;
|
||||
sp
|
||||
})(),
|
||||
@@ -1746,6 +1947,7 @@ fn miner_writes_proposed_block_to_stackerdb() {
|
||||
return;
|
||||
}
|
||||
|
||||
let signers = TestSigners::default();
|
||||
let (mut naka_conf, _miner_account) = naka_neon_integration_conf(None);
|
||||
naka_conf.miner.wait_on_interim_blocks = Duration::from_secs(1000);
|
||||
let sender_sk = Secp256k1PrivateKey::new();
|
||||
@@ -1786,6 +1988,7 @@ fn miner_writes_proposed_block_to_stackerdb() {
|
||||
blocks_processed,
|
||||
naka_submitted_vrfs: vrfs_submitted,
|
||||
naka_submitted_commits: commits_submitted,
|
||||
naka_proposed_blocks: proposals_submitted,
|
||||
..
|
||||
} = run_loop.counters();
|
||||
|
||||
@@ -1798,10 +2001,12 @@ fn miner_writes_proposed_block_to_stackerdb() {
|
||||
&blocks_processed,
|
||||
&[stacker_sk],
|
||||
&[sender_signer_sk],
|
||||
Some(&signers),
|
||||
&mut btc_regtest_controller,
|
||||
);
|
||||
|
||||
info!("Nakamoto miner started...");
|
||||
blind_signer(&naka_conf, &signers, &sender_signer_sk, proposals_submitted);
|
||||
// first block wakes up the run loop, wait until a key registration has been submitted.
|
||||
next_block_and(&mut btc_regtest_controller, 60, || {
|
||||
let vrf_count = vrfs_submitted.load(Ordering::SeqCst);
|
||||
@@ -1840,20 +2045,14 @@ fn miner_writes_proposed_block_to_stackerdb() {
|
||||
.expect("Unable to get miner slot")
|
||||
.expect("No miner slot exists");
|
||||
|
||||
let chunk = std::thread::spawn(move || {
|
||||
let proposed_block: NakamotoBlock = {
|
||||
let miner_contract_id = boot_code_id(MINERS_NAME, false);
|
||||
let mut miners_stackerdb = StackerDBSession::new(rpc_sock, miner_contract_id);
|
||||
miners_stackerdb
|
||||
.get_latest_chunk(slot_id)
|
||||
.get_latest(slot_id)
|
||||
.expect("Failed to get latest chunk from the miner slot ID")
|
||||
.expect("No chunk found")
|
||||
})
|
||||
.join()
|
||||
.expect("Failed to join chunk handle");
|
||||
|
||||
// We should now successfully deserialize a chunk
|
||||
let proposed_block = NakamotoBlock::consensus_deserialize(&mut &chunk[..])
|
||||
.expect("Failed to deserialize chunk into block");
|
||||
};
|
||||
let proposed_block_hash = format!("0x{}", proposed_block.header.block_hash());
|
||||
|
||||
let mut proposed_zero_block = proposed_block.clone();
|
||||
|
||||
@@ -92,7 +92,6 @@ impl SignerTest {
|
||||
.collect::<Vec<StacksPrivateKey>>();
|
||||
|
||||
let (mut naka_conf, _miner_account) = naka_neon_integration_conf(None);
|
||||
naka_conf.miner.self_signing_key = None;
|
||||
|
||||
// Setup the signer and coordinator configurations
|
||||
let signer_configs = build_signer_config_tomls(
|
||||
@@ -715,9 +714,9 @@ fn setup_stx_btc_node(
|
||||
btc_regtest_controller,
|
||||
run_loop_thread,
|
||||
run_loop_stopper,
|
||||
vrfs_submitted,
|
||||
commits_submitted,
|
||||
blocks_processed,
|
||||
vrfs_submitted: vrfs_submitted.0,
|
||||
commits_submitted: commits_submitted.0,
|
||||
blocks_processed: blocks_processed.0,
|
||||
coord_channel,
|
||||
conf: naka_conf,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user