Skip to content

Commit f6314e6

Browse files
committed
refactor(signer): Add enum for version-specific data to BlockInfo
1 parent beb4795 commit f6314e6

File tree

3 files changed

+101
-27
lines changed

3 files changed

+101
-27
lines changed

stacks-signer/src/signerdb.rs

Lines changed: 79 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,73 @@ 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+
/// Whether this block is already being signed over
43+
pub signed_over: bool,
44+
}
45+
46+
impl From<NonceRequest> for BlockInfoV1 {
47+
fn from(value: NonceRequest) -> Self {
48+
Self {
49+
nonce_request: Some(value),
50+
signed_over: true,
51+
}
52+
}
53+
}
54+
55+
#[derive(Serialize, Deserialize, Debug, PartialEq, Default)]
56+
/// Store extra version-specific info in `BlockInfo`
57+
pub enum ExtraBlockInfo {
58+
#[default]
59+
/// Don't know what version
60+
None,
61+
/// Extra data for Signer V0
62+
V0,
63+
/// Extra data for Signer V1
64+
V1(BlockInfoV1),
65+
}
66+
67+
impl ExtraBlockInfo {
68+
/// Get `signed_over` if it exists
69+
pub fn get_signed_over(&self) -> Option<bool> {
70+
match self {
71+
ExtraBlockInfo::None | ExtraBlockInfo::V0 => None,
72+
ExtraBlockInfo::V1(v1) => Some(v1.signed_over),
73+
}
74+
}
75+
/// Set `signed_over` if it exists
76+
pub fn set_signed_over(&mut self, value: bool) -> Result<(), &str> {
77+
match self {
78+
ExtraBlockInfo::None | ExtraBlockInfo::V0 => Err("Field doesn't exist"),
79+
ExtraBlockInfo::V1(v1) => {
80+
v1.signed_over = value;
81+
Ok(())
82+
}
83+
}
84+
}
85+
/// Take `nonce_request` if it exists
86+
pub fn take_nonce_request(&mut self) -> Option<NonceRequest> {
87+
match self {
88+
ExtraBlockInfo::None | ExtraBlockInfo::V0 => None,
89+
ExtraBlockInfo::V1(v1) => v1.nonce_request.take(),
90+
}
91+
}
92+
/// Set `nonce_request` if it exists
93+
pub fn set_nonce_request(&mut self, value: NonceRequest) -> Result<(), &str> {
94+
match self {
95+
ExtraBlockInfo::None | ExtraBlockInfo::V0 => Err("Field doesn't exist"),
96+
ExtraBlockInfo::V1(v1) => {
97+
v1.nonce_request = Some(value);
98+
Ok(())
99+
}
100+
}
101+
}
102+
}
103+
37104
/// Additional Info about a proposed block
38105
#[derive(Serialize, Deserialize, Debug, PartialEq)]
39106
pub struct BlockInfo {
@@ -47,16 +114,14 @@ pub struct BlockInfo {
47114
pub vote: Option<NakamotoBlockVote>,
48115
/// Whether the block contents are valid
49116
pub valid: Option<bool>,
50-
/// The associated packet nonce request if we have one
51-
pub nonce_request: Option<NonceRequest>,
52-
/// Whether this block is already being signed over
53-
pub signed_over: bool,
54117
/// Time at which the proposal was received by this signer (epoch time in seconds)
55118
pub proposed_time: u64,
56119
/// Time at which the proposal was signed by this signer (epoch time in seconds)
57120
pub signed_self: Option<u64>,
58121
/// Time at which the proposal was signed by a threshold in the signer set (epoch time in seconds)
59122
pub signed_group: Option<u64>,
123+
/// Extra data specific to v0, v1, etc.
124+
pub ext: ExtraBlockInfo,
60125
}
61126

62127
impl From<BlockProposal> for BlockInfo {
@@ -67,31 +132,27 @@ impl From<BlockProposal> for BlockInfo {
67132
reward_cycle: value.reward_cycle,
68133
vote: None,
69134
valid: None,
70-
nonce_request: None,
71-
signed_over: false,
72135
proposed_time: get_epoch_time_secs(),
73136
signed_self: None,
74137
signed_group: None,
138+
ext: ExtraBlockInfo::default(),
75139
}
76140
}
77141
}
78142
impl BlockInfo {
79143
/// Create a new BlockInfo with an associated nonce request packet
80-
pub fn new_with_request(block_proposal: BlockProposal, nonce_request: NonceRequest) -> Self {
144+
pub fn new_v1_with_request(block_proposal: BlockProposal, nonce_request: NonceRequest) -> Self {
81145
let mut block_info = BlockInfo::from(block_proposal);
82-
block_info.nonce_request = Some(nonce_request);
83-
block_info.signed_over = true;
146+
block_info.ext = ExtraBlockInfo::V1(BlockInfoV1::from(nonce_request));
84147
block_info
85148
}
86149

87150
/// Mark this block as valid, signed over, and record a timestamp in the block info if it wasn't
88151
/// already set.
89152
pub fn mark_signed_and_valid(&mut self) {
90153
self.valid = Some(true);
91-
self.signed_over = true;
92-
if self.signed_self.is_none() {
93-
self.signed_self = Some(get_epoch_time_secs());
94-
}
154+
self.signed_self.get_or_insert(get_epoch_time_secs());
155+
_ = self.ext.set_signed_over(true);
95156
}
96157

97158
/// Return the block's signer signature hash
@@ -115,7 +176,7 @@ CREATE TABLE IF NOT EXISTS blocks (
115176
block_info TEXT NOT NULL,
116177
consensus_hash TEXT NOT NULL,
117178
signed_over INTEGER NOT NULL,
118-
stacks_height INTEGER NOT NULL,
179+
stacks_height INTEGER NOT NULL,
119180
burn_block_height INTEGER NOT NULL,
120181
PRIMARY KEY (reward_cycle, signer_signature_hash)
121182
) STRICT";
@@ -189,7 +250,7 @@ impl SignerDb {
189250
})
190251
.optional();
191252
match result {
192-
Ok(x) => Ok(x.unwrap_or_else(|| 0)),
253+
Ok(x) => Ok(x.unwrap_or(0)),
193254
Err(e) => Err(DBError::from(e)),
194255
}
195256
}
@@ -346,7 +407,7 @@ impl SignerDb {
346407
serde_json::to_string(&block_info).expect("Unable to serialize block info");
347408
let hash = &block_info.signer_signature_hash();
348409
let block_id = &block_info.block.block_id();
349-
let signed_over = &block_info.signed_over;
410+
let signed_over = &block_info.ext.get_signed_over().unwrap_or(false);
350411
let vote = block_info
351412
.vote
352413
.as_ref()
@@ -543,6 +604,8 @@ mod tests {
543604
let db_path = tmp_db_path();
544605
let mut db = SignerDb::new(db_path).expect("Failed to create signer db");
545606
let (mut block_info, block_proposal) = create_block();
607+
// We'll need the V1 data fields for this
608+
block_info.ext = ExtraBlockInfo::V1(BlockInfoV1::default());
546609
db.insert_block(&block_info).unwrap();
547610

548611
assert!(db

stacks-signer/src/v1/signer.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ impl Signer {
586586
.block_lookup(self.reward_cycle, &signer_signature_hash)
587587
.unwrap_or_else(|_| Some(BlockInfo::from(block_proposal.clone())))
588588
.unwrap_or_else(|| BlockInfo::from(block_proposal.clone()));
589-
if block_info.signed_over {
589+
if block_info.ext.get_signed_over().unwrap_or(false) {
590590
debug!("{self}: Received a sign command for a block we are already signing over. Ignore it.");
591591
return;
592592
}
@@ -603,7 +603,9 @@ impl Signer {
603603
Ok(msg) => {
604604
let ack = self.stackerdb_manager.send_message_with_retry(msg.into());
605605
debug!("{self}: ACK: {ack:?}",);
606-
block_info.signed_over = true;
606+
block_info.ext.set_signed_over(true).unwrap_or_else(|e| {
607+
error!("{self}: `set_signed_over()` failed: {e:?}");
608+
});
607609
self.signer_db
608610
.insert_block(&block_info)
609611
.unwrap_or_else(|e| {
@@ -692,7 +694,7 @@ impl Signer {
692694
block_info
693695
}
694696
};
695-
if let Some(mut nonce_request) = block_info.nonce_request.take() {
697+
if let Some(mut nonce_request) = block_info.ext.take_nonce_request() {
696698
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...");
697699
// We have received validation from the stacks node. Determine our vote and update the request message
698700
self.determine_vote(&mut block_info, &mut nonce_request);
@@ -707,7 +709,7 @@ impl Signer {
707709
"{self}: Received a block validate response";
708710
"block_hash" => block_info.block.header.block_hash(),
709711
"valid" => block_info.valid,
710-
"signed_over" => block_info.signed_over,
712+
"signed_over" => block_info.ext.get_signed_over(),
711713
);
712714
self.signer_db
713715
.insert_block(&block_info)
@@ -916,7 +918,7 @@ impl Signer {
916918
"{self}: received a nonce request for a new block. Submit block for validation. ";
917919
"signer_sighash" => %signer_signature_hash,
918920
);
919-
let block_info = BlockInfo::new_with_request(block_proposal, nonce_request.clone());
921+
let block_info = BlockInfo::new_v1_with_request(block_proposal, nonce_request.clone());
920922
stacks_client
921923
.submit_block_for_validation(block_info.block.clone())
922924
.unwrap_or_else(|e| {
@@ -928,7 +930,12 @@ impl Signer {
928930
if block_info.valid.is_none() {
929931
// We have not yet received validation from the stacks node. Cache the request and wait for validation
930932
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());
933+
block_info
934+
.ext
935+
.set_nonce_request(nonce_request.clone())
936+
.unwrap_or_else(|e| {
937+
warn!("{self}: Failed to set nonce_request: {e:?}",);
938+
});
932939
return Some(block_info);
933940
}
934941

testnet/stacks-node/src/tests/nakamoto_integrations.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ use stacks_common::util::hash::{to_hex, Hash160, Sha512Trunc256Sum};
8989
use stacks_common::util::secp256k1::{MessageSignature, Secp256k1PrivateKey, Secp256k1PublicKey};
9090
use stacks_common::util::{get_epoch_time_secs, sleep_ms};
9191
use stacks_signer::chainstate::{ProposalEvalConfig, SortitionsView};
92-
use stacks_signer::signerdb::{BlockInfo, SignerDb};
92+
use stacks_signer::signerdb::{BlockInfo, BlockInfoV1, ExtraBlockInfo, SignerDb};
9393
use wsts::net::Message;
9494

9595
use super::bitcoin_regtest::BitcoinCoreController;
@@ -4714,11 +4714,13 @@ fn signer_chainstate() {
47144714
reward_cycle,
47154715
vote: None,
47164716
valid: Some(true),
4717-
nonce_request: None,
4718-
signed_over: true,
47194717
proposed_time: get_epoch_time_secs(),
47204718
signed_self: None,
47214719
signed_group: None,
4720+
ext: ExtraBlockInfo::V1(BlockInfoV1 {
4721+
nonce_request: None,
4722+
signed_over: true,
4723+
}),
47224724
})
47234725
.unwrap();
47244726

@@ -4789,11 +4791,13 @@ fn signer_chainstate() {
47894791
reward_cycle,
47904792
vote: None,
47914793
valid: Some(true),
4792-
nonce_request: None,
4793-
signed_over: true,
47944794
proposed_time: get_epoch_time_secs(),
47954795
signed_self: None,
47964796
signed_group: None,
4797+
ext: ExtraBlockInfo::V1(BlockInfoV1 {
4798+
nonce_request: None,
4799+
signed_over: true,
4800+
}),
47974801
})
47984802
.unwrap();
47994803

0 commit comments

Comments
 (0)