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

Add beta-4 target to forc, refactor with tests, and UX improvements #4991

Merged
merged 29 commits into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
023e2c8
feat: derive first account with forc-deploy after creating a wallet
kayagokalp Aug 17, 2023
354409b
feat: point empty accounts to beta-4 faucet
kayagokalp Aug 17, 2023
551c4ac
Merge branch 'master' into kayagokalp/4862
sdankel Aug 17, 2023
88b4bf5
feat: add beta-4 target, and point --testnet to beta-4 network
kayagokalp Aug 17, 2023
28c9bbe
docs: update docs to point out --testnet flag
kayagokalp Aug 17, 2023
362110b
Apply suggestions from code review
kayagokalp Aug 17, 2023
b354148
fix: check if --node-url is present
kayagokalp Aug 17, 2023
21360da
Merge branch 'master' into kayagokalp/4973
kayagokalp Aug 18, 2023
07d7bf3
chore: clean fromstr and display impls, change LATEST to Local
kayagokalp Aug 18, 2023
8768f1f
Update docs/book/src/forc/plugins/forc_client/index.md
kayagokalp Aug 18, 2023
7424c60
refactor for readability
sdankel Aug 18, 2023
794160d
Add unit tests
sdankel Aug 18, 2023
7f2c0ad
Use defaults from node
sdankel Aug 21, 2023
73b2629
Clean up
sdankel Aug 22, 2023
8e30c01
Update unit tests
sdankel Aug 22, 2023
5d36d09
Update docs
sdankel Aug 22, 2023
3bf82f0
restore default in forc-tx
sdankel Aug 22, 2023
810620a
Merge branch 'master' into sophie/4973refactor
sdankel Aug 22, 2023
7e1fb18
Merge branch 'master' into sophie/4973refactor
sdankel Aug 22, 2023
0410232
Merge branch 'master' into sophie/4973refactor
JoshuaBatty Aug 22, 2023
134b203
set default to 0
sdankel Aug 22, 2023
6a81c08
gas values optional
sdankel Aug 22, 2023
1ceb387
update help text
sdankel Aug 22, 2023
6f3105f
Merge branch 'master' into sophie/4973refactor
sdankel Aug 22, 2023
51a4df0
update test harness runcmd
sdankel Aug 22, 2023
5a0121b
update comment
sdankel Aug 22, 2023
03c4d35
Merge branch 'master' into sophie/4973refactor
sdankel Aug 23, 2023
b48c9bd
Merge branch 'master' into sophie/4973refactor
kayagokalp Aug 23, 2023
0b4ec11
Merge branch 'master' into sophie/4973refactor
kayagokalp Aug 23, 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
16 changes: 11 additions & 5 deletions docs/book/src/forc/plugins/forc_client/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,26 @@ By default `--default-signer` flag would sign your transactions with the followi

## Interacting with the testnet

While using `forc-deploy` or `forc-run` to interact with the testnet you need to pass the testnet end point with `--node-url`
To interact with the latest testnet, use the `--testnet` flag. When this flag is passed, transactions created by `forc-deploy` will be sent to the `beta-4` testnet.

```sh
forc-deploy --node-url https://beta-3.fuel.network/graphql
forc-deploy --testnet
```

Since deploying and running projects on the testnet cost gas, you will need coins to pay for them. You can get some using the [testnet faucet](https://faucet-beta-3.fuel.network/).
It is also possible to pass the exact node url while using `forc-deploy` or `forc-run` which can be done using `--node-url` flag.

Also the default value of the "gas price" parameter is 0 for both `forc-deploy` and `forc-run`. Without changing it you will get an error complaining about gas price being too low. While using testnet you can pass `--gas-price 1` to overcome this issue. So a complete command for deploying to the testnet would look like:
```sh
forc-deploy --node-url https://beta-3.fuel.network
```

Another alternative is the `--target` option, which provides useful aliases to all targets. For example if you want to deploy to `beta-3` you can use:

```sh
forc-deploy --node-url https://beta-3.fuel.network/graphql --gas-price 1
forc-deploy --target beta-3
```

Since deploying and running projects on the testnet cost gas, you will need coins to pay for them. You can get some using the [testnet faucet](https://faucet-beta-4.fuel.network/).

## Deployment Artifacts

forc-deploy saves the details of each deployment in the `out/deployments` folder within the project's root directory. Below is an example of a deployment artifact:
Expand Down
6 changes: 3 additions & 3 deletions forc-pkg/src/manifest.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::pkg::{manifest_file_missing, parsing_failed, wrong_program_type};
use anyhow::{anyhow, bail, Context, Result};
use forc_tracing::println_yellow_err;
use forc_tracing::println_warning;
use forc_util::{find_nested_manifest_dir, find_parent_manifest_dir, validate_name};
use serde::{Deserialize, Serialize};
use std::{
Expand Down Expand Up @@ -508,7 +508,7 @@ impl PackageManifest {
})
.map_err(|e| anyhow!("failed to parse manifest: {}.", e))?;
for warning in warnings {
println_yellow_err(&warning);
println_warning(&warning);
}
manifest.implicitly_include_std_if_missing();
manifest.implicitly_include_default_build_profiles_if_missing();
Expand Down Expand Up @@ -930,7 +930,7 @@ impl WorkspaceManifest {
})
.map_err(|e| anyhow!("failed to parse manifest: {}.", e))?;
for warning in warnings {
println_yellow_err(&warning);
println_warning(&warning);
}
Ok(manifest)
}
Expand Down
4 changes: 2 additions & 2 deletions forc-plugins/forc-client/src/bin/deploy.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use clap::Parser;
use forc_tracing::init_tracing_subscriber;
use forc_tracing::{init_tracing_subscriber, println_error};

#[tokio::main]
async fn main() {
init_tracing_subscriber(Default::default());
let command = forc_client::cmd::Deploy::parse();
if let Err(err) = forc_client::op::deploy(command).await {
tracing::error!("Error: {:?}", err);
println_error(&format!("{}", err));
std::process::exit(1);
}
}
4 changes: 2 additions & 2 deletions forc-plugins/forc-client/src/bin/run.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use clap::Parser;
use forc_tracing::init_tracing_subscriber;
use forc_tracing::{init_tracing_subscriber, println_error};

#[tokio::main]
async fn main() {
init_tracing_subscriber(Default::default());
let command = forc_client::cmd::Run::parse();
if let Err(err) = forc_client::op::run(command).await {
tracing::error!("Error: {:?}", err);
println_error(&format!("{}", err));
std::process::exit(1);
}
}
4 changes: 2 additions & 2 deletions forc-plugins/forc-client/src/bin/submit.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use clap::Parser;
use forc_tracing::init_tracing_subscriber;
use forc_tracing::{init_tracing_subscriber, println_error};

#[tokio::main]
async fn main() {
init_tracing_subscriber(Default::default());
let command = forc_client::cmd::Submit::parse();
if let Err(err) = forc_client::op::submit(command).await {
tracing::error!("Error: {:?}", err);
println_error(&format!("{}", err));
std::process::exit(1);
}
}
18 changes: 4 additions & 14 deletions forc-plugins/forc-client/src/cmd/deploy.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use clap::Parser;
use fuel_crypto::SecretKey;

pub use crate::util::Target;
pub use forc::cli::shared::{BuildOutput, BuildProfile, Minify, Pkg, Print};
pub use forc_tx::{Gas, Maturity};
pub use forc_util::tx_utils::Salt;

use crate::NodeTarget;

#[derive(Debug, Default, Parser)]
#[clap(bin_name = "forc deploy", version)]
pub struct Command {
Expand All @@ -19,6 +20,8 @@ pub struct Command {
pub gas: Gas,
#[clap(flatten)]
pub maturity: Maturity,
#[clap(flatten)]
pub node: NodeTarget,
/// Optional 256-bit hexadecimal literal(s) to redeploy contracts.
///
/// For a single contract, use `--salt <SALT>`, eg.: forc deploy --salt 0x0000000000000000000000000000000000000000000000000000000000000001
Expand All @@ -38,11 +41,6 @@ pub struct Command {
pub build_output: BuildOutput,
#[clap(flatten)]
pub build_profile: BuildProfile,
/// The URL of the Fuel node to which we're submitting the transaction.
/// If unspecified, checks the manifest's `network` table, then falls back
/// to [`crate::default::NODE_URL`].
#[clap(long, env = "FUEL_NODE_URL")]
pub node_url: Option<String>,
/// Sign the transaction with default signer that is pre-funded by fuel-core. Useful for testing against local node.
#[clap(long)]
pub default_signer: bool,
Expand All @@ -54,12 +52,4 @@ pub struct Command {
/// Sign the deployment transaction manually.
#[clap(long)]
pub manual_signing: bool,
/// Use preset configurations for deploying to a specific target.
///
/// Possible values are: [beta-1, beta-2, beta-3, latest]
#[clap(long)]
pub target: Option<Target>,
/// Use preset configuration for the latest testnet.
#[clap(long)]
pub testnet: bool,
}
8 changes: 3 additions & 5 deletions forc-plugins/forc-client/src/cmd/run.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::NodeTarget;
use clap::Parser;
use fuel_crypto::SecretKey;

Expand All @@ -24,11 +25,8 @@ pub struct Command {
pub build_output: BuildOutput,
#[clap(flatten)]
pub build_profile: BuildProfile,
/// The URL of the Fuel node to which we're submitting the transaction.
/// If unspecified, checks the manifest's `network` table, then falls back
/// to [`crate::default::NODE_URL`].
#[clap(long, env = "FUEL_NODE_URL")]
pub node_url: Option<String>,
#[clap(flatten)]
pub node: NodeTarget,
/// Hex string of data to input to script.
#[clap(short, long)]
pub data: Option<String>,
Expand Down
7 changes: 3 additions & 4 deletions forc-plugins/forc-client/src/cmd/submit.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::NodeTarget;
use devault::Devault;
use std::path::PathBuf;

Expand All @@ -20,10 +21,8 @@ pub struct Command {
/// Options related to networking.
#[derive(Debug, Devault, clap::Args)]
pub struct Network {
/// The URL of the Fuel node to which we're submitting the transaction.
#[clap(long, env = "FUEL_NODE_URL", default_value_t = String::from(crate::default::NODE_URL))]
#[devault("String::from(crate::default::NODE_URL)")]
pub node_url: String,
#[clap(flatten)]
pub node: NodeTarget,
/// Whether or not to await confirmation that the transaction has been committed.
///
/// When `true`, await commitment and output the transaction status.
Expand Down
6 changes: 6 additions & 0 deletions forc-plugins/forc-client/src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/// Default to localhost to favour the common case of testing.
pub const NODE_URL: &str = sway_utils::constants::DEFAULT_NODE_URL;
pub const BETA_2_ENDPOINT_URL: &str = "https://node-beta-2.fuel.network";
pub const BETA_3_ENDPOINT_URL: &str = "https://beta-3.fuel.network";
pub const BETA_4_ENDPOINT_URL: &str = "https://beta-4.fuel.network";
pub const BETA_4_FAUCET_URL: &str = "https://faucet-beta-4.fuel.network";
33 changes: 27 additions & 6 deletions forc-plugins/forc-client/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
pub mod cmd;
mod constants;
pub mod op;
mod util;

pub mod default {
/// Default to localhost to favour the common case of testing.
pub const NODE_URL: &str = sway_utils::constants::DEFAULT_NODE_URL;
pub const BETA_2_ENDPOINT_URL: &str = "node-beta-2.fuel.network/graphql";
pub const BETA_3_ENDPOINT_URL: &str = "beta-3.fuel.network/graphql";
pub const BETA_4_FAUCET_URL: &str = "https://faucet-beta-4.fuel.network";
use clap::Parser;
use serde::{Deserialize, Serialize};
use util::target::Target;

/// Flags for specifying the node to target.
#[derive(Debug, Default, Parser, Deserialize, Serialize)]
pub struct NodeTarget {
/// The URL of the Fuel node to which we're submitting the transaction.
/// If unspecified, checks the manifest's `network` table, then falls back
/// to `http://127.0.0.1:4000`
///
/// You can also use `--target` or `--testnet` to specify the Fuel node.
#[clap(long, env = "FUEL_NODE_URL")]
pub node_url: Option<String>,
/// Use preset configurations for deploying to a specific target.
///
/// You can also use `--node-url` or `--testnet` to specify the Fuel node.
///
/// Possible values are: [beta-1, beta-2, beta-3, beta-4, local]
#[clap(long)]
pub target: Option<Target>,
/// Use preset configuration for the latest testnet.
///
/// You can also use `--node-url` or `--target` to specify the Fuel node.
#[clap(long)]
pub testnet: bool,
}
74 changes: 17 additions & 57 deletions forc-plugins/forc-client/src/op/deploy.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use crate::{
cmd::{self, deploy::Target},
cmd,
util::{
gas::{get_gas_limit, get_gas_price},
node_url::get_node_url,
pkg::built_pkgs,
tx::{TransactionBuilderExt, WalletSelectionMode, TX_SUBMIT_TIMEOUT_MS},
},
};
use anyhow::{bail, Context, Result};
use forc_pkg::{self as pkg, PackageManifestFile};
use forc_tx::Gas;
use forc_tracing::println_warning;
use forc_util::default_output_directory;
use fuel_core_client::client::types::TransactionStatus;
use fuel_core_client::client::FuelClient;
Expand All @@ -24,7 +26,7 @@ use std::{
};
use sway_core::language::parsed::TreeType;
use sway_core::BuildTarget;
use tracing::{info, warn};
use tracing::info;

#[derive(Debug)]
pub struct DeployedContract {
Expand Down Expand Up @@ -116,11 +118,10 @@ fn validate_and_parse_salts<'a>(
///
/// When deploying a single contract, only that contract's ID is returned.
pub async fn deploy(command: cmd::Deploy) -> Result<Vec<DeployedContract>> {
let mut command = apply_target(command)?;
if command.unsigned {
warn!(" Warning: --unsigned flag is deprecated, please prefer using --default-signer. Assuming `--default-signer` is passed. This means your transaction will be signed by an account that is funded by fuel-core by default for testing purposes.");
command.default_signer = true;
println_warning("--unsigned flag is deprecated, please prefer using --default-signer. Assuming `--default-signer` is passed. This means your transaction will be signed by an account that is funded by fuel-core by default for testing purposes.");
}

let mut contract_ids = Vec::new();
let curr_dir = if let Some(ref path) = command.pkg.path {
PathBuf::from(path)
Expand All @@ -131,6 +132,11 @@ pub async fn deploy(command: cmd::Deploy) -> Result<Vec<DeployedContract>> {
let build_opts = build_opts_from_cmd(&command);
let built_pkgs = built_pkgs(&curr_dir, build_opts)?;

if built_pkgs.is_empty() {
println_warning("No deployable contracts found in the current directory.");
return Ok(contract_ids);
}

let contract_salt_map = if let Some(salt_input) = &command.salt {
// If we're building 1 package, we just parse the salt as a string, ie. 0x00...
// If we're building >1 package, we must parse the salt as a pair of strings, ie. contract_name:0x00...
Expand Down Expand Up @@ -197,61 +203,15 @@ pub async fn deploy(command: cmd::Deploy) -> Result<Vec<DeployedContract>> {
Ok(contract_ids)
}

/// Applies specified target information to the provided arguments.
///
/// Basically provides preset configurations for known test-nets.
fn apply_target(command: cmd::Deploy) -> Result<cmd::Deploy> {
let deploy_to_latest_testnet = command.testnet;
let target = if deploy_to_latest_testnet {
if command.target.is_some() {
bail!("Both `--testnet` and `--target` were specified: must choose one")
}
Some(Target::Beta3)
} else {
command.target.clone()
};

if let Some(target) = target {
match target {
cmd::deploy::Target::Beta2 | cmd::deploy::Target::Beta3 => {
// If the user did not specified a gas price, we can use `1` as a gas price for
// beta test-nets.
let gas_price = if command.gas.price == 0 {
1
} else {
command.gas.price
};

let target_url = Some(target.target_url().to_string());
Ok(cmd::Deploy {
gas: Gas {
price: gas_price,
..command.gas
},
node_url: target_url,
..command
})
}
cmd::deploy::Target::LATEST => Ok(command),
}
} else {
Ok(command)
}
}

/// Deploy a single pkg given deploy command and the manifest file
pub async fn deploy_pkg(
command: &cmd::Deploy,
manifest: &PackageManifestFile,
compiled: &BuiltPackage,
salt: Salt,
) -> Result<DeployedContract> {
let node_url = command
.node_url
.as_deref()
.or_else(|| manifest.network.as_ref().map(|nw| &nw.url[..]))
.unwrap_or(crate::default::NODE_URL);
let client = FuelClient::new(node_url)?;
let node_url = get_node_url(&command.node, &manifest.network)?;
let client = FuelClient::new(node_url.clone())?;

let bytecode = &compiled.bytecode.bytes;

Expand All @@ -270,13 +230,13 @@ pub async fn deploy_pkg(
};

let tx = TransactionBuilder::create(bytecode.as_slice().into(), salt, storage_slots.clone())
.gas_limit(command.gas.limit)
.gas_price(command.gas.price)
.gas_limit(get_gas_limit(&command.gas, client.chain_info().await?))
.gas_price(get_gas_price(&command.gas, client.node_info().await?))
.maturity(command.maturity.maturity.into())
.add_output(Output::contract_created(contract_id, state_root))
.finalize_signed(
client.clone(),
command.default_signer,
command.default_signer || command.unsigned,
command.signing_key,
wallet_mode,
)
Expand Down
Loading
Loading