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

Allow forc deploy to submit transaction without waiting for commit confirmation #6294

Merged
merged 35 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
72d7c3a
feat(submit-only): add command to submit tx without wait execution
luisburigo Jul 22, 2024
38f76df
feat(submit-only): add command to submit tx without wait execution
luisburigo Jul 23, 2024
ebf0b27
feat(submit-only): add logs on submit the tx
luisburigo Jul 24, 2024
37a8254
Merge branch 'master' into lb/feat/deploy-submit-only
luisburigo Jul 24, 2024
87a0e27
feat(submit-only): correct typos in command and comments
luisburigo Jul 25, 2024
a6eaf1f
feat(submit-only): move deployment logs inside the method
luisburigo Jul 25, 2024
84a5480
Merge remote-tracking branch 'origin/lb/feat/deploy-submit-only' into…
luisburigo Jul 25, 2024
f1d1a48
feat(submit-only): remove package name from method and retrieve it fr…
luisburigo Jul 25, 2024
4e26ebd
Merge branch 'master' into lb/feat/deploy-submit-only
luisburigo Jul 25, 2024
adcc3df
feat(submit-only): move deployment logs and fix merge
luisburigo Jul 26, 2024
224b80c
Merge branch 'master' into lb/feat/deploy-submit-only
luisburigo Jul 26, 2024
27a5ac3
Merge branch 'master' into lb/feat/deploy-submit-only
luisburigo Jul 26, 2024
ebc78a8
feat(submit-only): add description in method
luisburigo Jul 30, 2024
5eb47e6
Merge remote-tracking branch 'origin/lb/feat/deploy-submit-only' into…
luisburigo Jul 30, 2024
b3f42fc
Merge branch 'master' into lb/feat/deploy-submit-only
luisburigo Jul 30, 2024
2b512b6
Merge branch 'master' into lb/feat/deploy-submit-only
luisburigo Jul 31, 2024
59d36c5
Merge branch 'master' into lb/feat/deploy-submit-only
luisburigo Aug 1, 2024
8e0f871
Merge branch 'master' into lb/feat/deploy-submit-only
sdankel Aug 1, 2024
57becdd
feat(submit-only): add doc
luisburigo Aug 5, 2024
7d19a7d
Merge remote-tracking branch 'origin/lb/feat/deploy-submit-only' into…
luisburigo Aug 5, 2024
a0f51e6
Merge branch 'master' into lb/feat/deploy-submit-only
sdankel Aug 5, 2024
31bdac9
feat(submit-only): change doc to add use case of submit-only
luisburigo Aug 6, 2024
6cb4482
Merge remote-tracking branch 'origin/lb/feat/deploy-submit-only' into…
luisburigo Aug 6, 2024
a289294
feat(submit-only): change doc to add section of delayed transactions
luisburigo Aug 6, 2024
b320488
feat(submit-only): add blank lines around headings for linter compliance
luisburigo Aug 6, 2024
1251245
Merge branch 'master' into lb/feat/deploy-submit-only
luisburigo Aug 7, 2024
a6f668d
Merge remote-tracking branch 'origin/master' into lb/feat/deploy-subm…
luisburigo Aug 7, 2024
7ee9bf1
Merge branch 'master' into lb/feat/deploy-submit-only
luisburigo Aug 7, 2024
559c616
Merge branch 'master' into lb/feat/deploy-submit-only
luisburigo Aug 7, 2024
0065c39
Merge branch 'master' into lb/feat/deploy-submit-only
K1-R1 Aug 8, 2024
6e70c8a
feat(submit-only): add multisig to spell check
luisburigo Aug 8, 2024
4d36d0d
Merge remote-tracking branch 'origin/lb/feat/deploy-submit-only' into…
luisburigo Aug 8, 2024
7f29ca1
Merge branch 'master' into lb/feat/deploy-submit-only
K1-R1 Aug 9, 2024
fcf2029
feat(submit-only): change expected contract id in submit only test
luisburigo Aug 9, 2024
85a3f61
Merge branch 'master' into lb/feat/deploy-submit-only
luisburigo Aug 9, 2024
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
3 changes: 3 additions & 0 deletions forc-plugins/forc-client/src/cmd/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ pub struct Command {
/// Deprecated in favor of `--default-signer`.
#[clap(long)]
pub unsigned: bool,
/// Submit the deployment transaction without wait execution.
luisburigo marked this conversation as resolved.
Show resolved Hide resolved
#[clap(long)]
pub submit_only: bool,
luisburigo marked this conversation as resolved.
Show resolved Hide resolved
/// Set the key to be used for signing.
pub signing_key: Option<SecretKey>,
/// Sign the deployment transaction manually.
Expand Down
143 changes: 96 additions & 47 deletions forc-plugins/forc-client/src/op/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub struct DeploymentArtifact {
chain_id: ChainId,
contract_id: String,
deployment_size: usize,
deployed_block_height: u32,
deployed_block_height: Option<u32>,
}

impl DeploymentArtifact {
Expand Down Expand Up @@ -275,66 +275,98 @@ pub async fn deploy_pkg(
let tx = Transaction::from(tx);

let chain_id = client.chain_info().await?.consensus_parameters.chain_id();
let pkg_name = manifest.project_name();
luisburigo marked this conversation as resolved.
Show resolved Hide resolved

let deployment_request = client.submit_and_await_commit(&tx).map(|res| match res {
Ok(logs) => match logs {
TransactionStatus::Submitted { .. } => {
bail!("contract {} deployment timed out", &contract_id);
}
TransactionStatus::Success { block_height, .. } => {
let pkg_name = manifest.project_name();
// if just submitting the transaction, don't wait for the deployment to complete
luisburigo marked this conversation as resolved.
Show resolved Hide resolved
let contract_id: ContractId = if command.submit_only {
match client.submit(&tx).await {
Ok(transaction_id) => {
info!("\n\nContract {pkg_name} Deployed!");

info!("\nNetwork: {node_url}");
info!("Contract ID: 0x{contract_id}");
info!("Deployed in block {}", &block_height);

// Create a deployment artifact.
let deployment_size = bytecode.len();
let deployment_artifact = DeploymentArtifact {
transaction_id: format!("0x{}", tx.id(&chain_id)),
salt: format!("0x{}", salt),
network_endpoint: node_url.to_string(),
chain_id,
contract_id: format!("0x{}", contract_id),
deployment_size,
deployed_block_height: *block_height,
};

let output_dir = command
.pkg
.output_directory
.as_ref()
.map(PathBuf::from)
.unwrap_or_else(|| default_output_directory(manifest.dir()))
.join("deployments");
deployment_artifact.to_file(&output_dir, pkg_name, contract_id)?;

Ok(contract_id)
create_deployment_artifact(
DeploymentArtifact {
transaction_id: format!("0x{}", transaction_id),
salt: format!("0x{}", salt),
network_endpoint: node_url.to_string(),
chain_id,
contract_id: format!("0x{}", contract_id),
deployment_size: bytecode.len(),
deployed_block_height: None,
},
command,
manifest,
pkg_name,
contract_id,
)?;

contract_id
}
e => {
Err(e) => {
bail!(
"contract {} failed to deploy due to an error: {:?}",
&contract_id,
e
)
}
},
Err(e) => bail!("{e}"),
});

// submit contract deployment with a timeout
let contract_id = tokio::time::timeout(
Duration::from_millis(TX_SUBMIT_TIMEOUT_MS),
deployment_request,
)
.await
.with_context(|| {
format!(
"Timed out waiting for contract {} to deploy. The transaction may have been dropped.",
&contract_id
}
} else {
let deployment_request = client.submit_and_await_commit(&tx).map(|res| match res {
Ok(logs) => match logs {
TransactionStatus::Submitted { .. } => {
bail!("contract {} deployment timed out", &contract_id);
}
TransactionStatus::Success { block_height, .. } => {
info!("\n\nContract {pkg_name} Deployed!");

info!("\nNetwork: {node_url}");
info!("Contract ID: 0x{contract_id}");
info!("Deployed in block {}", &block_height);

luisburigo marked this conversation as resolved.
Show resolved Hide resolved
// Create a deployment artifact.
create_deployment_artifact(
DeploymentArtifact {
transaction_id: format!("0x{}", tx.id(&chain_id)),
salt: format!("0x{}", salt),
network_endpoint: node_url.to_string(),
chain_id,
contract_id: format!("0x{}", contract_id),
deployment_size: bytecode.len(),
deployed_block_height: Some(*block_height),
},
command,
manifest,
pkg_name,
contract_id,
)?;

Ok(contract_id)
}
e => {
bail!(
"contract {} failed to deploy due to an error: {:?}",
&contract_id,
e
)
}
},
Err(e) => bail!("{e}"),
});
tokio::time::timeout(
Duration::from_millis(TX_SUBMIT_TIMEOUT_MS),
deployment_request,
)
})??;
.await
.with_context(|| {
format!(
"Timed out waiting for contract {} to deploy. The transaction may have been dropped.",
&contract_id
)
})??
};

Ok(DeployedContract { id: contract_id })
}

Expand Down Expand Up @@ -379,6 +411,23 @@ fn build_opts_from_cmd(cmd: &cmd::Deploy) -> pkg::BuildOpts {
}
}

fn create_deployment_artifact(
luisburigo marked this conversation as resolved.
Show resolved Hide resolved
deployment_artifact: DeploymentArtifact,
cmd: &cmd::Deploy,
manifest: &PackageManifestFile,
pkg_name: &str,
contract_id: ContractId,
) -> Result<()> {
let output_dir = cmd
.pkg
.output_directory
.as_ref()
.map(PathBuf::from)
.unwrap_or_else(|| default_output_directory(manifest.dir()))
.join("deployments");
deployment_artifact.to_file(&output_dir, pkg_name, contract_id)
}

#[cfg(test)]
mod test {
use super::*;
Expand Down
40 changes: 40 additions & 0 deletions forc-plugins/forc-client/tests/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,43 @@ async fn simple_deploy() {

assert_eq!(contract_ids, expected)
}

#[tokio::test]
async fn deploy_submit_only() {
let (mut node, port) = run_node();
let tmp_dir = tempdir().unwrap();
let project_dir = test_data_path().join("standalone_contract");
copy_dir(&project_dir, tmp_dir.path()).unwrap();
patch_manifest_file_with_path_std(tmp_dir.path()).unwrap();

let pkg = Pkg {
path: Some(tmp_dir.path().display().to_string()),
..Default::default()
};

let node_url = format!("http://127.0.0.1:{}/v1/graphql", port);

let target = NodeTarget {
node_url: Some(node_url),
target: None,
testnet: false,
};
let cmd = cmd::Deploy {
pkg,
salt: Some(vec![format!("{}", Salt::default())]),
node: target,
default_signer: true,
submit_only: true,
..Default::default()
};
let contract_ids = deploy(cmd).await.unwrap();
node.kill().unwrap();
let expected = vec![DeployedContract {
id: ContractId::from_str(
"822c8d3672471f64f14f326447793c7377b6e430122db23b622880ccbd8a33ef",
)
.unwrap(),
}];

assert_eq!(contract_ids, expected)
}
Loading