Skip to content
This repository has been archived by the owner on Aug 22, 2024. It is now read-only.

Mutants develop/concurrency and shards/source #34

Open
wants to merge 37 commits into
base: mutants-develop/concurrency-and-shards/base
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
dba2277
wip: dkg contract interactions
soju-drinker Oct 5, 2023
4cb14bd
make
soju-drinker Oct 6, 2023
7c6ecbf
Add tests to call read only function and fix relative url
jferrant Oct 9, 2023
a85b84f
WIP: add todo functions for interacting with a contract to trigger DKG
jferrant Oct 4, 2023
0185a3d
Add call to get pox contract id from stacks node
jferrant Oct 9, 2023
f8ddb2f
Parse aggregate public key from clarity contract and add test
jferrant Oct 9, 2023
cf3619f
Fix rebase issues
jferrant Oct 10, 2023
e367cab
Fix parsing of bitcoin wallet to be a full Point rather than an xonly…
jferrant Oct 10, 2023
545f0a1
WIP: Broken commit. Issues with converting pox contract id into a Qua…
jferrant Oct 11, 2023
d393002
WIP: Broken commit. Adding scaffolding for cast_aggregate_public_key_…
jferrant Oct 11, 2023
c286e47
Add cast aggregate vote and get current reward cycle from pox
jferrant Oct 11, 2023
fa9948d
Cleanup some functions
jferrant Oct 11, 2023
7d0f653
Add another error case to reward cycle tests
jferrant Oct 11, 2023
8d62f80
Need to add get_nonce and simulate its response in ignored transactio…
jferrant Oct 11, 2023
1c5fcca
WIP: broken integration tests due to getting aggregate public key. Ad…
jferrant Oct 11, 2023
d9fb56d
Fix broken parsing due to trailing quotes in pox contract
jferrant Oct 12, 2023
aea9eb8
Add pox contract ID option to config to overwrite node result
jferrant Oct 12, 2023
96e8dcc
WIP: Need to fix state for contacting node
jferrant Oct 13, 2023
260473d
WIP: Still unable to run should_run_dkg without hanging
jferrant Oct 16, 2023
365c5a9
WIP: no longer hanging, needs cleanup
jferrant Oct 17, 2023
1ebb417
WIP: cleanup and add cast_vote helper fn
jferrant Oct 17, 2023
cee0eea
Cleanup unnecessary errors, functions, and add retry backoff to aggre…
jferrant Oct 18, 2023
0014d1e
Clippy cleanup of signer.rs
jferrant Oct 18, 2023
2be0b03
CRC: make backoff values into const vars and add github issues for TODOs
jferrant Oct 26, 2023
2ba5647
Address bug in parse_aggregate_public_key by verifying data len is 32
jferrant Oct 27, 2023
e640990
Merge pull request #3988 from stacks-network/feature/retrieve-set-dkg
xoloki Oct 30, 2023
cc8de7b
feat: ready source branch
ASuciuX Dec 19, 2023
746c66f
Merge branch 'mutants-develop/7/base' into mutants-develop/7/source
ASuciuX Dec 20, 2023
a861e32
feat: run workflow again
ASuciuX Dec 22, 2023
24d8912
feat: resolve conflicts
ASuciuX Dec 22, 2023
ec9e3ea
feat: run workflow again
ASuciuX Dec 22, 2023
2ece9d7
feat: run workflow again
ASuciuX Dec 22, 2023
76138cf
feat: run again with artifact upload
ASuciuX Dec 22, 2023
e44eab9
feat: run again with artifact download and output print
ASuciuX Dec 22, 2023
48bdc0c
feat: run again with updated folder names
ASuciuX Dec 22, 2023
34fe144
feat: try running again to test concurrency stops previous workflow
ASuciuX Dec 22, 2023
6acb3ac
feat: run with exit codes handling
ASuciuX Dec 22, 2023
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
237 changes: 219 additions & 18 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion clarity/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ resolver = "2"

[lib]
name = "clarity"
path = "./src/libclarity.rs"
path = "./src/lib.rs"

[dependencies]
rand = "0.7.3"
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion libsigner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ edition = "2021"

[lib]
name = "libsigner"
path = "./src/libsigner.rs"
path = "./src/lib.rs"

[dependencies]
clarity = { path = "../clarity" }
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion stacks-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ edition = "2021"

[lib]
name = "stacks_common"
path = "./src/libcommon.rs"
path = "./src/lib.rs"

[dependencies]
rand = "0.7.3"
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions stacks-signer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ name = "stacks-signer"
path = "src/main.rs"

[dependencies]
backoff = "0.4"
bincode = "1.3.3"
clarity = { path = "../clarity" }
clap = { version = "4.1.1", features = ["derive", "env"] }
Expand Down
19 changes: 18 additions & 1 deletion stacks-signer/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ pub struct Config {
pub endpoint: SocketAddr,
/// smart contract that controls the target stackerdb
pub stackerdb_contract_id: QualifiedContractIdentifier,
/// smart contract that controls the target stackerdb
pub pox_contract_id: Option<QualifiedContractIdentifier>,
/// The Scalar representation of the private key for signer communication
pub message_private_key: Scalar,
/// The signer's Stacks private key
Expand Down Expand Up @@ -133,8 +135,11 @@ struct RawConfigFile {
pub node_host: String,
/// endpoint to stackerdb receiver
pub endpoint: String,
/// contract identifier
// FIXME: these contract's should go away in non testing scenarios. Make them both optionals.
/// Stacker db contract identifier
pub stackerdb_contract_id: String,
/// pox contract identifier
pub pox_contract_id: Option<String>,
/// the 32 byte ECDSA private key used to sign blocks, chunks, and transactions
pub message_private_key: String,
/// The hex representation of the signer's Stacks private key used for communicating
Expand Down Expand Up @@ -214,6 +219,17 @@ impl TryFrom<RawConfigFile> for Config {
)
})?;

let pox_contract_id = if let Some(id) = raw_data.pox_contract_id.as_ref() {
Some(QualifiedContractIdentifier::parse(id).map_err(|_| {
ConfigError::BadField(
"pox_contract_id".to_string(),
raw_data.pox_contract_id.unwrap_or("".to_string()),
)
})?)
} else {
None
};

let message_private_key =
Scalar::try_from(raw_data.message_private_key.as_str()).map_err(|_| {
ConfigError::BadField(
Expand Down Expand Up @@ -265,6 +281,7 @@ impl TryFrom<RawConfigFile> for Config {
node_host,
endpoint,
stackerdb_contract_id,
pox_contract_id,
message_private_key,
stacks_private_key,
stacks_address,
Expand Down
1 change: 1 addition & 0 deletions stacks-signer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ fn handle_generate_files(args: GenerateFilesArgs) {
args.num_keys,
&args.db_args.host.to_string(),
&args.db_args.contract.to_string(),
None,
args.timeout.map(Duration::from_millis),
);
debug!("Built {:?} signer config tomls.", signer_config_tomls.len());
Expand Down
90 changes: 65 additions & 25 deletions stacks-signer/src/runloop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use wsts::state_machine::{OperationResult, PublicKeys};
use wsts::v2;

use crate::config::Config;
use crate::stacks_client::StacksClient;
use crate::stacks_client::{retry_with_exponential_backoff, ClientError, StacksClient};

/// Which operation to perform
#[derive(PartialEq, Clone)]
Expand All @@ -36,6 +36,9 @@ pub enum RunLoopCommand {
/// The RunLoop state
#[derive(PartialEq, Debug)]
pub enum State {
// TODO: Uninitialized should indicate we need to replay events/configure the signer
/// The runloop signer is uninitialized
Uninitialized,
/// The runloop is idle
Idle,
/// The runloop is executing a DKG round
Expand All @@ -48,7 +51,7 @@ pub enum State {
pub struct RunLoop<C> {
/// The timeout for events
pub event_timeout: Duration,
/// the coordinator for inbound messages
/// The coordinator for inbound messages
pub coordinator: C,
/// The signing round used to sign messages
// TODO: update this to use frost_signer directly instead of the frost signing round
Expand All @@ -63,7 +66,27 @@ pub struct RunLoop<C> {
}

impl<C: Coordinatable> RunLoop<C> {
/// Helper function to actually execute the command and update state accordingly
/// Initialize the signer, reading the stacker-db state and setting the aggregate public key
fn initialize(&mut self) -> Result<(), ClientError> {
// TODO: update to read stacker db to get state.
// Check if the aggregate key is set in the pox contract
if let Some(key) = self.stacks_client.get_aggregate_public_key()? {
debug!("Aggregate public key is set: {:?}", key);
self.coordinator.set_aggregate_public_key(Some(key));
} else {
// Update the state to IDLE so we don't needlessy requeue the DKG command.
let (coordinator_id, _) = calculate_coordinator(&self.signing_round.public_keys);
if coordinator_id == self.signing_round.signer_id
&& self.commands.front() != Some(&RunLoopCommand::Dkg)
{
self.commands.push_front(RunLoopCommand::Dkg);
}
}
self.state = State::Idle;
Ok(())
}

/// Execute the given command and update state accordingly
/// Returns true when it is successfully executed, else false
fn execute_command(&mut self, command: &RunLoopCommand) -> bool {
match command {
Expand All @@ -73,7 +96,7 @@ impl<C: Coordinatable> RunLoop<C> {
Ok(msg) => {
let ack = self
.stacks_client
.send_message(self.signing_round.signer_id, msg);
.send_message_with_retry(self.signing_round.signer_id, msg);
debug!("ACK: {:?}", ack);
self.state = State::Dkg;
true
Expand All @@ -99,7 +122,7 @@ impl<C: Coordinatable> RunLoop<C> {
Ok(msg) => {
let ack = self
.stacks_client
.send_message(self.signing_round.signer_id, msg);
.send_message_with_retry(self.signing_round.signer_id, msg);
debug!("ACK: {:?}", ack);
self.state = State::Sign;
true
Expand All @@ -115,9 +138,14 @@ impl<C: Coordinatable> RunLoop<C> {
}
}

/// Helper function to check the current state, process the next command in the queue, and update state accordingly
/// Attempt to process the next command in the queue, and update state accordingly
fn process_next_command(&mut self) {
match self.state {
State::Uninitialized => {
debug!(
"Signer is uninitialized. Waiting for aggregate public key from stacks node..."
);
}
State::Idle => {
if let Some(command) = self.commands.pop_front() {
while !self.execute_command(&command) {
Expand Down Expand Up @@ -205,26 +233,29 @@ impl From<&Config> for RunLoop<FrostCoordinator<v2::Aggregator>> {
.iter()
.map(|i| i - 1) // SigningRound::new (unlike SigningRound::from) doesn't do this
.collect::<Vec<u32>>();
let coordinator = FrostCoordinator::new(
total_signers,
total_keys,
threshold,
config.message_private_key,
);
let signing_round = SigningRound::new(
threshold,
total_signers,
total_keys,
config.signer_id,
key_ids,
config.message_private_key,
config.signer_ids_public_keys.clone(),
);
let stacks_client = StacksClient::from(config);
RunLoop {
event_timeout: config.event_timeout,
coordinator: FrostCoordinator::new(
total_signers,
total_keys,
threshold,
config.message_private_key,
),
signing_round: SigningRound::new(
threshold,
total_signers,
total_keys,
config.signer_id,
key_ids,
config.message_private_key,
config.signer_ids_public_keys.clone(),
),
stacks_client: StacksClient::from(config),
coordinator,
signing_round,
stacks_client,
commands: VecDeque::new(),
state: State::Idle,
state: State::Uninitialized,
}
}
}
Expand All @@ -244,10 +275,19 @@ impl<C: Coordinatable> SignerRunLoop<Vec<OperationResult>, RunLoopCommand> for R
cmd: Option<RunLoopCommand>,
res: Sender<Vec<OperationResult>>,
) -> Option<Vec<OperationResult>> {
info!(
"Running one pass for signer ID# {}. Current state: {:?}",
self.signing_round.signer_id, self.state
);
if let Some(command) = cmd {
self.commands.push_back(command);
}
// First process any arrived events
if self.state == State::Uninitialized {
let request_fn = || self.initialize().map_err(backoff::Error::transient);
retry_with_exponential_backoff(request_fn)
.expect("Failed to connect to initialize due to timeout. Stacks node may be down.");
}
// Process any arrived events
if let Some(event) = event {
let (outbound_messages, operation_results) = self.process_event(&event);
debug!(
Expand All @@ -257,7 +297,7 @@ impl<C: Coordinatable> SignerRunLoop<Vec<OperationResult>, RunLoopCommand> for R
for msg in outbound_messages {
let ack = self
.stacks_client
.send_message(self.signing_round.signer_id, msg);
.send_message_with_retry(self.signing_round.signer_id, msg);
if let Ok(ack) = ack {
debug!("ACK: {:?}", ack);
} else {
Expand Down
Loading
Loading