Skip to content

Commit f9ac9b2

Browse files
committed
Merge branch 'develop' of https://github.com/stacks-network/stacks-core into feature/timed-out-block-proposal-handling
2 parents ba24d00 + 409fb28 commit f9ac9b2

File tree

27 files changed

+1380
-364
lines changed

27 files changed

+1380
-364
lines changed

.github/workflows/bitcoin-tests.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,15 @@ jobs:
9090
- tests::signer::v0::forked_tenure_okay
9191
- tests::signer::v0::forked_tenure_invalid
9292
- tests::signer::v0::empty_sortition
93+
- tests::signer::v0::bitcoind_forking_test
9394
- tests::nakamoto_integrations::stack_stx_burn_op_integration_test
9495
- tests::nakamoto_integrations::check_block_heights
9596
- tests::nakamoto_integrations::clarity_burn_state
9697
- tests::nakamoto_integrations::check_block_times
9798
- tests::nakamoto_integrations::check_block_info
9899
- tests::nakamoto_integrations::check_block_info_rewards
99100
- tests::nakamoto_integrations::continue_tenure_extend
101+
- tests::nakamoto_integrations::multiple_miners
100102
# Do not run this one until we figure out why it fails in CI
101103
# - tests::neon_integrations::bitcoin_reorg_flap
102104
# - tests::neon_integrations::bitcoin_reorg_flap_with_follower

libsigner/src/events.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,6 @@ fn process_stackerdb_event<T: SignerEventTrait>(
393393
local_addr: Option<SocketAddr>,
394394
mut request: HttpRequest,
395395
) -> Result<SignerEvent<T>, EventError> {
396-
debug!("Got stackerdb_chunks event");
397396
let mut body = String::new();
398397
if let Err(e) = request.as_reader().read_to_string(&mut body) {
399398
error!("Failed to read body: {:?}", &e);
@@ -404,6 +403,7 @@ fn process_stackerdb_event<T: SignerEventTrait>(
404403
)));
405404
}
406405

406+
debug!("Got stackerdb_chunks event"; "chunks_event_body" => %body);
407407
let event: StackerDBChunksEvent = serde_json::from_slice(body.as_bytes())
408408
.map_err(|e| EventError::Deserialize(format!("Could not decode body to JSON: {:?}", &e)))?;
409409

stacks-common/src/deps_common/httparse/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1280,7 +1280,6 @@ mod tests {
12801280
);
12811281
}
12821282

1283-
#[cfg(feature = "std")]
12841283
#[test]
12851284
fn test_std_error() {
12861285
use std::error::Error as StdError;

stacks-signer/src/chainstate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ impl SortitionsView {
485485
Ok(true)
486486
} else {
487487
warn!(
488-
"Miner block proposal's tenure change transaction does not confirm as many blocks as we expect in the parent tenure";
488+
"Miner's block proposal does not confirm as many blocks as we expect";
489489
"proposed_block_consensus_hash" => %block.header.consensus_hash,
490490
"proposed_block_signer_sighash" => %block.header.signer_signature_hash(),
491491
"proposed_chain_length" => block.header.chain_length,

stacks-signer/src/cli.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use clarity::util::hash::Sha256Sum;
2929
use clarity::util::secp256k1::MessageSignature;
3030
use clarity::vm::types::{QualifiedContractIdentifier, TupleData};
3131
use clarity::vm::Value;
32+
use lazy_static::lazy_static;
3233
use serde::{Deserialize, Serialize};
3334
use stacks_common::address::{
3435
b58, AddressHashMode, C32_ADDRESS_VERSION_MAINNET_MULTISIG,
@@ -40,8 +41,34 @@ use stacks_common::types::chainstate::StacksPrivateKey;
4041

4142
extern crate alloc;
4243

44+
const GIT_BRANCH: Option<&'static str> = option_env!("GIT_BRANCH");
45+
const GIT_COMMIT: Option<&'static str> = option_env!("GIT_COMMIT");
46+
#[cfg(debug_assertions)]
47+
const BUILD_TYPE: &'static str = "debug";
48+
#[cfg(not(debug_assertions))]
49+
const BUILD_TYPE: &'static str = "release";
50+
51+
lazy_static! {
52+
static ref VERSION_STRING: String = {
53+
let pkg_version = option_env!("STACKS_NODE_VERSION").unwrap_or(env!("CARGO_PKG_VERSION"));
54+
let git_branch = GIT_BRANCH.unwrap_or("");
55+
let git_commit = GIT_COMMIT.unwrap_or("");
56+
format!(
57+
"{} ({}:{}, {} build, {} [{}])",
58+
pkg_version,
59+
git_branch,
60+
git_commit,
61+
BUILD_TYPE,
62+
std::env::consts::OS,
63+
std::env::consts::ARCH
64+
)
65+
};
66+
}
67+
4368
#[derive(Parser, Debug)]
4469
#[command(author, version, about)]
70+
#[command(long_version = VERSION_STRING.as_str())]
71+
4572
/// The CLI arguments for the stacks signer
4673
pub struct Cli {
4774
/// Subcommand action to take

stacks-signer/src/signerdb.rs

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,53 @@ use stacks_common::util::hash::Sha512Trunc256Sum;
3434
use stacks_common::{debug, error};
3535
use wsts::net::NonceRequest;
3636

37+
#[derive(Serialize, Deserialize, Debug, PartialEq, Default)]
38+
/// Information specific to Signer V1
39+
pub struct BlockInfoV1 {
40+
/// The associated packet nonce request if we have one
41+
pub nonce_request: Option<NonceRequest>,
42+
}
43+
44+
impl From<NonceRequest> for BlockInfoV1 {
45+
fn from(value: NonceRequest) -> Self {
46+
Self {
47+
nonce_request: Some(value),
48+
}
49+
}
50+
}
51+
52+
#[derive(Serialize, Deserialize, Debug, PartialEq, Default)]
53+
/// Store extra version-specific info in `BlockInfo`
54+
pub enum ExtraBlockInfo {
55+
#[default]
56+
/// Don't know what version
57+
None,
58+
/// Extra data for Signer V0
59+
V0,
60+
/// Extra data for Signer V1
61+
V1(BlockInfoV1),
62+
}
63+
64+
impl ExtraBlockInfo {
65+
/// Take `nonce_request` if it exists
66+
pub fn take_nonce_request(&mut self) -> Option<NonceRequest> {
67+
match self {
68+
ExtraBlockInfo::None | ExtraBlockInfo::V0 => None,
69+
ExtraBlockInfo::V1(v1) => v1.nonce_request.take(),
70+
}
71+
}
72+
/// Set `nonce_request` if it exists
73+
pub fn set_nonce_request(&mut self, value: NonceRequest) -> Result<(), &str> {
74+
match self {
75+
ExtraBlockInfo::None | ExtraBlockInfo::V0 => Err("Field doesn't exist"),
76+
ExtraBlockInfo::V1(v1) => {
77+
v1.nonce_request = Some(value);
78+
Ok(())
79+
}
80+
}
81+
}
82+
}
83+
3784
/// Additional Info about a proposed block
3885
#[derive(Serialize, Deserialize, Debug, PartialEq)]
3986
pub struct BlockInfo {
@@ -47,8 +94,6 @@ pub struct BlockInfo {
4794
pub vote: Option<NakamotoBlockVote>,
4895
/// Whether the block contents are valid
4996
pub valid: Option<bool>,
50-
/// The associated packet nonce request if we have one
51-
pub nonce_request: Option<NonceRequest>,
5297
/// Whether this block is already being signed over
5398
pub signed_over: bool,
5499
/// Time at which the proposal was received by this signer (epoch time in seconds)
@@ -57,6 +102,8 @@ pub struct BlockInfo {
57102
pub signed_self: Option<u64>,
58103
/// Time at which the proposal was signed by a threshold in the signer set (epoch time in seconds)
59104
pub signed_group: Option<u64>,
105+
/// Extra data specific to v0, v1, etc.
106+
pub ext: ExtraBlockInfo,
60107
}
61108

62109
impl From<BlockProposal> for BlockInfo {
@@ -67,19 +114,19 @@ impl From<BlockProposal> for BlockInfo {
67114
reward_cycle: value.reward_cycle,
68115
vote: None,
69116
valid: None,
70-
nonce_request: None,
71117
signed_over: false,
72118
proposed_time: get_epoch_time_secs(),
73119
signed_self: None,
74120
signed_group: None,
121+
ext: ExtraBlockInfo::default(),
75122
}
76123
}
77124
}
78125
impl BlockInfo {
79126
/// Create a new BlockInfo with an associated nonce request packet
80-
pub fn new_with_request(block_proposal: BlockProposal, nonce_request: NonceRequest) -> Self {
127+
pub fn new_v1_with_request(block_proposal: BlockProposal, nonce_request: NonceRequest) -> Self {
81128
let mut block_info = BlockInfo::from(block_proposal);
82-
block_info.nonce_request = Some(nonce_request);
129+
block_info.ext = ExtraBlockInfo::V1(BlockInfoV1::from(nonce_request));
83130
block_info.signed_over = true;
84131
block_info
85132
}
@@ -89,9 +136,7 @@ impl BlockInfo {
89136
pub fn mark_signed_and_valid(&mut self) {
90137
self.valid = Some(true);
91138
self.signed_over = true;
92-
if self.signed_self.is_none() {
93-
self.signed_self = Some(get_epoch_time_secs());
94-
}
139+
self.signed_self.get_or_insert(get_epoch_time_secs());
95140
}
96141

97142
/// Return the block's signer signature hash
@@ -115,7 +160,7 @@ CREATE TABLE IF NOT EXISTS blocks (
115160
block_info TEXT NOT NULL,
116161
consensus_hash TEXT NOT NULL,
117162
signed_over INTEGER NOT NULL,
118-
stacks_height INTEGER NOT NULL,
163+
stacks_height INTEGER NOT NULL,
119164
burn_block_height INTEGER NOT NULL,
120165
PRIMARY KEY (reward_cycle, signer_signature_hash)
121166
) STRICT";

stacks-signer/src/v1/signer.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ impl Signer {
692692
block_info
693693
}
694694
};
695-
if let Some(mut nonce_request) = block_info.nonce_request.take() {
695+
if let Some(mut nonce_request) = block_info.ext.take_nonce_request() {
696696
debug!("{self}: Received a block validate response from the stacks node for a block we already received a nonce request for. Responding to the nonce request...");
697697
// We have received validation from the stacks node. Determine our vote and update the request message
698698
self.determine_vote(&mut block_info, &mut nonce_request);
@@ -916,7 +916,7 @@ impl Signer {
916916
"{self}: received a nonce request for a new block. Submit block for validation. ";
917917
"signer_sighash" => %signer_signature_hash,
918918
);
919-
let block_info = BlockInfo::new_with_request(block_proposal, nonce_request.clone());
919+
let block_info = BlockInfo::new_v1_with_request(block_proposal, nonce_request.clone());
920920
stacks_client
921921
.submit_block_for_validation(block_info.block.clone())
922922
.unwrap_or_else(|e| {
@@ -928,7 +928,12 @@ impl Signer {
928928
if block_info.valid.is_none() {
929929
// We have not yet received validation from the stacks node. Cache the request and wait for validation
930930
debug!("{self}: We have yet to receive validation from the stacks node for a nonce request. Cache the nonce request and wait for block validation...");
931-
block_info.nonce_request = Some(nonce_request.clone());
931+
block_info
932+
.ext
933+
.set_nonce_request(nonce_request.clone())
934+
.unwrap_or_else(|e| {
935+
warn!("{self}: Failed to set nonce_request: {e:?}",);
936+
});
932937
return Some(block_info);
933938
}
934939

stackslib/src/chainstate/burn/operations/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ pub struct LeaderBlockCommitOp {
249249
/// of the PoX addresses active during the block commit.
250250
///
251251
/// This value is set by the check() call, not during parsing.
252+
#[serde(default = "default_treatment")]
252253
pub treatment: Vec<Treatment>,
253254

254255
// PoX sunset burn
@@ -261,6 +262,10 @@ pub struct LeaderBlockCommitOp {
261262
pub burn_header_hash: BurnchainHeaderHash, // hash of the burn chain block header
262263
}
263264

265+
fn default_treatment() -> Vec<Treatment> {
266+
Vec::new()
267+
}
268+
264269
#[derive(Debug, PartialEq, Clone, Eq, Serialize, Deserialize)]
265270
pub struct LeaderKeyRegisterOp {
266271
pub consensus_hash: ConsensusHash, // consensus hash at time of issuance

0 commit comments

Comments
 (0)