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

fix: polish deployment ux #1286

Merged
merged 4 commits into from
Dec 12, 2023
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
8 changes: 5 additions & 3 deletions components/clarinet-cli/src/deployments/ui/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ where
TransactionStatus::Encoded(_, _) => {
("🟦", "Transaction encoded and queued".to_string())
}
TransactionStatus::Broadcasted(_) => ("🟨", "Transaction broadcasted".to_string()),
TransactionStatus::Broadcasted(_, txid) => {
("🟨", format!("Transaction broadcasted (txid: {})", txid))
}
TransactionStatus::Confirmed => ("🟩", "Transaction confirmed".to_string()),
TransactionStatus::Error(message) => ("🟥", message.to_string()),
};
Expand All @@ -42,8 +44,8 @@ where
.style(Style::default().fg(Color::White))
.widths(&[
Constraint::Length(3),
Constraint::Length(80),
Constraint::Length(120),
Constraint::Length(90),
Constraint::Length(110),
]);
f.render_widget(t, area);
}
12 changes: 9 additions & 3 deletions components/clarinet-cli/src/frontend/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,13 +799,19 @@ pub fn main() {
let network_moved = network.clone();
std::thread::spawn(move || {
let manifest = manifest_moved;
let network_manifest = NetworkManifest::from_project_manifest_location(
let res = NetworkManifest::from_project_manifest_location(
&manifest.location,
&network_moved.get_networks(),
Some(&manifest.project.cache_location),
None,
)
.expect("unable to load network manifest");
);
let network_manifest = match res {
Ok(network_manifest) => network_manifest,
Err(e) => {
let _ = event_tx.send(DeploymentEvent::Interrupted(e));
return;
}
};
apply_on_chain_deployment(
network_manifest,
deployment,
Expand Down
125 changes: 69 additions & 56 deletions components/clarinet-deployments/src/onchain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ pub fn encode_contract_publish(
pub enum TransactionStatus {
Queued,
Encoded(StacksTransaction, TransactionCheck),
Broadcasted(TransactionCheck),
Broadcasted(TransactionCheck, String),
Confirmed,
Error(String),
}
Expand All @@ -218,8 +218,7 @@ pub struct TransactionTracker {
pub enum TransactionCheck {
NonceCheck(StandardPrincipalData, u64),
ContractPublish(StandardPrincipalData, ContractName),
// TODO(lgalabru): Handle Bitcoin checks
// BtcTransfer(),
BtcTransfer,
}

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -403,15 +402,7 @@ pub fn apply_on_chain_deployment(
}

for batch_spec in deployment.plan.batches.iter() {
let epoch = match batch_spec.epoch {
Some(epoch) => {
if network != StacksNetwork::Devnet {
println!("warning: 'epoch' specified for a deployment batch is ignored when applying a deployment plan. This field should only be specified for deployments plans used to launch a devnet with 'clarinet devnet start'.");
}
epoch
}
None => default_epoch,
};
let epoch = batch_spec.epoch.unwrap_or(default_epoch);
let mut batch = Vec::new();
for transaction in batch_spec.transactions.iter() {
let tracker = match transaction {
Expand Down Expand Up @@ -823,7 +814,7 @@ pub fn apply_on_chain_deployment(
};
match stacks_rpc.post_transaction(&transaction) {
Ok(res) => {
tracker.status = TransactionStatus::Broadcasted(check);
tracker.status = TransactionStatus::Broadcasted(check, res.txid.clone());

let _ = deployment_event_tx
.send(DeploymentEvent::TransactionUpdate(tracker.clone()));
Expand All @@ -840,68 +831,90 @@ pub fn apply_on_chain_deployment(
}
};
}
let mut last_stacks_chain_check_at_height = 0;
let mut last_bitcoin_chain_check_at_height = 0;

loop {
let (burn_block_height, stacks_tip_height) = match stacks_rpc.get_info() {
let (bitcoin_tip_height, stacks_tip_height) = match stacks_rpc.get_info() {
Ok(info) => (info.burn_block_height, info.stacks_tip_height),
_ => {
std::thread::sleep(std::time::Duration::from_secs(delay_between_checks));
continue;
}
};

// If no block has been mined since `delay_between_checks`,
// avoid flooding the stacks-node with status update requests.
if burn_block_height <= current_bitcoin_block_height {
std::thread::sleep(std::time::Duration::from_secs(delay_between_checks));
continue;
}

current_bitcoin_block_height = burn_block_height;
current_block_height = stacks_tip_height;

let mut keep_looping = false;

for (_txid, tracker) in ongoing_batch.iter_mut() {
match &tracker.status {
TransactionStatus::Broadcasted(TransactionCheck::ContractPublish(
deployer,
contract_name,
)) => {
let deployer_address = deployer.to_address();
let res = stacks_rpc.get_contract_source(&deployer_address, contract_name);
match res {
Ok(_contract) => {
tracker.status = TransactionStatus::Confirmed;
let _ = deployment_event_tx
.send(DeploymentEvent::TransactionUpdate(tracker.clone()));
// Handle Stacks releated checks
if stacks_tip_height > last_stacks_chain_check_at_height {
for (_, tracker) in ongoing_batch.iter_mut() {
let TransactionStatus::Broadcasted(brodcasting_status, _) = &tracker.status
else {
continue;
};
lgalabru marked this conversation as resolved.
Show resolved Hide resolved

match &brodcasting_status {
TransactionCheck::ContractPublish(deployer, contract_name) => {
let deployer_address = deployer.to_address();
let res =
stacks_rpc.get_contract_source(&deployer_address, contract_name);
match res {
Ok(_contract) => {
tracker.status = TransactionStatus::Confirmed;
let _ = deployment_event_tx
.send(DeploymentEvent::TransactionUpdate(tracker.clone()));
}
Err(_e) => {
keep_looping = true;
break;
}
}
Err(_e) => {
keep_looping = true;
break;
}
TransactionCheck::NonceCheck(tx_sender, expected_nonce) => {
let tx_sender_address = tx_sender.to_address();
let res = stacks_rpc.get_nonce(&tx_sender_address);
if let Ok(current_nonce) = res {
if current_nonce.gt(expected_nonce) {
tracker.status = TransactionStatus::Confirmed;
let _ = deployment_event_tx
.send(DeploymentEvent::TransactionUpdate(tracker.clone()));
} else {
keep_looping = true;
break;
}
}
}
_ => {}
}
TransactionStatus::Broadcasted(TransactionCheck::NonceCheck(
tx_sender,
expected_nonce,
)) => {
let tx_sender_address = tx_sender.to_address();
let res = stacks_rpc.get_nonce(&tx_sender_address);
if let Ok(current_nonce) = res {
if current_nonce.gt(expected_nonce) {
tracker.status = TransactionStatus::Confirmed;
let _ = deployment_event_tx
.send(DeploymentEvent::TransactionUpdate(tracker.clone()));
} else {
keep_looping = true;
break;
}
}
} else {
std::thread::sleep(std::time::Duration::from_secs(delay_between_checks));
continue;
}

// Handle Bitcoin releated checks
if bitcoin_tip_height > last_bitcoin_chain_check_at_height {
for (_, tracker) in ongoing_batch.iter_mut() {
let TransactionStatus::Broadcasted(brodcasting_status, _) = &tracker.status
else {
continue;
};
match &brodcasting_status {
TransactionCheck::BtcTransfer => {
// TODO
}
TransactionCheck::ContractPublish(_, _)
| TransactionCheck::NonceCheck(_, _) => {}
}
_ => {}
}
} else {
std::thread::sleep(std::time::Duration::from_secs(delay_between_checks));
continue;
}

last_stacks_chain_check_at_height = stacks_tip_height;
last_bitcoin_chain_check_at_height = bitcoin_tip_height;

if !keep_looping {
break;
}
Expand Down
4 changes: 2 additions & 2 deletions components/clarinet-files/src/network_manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,8 +417,8 @@ impl NetworkManifest {
Ok(result) => result.to_string(),
Err(e) => {
return Err(format!(
"mnemonic for wallet '{}' invalid: {}",
account_name, e
"mnemonic (located in ./settings/{:?}.toml) for deploying address is invalid: {}",
networks.1 , e
));
}
}
Expand Down
Loading