Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add chain_id to signer config #5314

Merged
merged 1 commit into from
Oct 15, 2024
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
1 change: 1 addition & 0 deletions stacks-signer/src/client/stackerdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ mod tests {
Some(100_000),
None,
Some(9000),
None,
);
let config = GlobalConfig::load_from_str(&signer_config[0]).unwrap();
let signer_config = generate_signer_config(&config, 5);
Expand Down
28 changes: 19 additions & 9 deletions stacks-signer/src/client/stacks_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ use serde::Deserialize;
use serde_json::json;
use slog::{slog_debug, slog_warn};
use stacks_common::codec::StacksMessageCodec;
use stacks_common::consts::{CHAIN_ID_MAINNET, CHAIN_ID_TESTNET};
use stacks_common::consts::CHAIN_ID_MAINNET;
use stacks_common::types::chainstate::{
ConsensusHash, StacksAddress, StacksPrivateKey, StacksPublicKey,
};
Expand Down Expand Up @@ -99,7 +99,7 @@ impl From<&GlobalConfig> for StacksClient {
stacks_address: config.stacks_address,
http_origin: format!("http://{}", config.node_host),
tx_version: config.network.to_transaction_version(),
chain_id: config.network.to_chain_id(),
chain_id: config.to_chain_id(),
stacks_node_client: reqwest::blocking::Client::new(),
mainnet: config.network.is_mainnet(),
auth_password: config.auth_password.clone(),
Expand All @@ -114,18 +114,14 @@ impl StacksClient {
node_host: String,
auth_password: String,
mainnet: bool,
chain_id: u32,
) -> Self {
let pubkey = StacksPublicKey::from_private(&stacks_private_key);
let tx_version = if mainnet {
TransactionVersion::Mainnet
} else {
TransactionVersion::Testnet
};
let chain_id = if mainnet {
CHAIN_ID_MAINNET
} else {
CHAIN_ID_TESTNET
};
let stacks_address = StacksAddress::p2pkh(mainnet, &pubkey);
Self {
stacks_private_key,
Expand All @@ -145,7 +141,13 @@ impl StacksClient {
node_host: String,
auth_password: String,
) -> Result<Self, ClientError> {
let mut stacks_client = Self::new(stacks_private_key, node_host, auth_password, true);
let mut stacks_client = Self::new(
stacks_private_key,
node_host,
auth_password,
true,
CHAIN_ID_MAINNET,
);
let pubkey = StacksPublicKey::from_private(&stacks_private_key);
let info = stacks_client.get_peer_info()?;
if info.network_id == CHAIN_ID_MAINNET {
Expand All @@ -154,7 +156,7 @@ impl StacksClient {
stacks_client.tx_version = TransactionVersion::Mainnet;
} else {
stacks_client.mainnet = false;
stacks_client.chain_id = CHAIN_ID_TESTNET;
stacks_client.chain_id = info.network_id;
stacks_client.tx_version = TransactionVersion::Testnet;
}
stacks_client.stacks_address = StacksAddress::p2pkh(stacks_client.mainnet, &pubkey);
Expand Down Expand Up @@ -1219,4 +1221,12 @@ mod tests {
write_response(mock.server, response.as_bytes());
assert_eq!(h.join().unwrap().unwrap(), reward_cycle as u128);
}

#[test]
fn get_chain_id_from_config() {
let mock = MockServerClient::from_config(
GlobalConfig::load_from_file("./src/tests/conf/signer-custom-chain-id.toml").unwrap(),
);
assert_eq!(mock.client.chain_id, 0x80000100);
}
}
71 changes: 63 additions & 8 deletions stacks-signer/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,6 @@ impl std::fmt::Display for Network {
}

impl Network {
/// Converts a Network enum variant to a corresponding chain id
pub const fn to_chain_id(&self) -> u32 {
match self {
Self::Mainnet => CHAIN_ID_MAINNET,
Self::Testnet | Self::Mocknet => CHAIN_ID_TESTNET,
}
}

/// Convert a Network enum variant to a corresponding address version
pub const fn to_address_version(&self) -> u8 {
match self {
Expand Down Expand Up @@ -163,6 +155,8 @@ pub struct GlobalConfig {
pub first_proposal_burn_block_timing: Duration,
/// How much time to wait for a miner to propose a block following a sortition
pub block_proposal_timeout: Duration,
/// An optional custom Chain ID
chain_id: Option<u32>,
}

/// Internal struct for loading up the config file
Expand Down Expand Up @@ -190,6 +184,8 @@ struct RawConfigFile {
pub first_proposal_burn_block_timing_secs: Option<u64>,
/// How much time to wait for a miner to propose a block following a sortition in milliseconds
pub block_proposal_timeout_ms: Option<u64>,
/// An optional custom Chain ID
pub chain_id: Option<u32>,
}

impl RawConfigFile {
Expand Down Expand Up @@ -278,6 +274,7 @@ impl TryFrom<RawConfigFile> for GlobalConfig {
metrics_endpoint,
first_proposal_burn_block_timing,
block_proposal_timeout,
chain_id: raw_data.chain_id,
})
}
}
Expand Down Expand Up @@ -308,13 +305,15 @@ impl GlobalConfig {
Some(endpoint) => endpoint.to_string(),
None => "None".to_string(),
};
let chain_id = format!("{:x}", self.to_chain_id());
format!(
r#"
Stacks node host: {node_host}
Signer endpoint: {endpoint}
Stacks address: {stacks_address}
Public key: {public_key}
Network: {network}
Chain ID: 0x{chain_id}
Database path: {db_path}
Metrics endpoint: {metrics_endpoint}
"#,
Expand All @@ -329,6 +328,14 @@ Metrics endpoint: {metrics_endpoint}
metrics_endpoint = metrics_endpoint,
)
}

/// Get the chain ID for the network
pub fn to_chain_id(&self) -> u32 {
self.chain_id.unwrap_or_else(|| match self.network {
Network::Mainnet => CHAIN_ID_MAINNET,
Network::Testnet | Network::Mocknet => CHAIN_ID_TESTNET,
})
}
}

impl Display for GlobalConfig {
Expand Down Expand Up @@ -356,6 +363,7 @@ pub fn build_signer_config_tomls(
max_tx_fee_ustx: Option<u64>,
tx_fee_ustx: Option<u64>,
mut metrics_port_start: Option<usize>,
chain_id: Option<u32>,
) -> Vec<String> {
let mut signer_config_tomls = vec![];

Expand Down Expand Up @@ -421,6 +429,15 @@ metrics_endpoint = "{metrics_endpoint}"
metrics_port_start = Some(metrics_port + 1);
}

if let Some(chain_id) = chain_id {
signer_config_toml = format!(
r#"
{signer_config_toml}
chain_id = {chain_id}
"#
)
}

signer_config_tomls.push(signer_config_toml);
}

Expand Down Expand Up @@ -453,13 +470,16 @@ mod tests {
None,
None,
Some(4000),
None,
);

let config =
RawConfigFile::load_from_str(&config_tomls[0]).expect("Failed to parse config file");

assert_eq!(config.auth_password, "melon");
assert_eq!(config.metrics_endpoint, Some("localhost:4000".to_string()));
let global_config = GlobalConfig::try_from(config).unwrap();
assert_eq!(global_config.to_chain_id(), CHAIN_ID_TESTNET);
}

#[test]
Expand All @@ -473,8 +493,10 @@ Signer endpoint: 127.0.0.1:30000
Stacks address: ST3FPN8KBZ3YPBP0ZJGAAHTVFMQDTJCR5QPS7VTNJ
Public key: 03bc489f27da3701d9f9e577c88de5567cf4023111b7577042d55cde4d823a3505
Network: testnet
Chain ID: 0x80000000
Database path: :memory:
Metrics endpoint: 0.0.0.0:9090
Chain ID: 2147483648
"#;

let expected_str_v6 = r#"
Expand All @@ -483,6 +505,7 @@ Signer endpoint: [::1]:30000
Stacks address: ST3FPN8KBZ3YPBP0ZJGAAHTVFMQDTJCR5QPS7VTNJ
Public key: 03bc489f27da3701d9f9e577c88de5567cf4023111b7577042d55cde4d823a3505
Network: testnet
Chain ID: 0x80000000
Database path: :memory:
Metrics endpoint: 0.0.0.0:9090
"#;
Expand Down Expand Up @@ -531,5 +554,37 @@ db_path = ":memory:"
);
let config = GlobalConfig::load_from_str(&config_toml).unwrap();
assert_eq!(config.stacks_address.to_string(), expected_addr);
assert_eq!(config.to_chain_id(), CHAIN_ID_MAINNET);
}

#[test]
fn test_custom_chain_id() {
let pk = StacksPrivateKey::from_hex(
"eb05c83546fdd2c79f10f5ad5434a90dd28f7e3acb7c092157aa1bc3656b012c01",
)
.unwrap();

let node_host = "localhost";
let network = Network::Testnet;
let password = "melon";
let config_tomls = build_signer_config_tomls(
&[pk],
node_host,
None,
&network,
password,
rand::random(),
3000,
None,
None,
Some(4000),
Some(0x80000100),
);

let config =
RawConfigFile::load_from_str(&config_tomls[0]).expect("Failed to parse config file");
assert_eq!(config.chain_id, Some(0x80000100));
let global_config = GlobalConfig::try_from(config).unwrap();
assert_eq!(global_config.to_chain_id(), 0x80000100);
}
}
2 changes: 1 addition & 1 deletion stacks-signer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ fn handle_generate_stacking_signature(
&private_key, //
args.reward_cycle.into(),
args.method.topic(),
config.network.to_chain_id(),
config.to_chain_id(),
args.period.into(),
args.max_amount,
args.auth_id,
Expand Down
2 changes: 2 additions & 0 deletions stacks-signer/src/tests/chainstate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use clarity::util::vrf::VRFProof;
use libsigner::BlockProposal;
use slog::slog_info;
use stacks_common::bitvec::BitVec;
use stacks_common::consts::CHAIN_ID_TESTNET;
use stacks_common::info;
use stacks_common::types::chainstate::{
ConsensusHash, StacksBlockId, StacksPrivateKey, StacksPublicKey, TrieHash,
Expand Down Expand Up @@ -96,6 +97,7 @@ fn setup_test_environment(
SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 10000).to_string(),
"FOO".into(),
false,
CHAIN_ID_TESTNET,
);

let signer_db_dir = "/tmp/stacks-node-tests/signer-units/";
Expand Down
7 changes: 7 additions & 0 deletions stacks-signer/src/tests/conf/signer-custom-chain-id.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
stacks_private_key = "126e916e77359ccf521e168feea1fcb9626c59dc375cae00c7464303381c7dff01"
node_host = "127.0.0.1:20444"
endpoint = "localhost:30001"
network = "testnet"
auth_password = "12345"
db_path = ":memory:"
chain_id = 0x80000100
3 changes: 2 additions & 1 deletion testnet/stacks-node/src/tests/nakamoto_integrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ use stacks::util_lib::signed_structured_data::pox4::{
use stacks_common::address::AddressHashMode;
use stacks_common::bitvec::BitVec;
use stacks_common::codec::StacksMessageCodec;
use stacks_common::consts::STACKS_EPOCH_MAX;
use stacks_common::consts::{CHAIN_ID_TESTNET, STACKS_EPOCH_MAX};
use stacks_common::types::chainstate::{
BlockHeaderHash, BurnchainHeaderHash, StacksAddress, StacksPrivateKey, StacksPublicKey,
TrieHash,
Expand Down Expand Up @@ -6400,6 +6400,7 @@ fn signer_chainstate() {
.clone()
.unwrap_or("".into()),
false,
CHAIN_ID_TESTNET,
);

wait_for_first_naka_block_commit(60, &commits_submitted);
Expand Down
1 change: 1 addition & 0 deletions testnet/stacks-node/src/tests/signer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SignerTest<Sp
Some(100_000),
None,
Some(9000),
None,
)
.into_iter()
.map(|toml| {
Expand Down
1 change: 1 addition & 0 deletions testnet/stacks-node/src/tests/signer/v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2990,6 +2990,7 @@ fn signer_set_rollover() {
Some(100_000),
None,
Some(9000 + num_signers),
None,
);

let new_spawned_signers: Vec<_> = (0..new_num_signers)
Expand Down