Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/vm/docs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ const PRINT_API: SpecialAPI = SpecialAPI {
input_type: "A",
output_type: "A",
signature: "(print expr)",
description: "The `print` function evaluates and returns its input expression. On Blockstack Core
description: "The `print` function evaluates and returns its input expression. On Stacks Core
nodes configured for development (as opposed to production mining nodes), this function prints the resulting value to `STDOUT` (standard output).",
example: "(print (+ 1 2 3)) ;; Returns 6",
};
Expand Down
18 changes: 13 additions & 5 deletions testnet/stacks-node/src/keychain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use stacks::burnchains::{BurnchainSigner, PrivateKey};
use stacks::chainstate::stacks::{
StacksAddress, StacksPrivateKey, StacksPublicKey, StacksTransactionSigner, TransactionAuth,
};
use stacks::util::hash::Sha256Sum;
use stacks::util::hash::{Hash160, Sha256Sum};
use stacks::util::vrf::{VRFPrivateKey, VRFProof, VRFPublicKey, VRF};

#[derive(Clone)]
Expand Down Expand Up @@ -97,14 +97,18 @@ impl Keychain {
pk
}

pub fn rotate_microblock_keypair(&mut self) -> StacksPrivateKey {
let mut seed = match self.microblocks_secret_keys.last() {
pub fn rotate_microblock_keypair(&mut self, burn_block_height: u64) -> StacksPrivateKey {
let mut secret_state = match self.microblocks_secret_keys.last() {
// First key is the hash of the secret state
None => self.hashed_secret_state,
None => self.hashed_secret_state.to_bytes().to_vec(),
// Next key is the hash of the last
Some(last_sk) => Sha256Sum::from_data(&last_sk.to_bytes()[..]),
Some(last_sk) => last_sk.to_bytes().to_vec(),
};

secret_state.extend_from_slice(&burn_block_height.to_be_bytes());

let mut seed = Sha256Sum::from_data(&secret_state);

// Not every 256-bit number is a valid secp256k1 secret key.
// As such, we continuously generate seeds through re-hashing until one works.
let mut sk = loop {
Expand All @@ -116,6 +120,10 @@ impl Keychain {
sk.set_compress_public(true);
self.microblocks_secret_keys.push(sk.clone());

debug!("Microblock keypair rotated";
"burn_block_height" => %burn_block_height,
"pubkey_hash" => %Hash160::from_node_public_key(&StacksPublicKey::from_private(&sk)).to_string(),);

sk
}

Expand Down
15 changes: 14 additions & 1 deletion testnet/stacks-node/src/neon_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1033,7 +1033,20 @@ impl InitializedNeonNode {

// Generates a new secret key for signing the trail of microblocks
// of the upcoming tenure.
let microblock_secret_key = keychain.rotate_microblock_keypair();
let microblock_secret_key = if attempt > 1 {
match keychain.get_microblock_key() {
Some(k) => k,
None => {
error!(
"Failed to obtain microblock key for mining attempt";
"attempt" => %attempt
);
return None;
}
}
} else {
keychain.rotate_microblock_keypair(burn_block.block_height)
};
let mblock_pubkey_hash =
Hash160::from_node_public_key(&StacksPublicKey::from_private(&microblock_secret_key));

Expand Down
4 changes: 3 additions & 1 deletion testnet/stacks-node/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,9 @@ impl Node {

// Generates a new secret key for signing the trail of microblocks
// of the upcoming tenure.
let microblock_secret_key = self.keychain.rotate_microblock_keypair();
let microblock_secret_key = self
.keychain
.rotate_microblock_keypair(block_to_build_upon.block_snapshot.block_height);

// Get the stack's chain tip
let chain_tip = match self.bootstraping_chain {
Expand Down
4 changes: 2 additions & 2 deletions testnet/stacks-node/src/tests/mempool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -637,8 +637,8 @@ fn mempool_setup_chainstate() {
conf.node.seed = vec![0x00];

let mut keychain = Keychain::default(conf.node.seed.clone());
for _i in 0..4 {
let microblock_secret_key = keychain.rotate_microblock_keypair();
for i in 0..4 {
let microblock_secret_key = keychain.rotate_microblock_keypair(1 + i);
let mut microblock_pubkey =
Secp256k1PublicKey::from_private(&microblock_secret_key);
microblock_pubkey.set_compressed(true);
Expand Down
5 changes: 3 additions & 2 deletions testnet/stacks-node/src/tests/neon_integrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,9 @@ fn find_microblock_privkey(
max_tries: u64,
) -> Option<StacksPrivateKey> {
let mut keychain = Keychain::default(conf.node.seed.clone());
for _ in 0..max_tries {
let privk = keychain.rotate_microblock_keypair();
for ix in 0..max_tries {
// the first rotation occurs at 203.
let privk = keychain.rotate_microblock_keypair(203 + ix);
let pubkh = Hash160::from_node_public_key(&StacksPublicKey::from_private(&privk));
if pubkh == *pubkey_hash {
return Some(privk);
Expand Down