Skip to content

Commit fb311cb

Browse files
authored
Merge pull request #5959 from jferrant/feat/send-signer-state-updates
Signers send updates to stackerdb when their state is Initialized/changes
2 parents d944d16 + f876d4d commit fb311cb

File tree

6 files changed

+268
-146
lines changed

6 files changed

+268
-146
lines changed

libsigner/src/v0/messages.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1705,6 +1705,12 @@ impl From<BlockResponse> for SignerMessage {
17051705
}
17061706
}
17071707

1708+
impl From<StateMachineUpdate> for SignerMessage {
1709+
fn from(update: StateMachineUpdate) -> Self {
1710+
Self::StateMachineUpdate(update)
1711+
}
1712+
}
1713+
17081714
#[cfg(test)]
17091715
mod test {
17101716
use blockstack_lib::chainstate::nakamoto::NakamotoBlockHeader;

stacks-signer/src/v0/signer.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ impl SignerTrait<SignerMessage> for Signer {
212212
return;
213213
}
214214

215+
let prior_state = self.local_state_machine.clone();
215216
if self.reward_cycle <= current_reward_cycle {
216217
self.local_state_machine.handle_pending_update(&self.signer_db, stacks_client, &self.proposal_config)
217218
.unwrap_or_else(|e| error!("{self}: failed to update local state machine for pending update"; "err" => ?e));
@@ -233,10 +234,17 @@ impl SignerTrait<SignerMessage> for Signer {
233234
);
234235
// try and gather signatures
235236
for message in messages {
236-
let SignerMessage::BlockResponse(block_response) = message else {
237-
continue;
238-
};
239-
self.handle_block_response(stacks_client, block_response, sortition_state);
237+
match message {
238+
SignerMessage::BlockResponse(block_response) => self.handle_block_response(
239+
stacks_client,
240+
block_response,
241+
sortition_state,
242+
),
243+
SignerMessage::StateMachineUpdate(_update) => {
244+
// TODO: should make note of this update view point to determine if there is an agreed upon global state
245+
}
246+
_ => {}
247+
}
240248
}
241249
}
242250
SignerEvent::MinerMessages(messages) => {
@@ -374,6 +382,10 @@ impl SignerTrait<SignerMessage> for Signer {
374382
}
375383
}
376384
}
385+
if prior_state != self.local_state_machine {
386+
self.local_state_machine
387+
.send_signer_update_message(&mut self.stackerdb);
388+
}
377389
}
378390

379391
fn has_unprocessed_blocks(&self) -> bool {

stacks-signer/src/v0/signer_state.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use std::time::{Duration, UNIX_EPOCH};
1818
use blockstack_lib::chainstate::burn::ConsensusHashExtensions;
1919
use blockstack_lib::chainstate::nakamoto::{NakamotoBlock, NakamotoBlockHeader};
2020
use libsigner::v0::messages::{
21-
StateMachineUpdate as StateMachineUpdateMessage, StateMachineUpdateContent,
22-
StateMachineUpdateMinerState,
21+
MessageSlotID, SignerMessage, StateMachineUpdate as StateMachineUpdateMessage,
22+
StateMachineUpdateContent, StateMachineUpdateMinerState,
2323
};
2424
use serde::{Deserialize, Serialize};
2525
use stacks_common::bitvec::BitVec;
@@ -32,11 +32,11 @@ use stacks_common::{info, warn};
3232
use crate::chainstate::{
3333
ProposalEvalConfig, SignerChainstateError, SortitionState, SortitionsView,
3434
};
35-
use crate::client::{ClientError, CurrentAndLastSortition, StacksClient};
35+
use crate::client::{ClientError, CurrentAndLastSortition, StackerDB, StacksClient};
3636
use crate::signerdb::SignerDb;
3737

3838
/// This is the latest supported protocol version for this signer binary
39-
pub static SUPPORTED_SIGNER_PROTOCOL_VERSION: u64 = 1;
39+
pub static SUPPORTED_SIGNER_PROTOCOL_VERSION: u64 = 0;
4040

4141
/// A signer state machine view. This struct can
4242
/// be used to encode the local signer's view or
@@ -158,7 +158,22 @@ impl LocalStateMachine {
158158
burn_block: ConsensusHash::empty(),
159159
burn_block_height: 0,
160160
current_miner: MinerState::NoValidMiner,
161-
active_signer_protocol_version: 1,
161+
active_signer_protocol_version: SUPPORTED_SIGNER_PROTOCOL_VERSION,
162+
}
163+
}
164+
165+
/// Send the local state machine as a signer update message to stackerdb
166+
pub fn send_signer_update_message(&self, stackerdb: &mut StackerDB<MessageSlotID>) {
167+
let update: Result<StateMachineUpdateMessage, _> = self.try_into();
168+
match update {
169+
Ok(update) => {
170+
if let Err(e) = stackerdb.send_message_with_retry::<SignerMessage>(update.into()) {
171+
warn!("Failed to send signer update to stacker-db: {e:?}",);
172+
}
173+
}
174+
Err(e) => {
175+
warn!("Failed to convert local signer state to a signer message: {e:?}");
176+
}
162177
}
163178
}
164179

@@ -256,7 +271,6 @@ impl LocalStateMachine {
256271
"inactive_tenure_ch" => %inactive_tenure_ch,
257272
"new_active_tenure_ch" => %new_active_tenure_ch
258273
);
259-
260274
Ok(())
261275
} else {
262276
warn!("Current miner timed out due to inactivity, but prior miner is not valid. Allowing current miner to continue");

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::collections::HashMap;
2-
use std::sync::atomic::Ordering;
32
use std::{env, thread};
43

54
use clarity::vm::costs::ExecutionCost;
@@ -15,8 +14,7 @@ use stacks::chainstate::stacks::{
1514
};
1615
use stacks::config::{EventKeyType, InitialBalance};
1716
use stacks::core::test_util::{
18-
make_contract_call, make_contract_call_mblock_only, make_contract_publish,
19-
make_contract_publish_microblock_only, to_addr,
17+
make_contract_call, make_contract_call_mblock_only, make_contract_publish, to_addr,
2018
};
2119
use stacks::core::{
2220
self, EpochList, StacksEpoch, StacksEpochId, PEER_VERSION_EPOCH_1_0, PEER_VERSION_EPOCH_2_0,
@@ -25,7 +23,6 @@ use stacks::core::{
2523
use stacks_common::codec::StacksMessageCodec;
2624
use stacks_common::types::chainstate::{BlockHeaderHash, BurnchainHeaderHash, VRFSeed};
2725
use stacks_common::util::hash::hex_bytes;
28-
use stacks_common::util::sleep_ms;
2926

3027
use crate::tests::bitcoin_regtest::BitcoinCoreController;
3128
use crate::tests::neon_integrations::*;

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

Lines changed: 3 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use clarity::vm::costs::ExecutionCost;
1111
use clarity::vm::types::serialization::SerializationError;
1212
use clarity::vm::types::PrincipalData;
1313
use clarity::vm::{ClarityName, ClarityVersion, ContractName, Value, MAX_CALL_STACK_DEPTH};
14-
use rand::Rng;
1514
use rusqlite::params;
1615
use serde::Deserialize;
1716
use serde_json::json;
@@ -30,12 +29,11 @@ use stacks::chainstate::stacks::address::PoxAddress;
3029
use stacks::chainstate::stacks::boot::POX_4_NAME;
3130
use stacks::chainstate::stacks::db::StacksChainState;
3231
use stacks::chainstate::stacks::miner::{
33-
signal_mining_blocked, signal_mining_ready, TransactionErrorEvent, TransactionEvent,
34-
TransactionSuccessEvent,
32+
TransactionErrorEvent, TransactionEvent, TransactionSuccessEvent,
3533
};
3634
use stacks::chainstate::stacks::{
37-
StacksBlock, StacksBlockHeader, StacksMicroblock, StacksMicroblockHeader, StacksPrivateKey,
38-
StacksPublicKey, StacksTransaction, TransactionContractCall, TransactionPayload,
35+
StacksBlock, StacksBlockHeader, StacksMicroblock, StacksPrivateKey, StacksPublicKey,
36+
StacksTransaction, TransactionContractCall, TransactionPayload,
3937
};
4038
use stacks::clarity_cli::vm_execute as execute;
4139
use stacks::cli;
@@ -90,8 +88,6 @@ use crate::stacks_common::types::PrivateKey;
9088
use crate::syncctl::PoxSyncWatchdogComms;
9189
use crate::tests::gen_random_port;
9290
use crate::tests::nakamoto_integrations::{get_key_for_cycle, wait_for};
93-
use crate::util::hash::{MerkleTree, Sha512Trunc256Sum};
94-
use crate::util::secp256k1::MessageSignature;
9591
use crate::{neon, BitcoinRegtestController, BurnchainController, Config, ConfigFile, Keychain};
9692

9793
fn inner_neon_integration_test_conf(seed: Option<Vec<u8>>) -> (Config, StacksAddress) {
@@ -3316,34 +3312,6 @@ fn should_fix_2771() {
33163312
channel.stop_chains_coordinator();
33173313
}
33183314

3319-
/// Returns a StacksMicroblock with the given transactions, sequence, and parent block that is
3320-
/// signed with the given private key.
3321-
fn make_signed_microblock(
3322-
block_privk: &StacksPrivateKey,
3323-
txs: Vec<StacksTransaction>,
3324-
parent_block: BlockHeaderHash,
3325-
seq: u16,
3326-
) -> StacksMicroblock {
3327-
let mut rng = rand::thread_rng();
3328-
3329-
let txid_vecs: Vec<_> = txs.iter().map(|tx| tx.txid().as_bytes().to_vec()).collect();
3330-
let merkle_tree = MerkleTree::<Sha512Trunc256Sum>::new(&txid_vecs);
3331-
let tx_merkle_root = merkle_tree.root();
3332-
3333-
let mut mblock = StacksMicroblock {
3334-
header: StacksMicroblockHeader {
3335-
version: rng.gen(),
3336-
sequence: seq,
3337-
prev_block: parent_block,
3338-
tx_merkle_root,
3339-
signature: MessageSignature([0u8; 65]),
3340-
},
3341-
txs,
3342-
};
3343-
mblock.sign(block_privk).unwrap();
3344-
mblock
3345-
}
3346-
33473315
#[test]
33483316
#[ignore]
33493317
fn filter_low_fee_tx_integration_test() {
@@ -8614,38 +8582,6 @@ pub fn make_random_tx_chain(
86148582
chain
86158583
}
86168584

8617-
fn make_mblock_tx_chain(privk: &StacksPrivateKey, fee_plus: u64, chain_id: u32) -> Vec<Vec<u8>> {
8618-
let addr = to_addr(privk);
8619-
let mut chain = vec![];
8620-
8621-
for nonce in 0..25 {
8622-
// N.B. private keys are 32-33 bytes, so this is always safe
8623-
let random_iters = privk.to_bytes()[nonce as usize] as usize;
8624-
8625-
let be_bytes = [
8626-
privk.to_bytes()[nonce as usize],
8627-
privk.to_bytes()[(nonce + 1) as usize],
8628-
];
8629-
8630-
let random_extra_fee = u16::from_be_bytes(be_bytes) as u64;
8631-
8632-
let mut addr_prefix = addr.to_string();
8633-
let _ = addr_prefix.split_off(12);
8634-
let contract_name = format!("crct-{nonce}-{addr_prefix}-{random_iters}");
8635-
eprintln!("Make tx {contract_name}");
8636-
let tx = make_contract_publish_microblock_only(
8637-
privk,
8638-
nonce,
8639-
1049230 + nonce + fee_plus + random_extra_fee,
8640-
chain_id,
8641-
&contract_name,
8642-
&make_runtime_sized_contract(1, nonce, &addr_prefix),
8643-
);
8644-
chain.push(tx);
8645-
}
8646-
chain
8647-
}
8648-
86498585
fn test_competing_miners_build_on_same_chain(
86508586
num_miners: usize,
86518587
conf_template: Config,

0 commit comments

Comments
 (0)