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

Proposition of changes into Casper Types to support a Rust SDK for 1.6 #110

Merged
merged 28 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
fa47e3a
sdk feature from node types
gRoussac Sep 28, 2023
c6b4e6a
feat sdk
gRoussac Sep 28, 2023
c5e020c
Compile wasm
gRoussac Sep 28, 2023
fcc43de
Backport changes for 2.0
gRoussac Sep 28, 2023
ea59751
Expose few things for sdk
gRoussac Sep 29, 2023
954167d
Timestamp on deploy
gRoussac Sep 30, 2023
bd01e25
Update Cargo.toml
gRoussac Oct 4, 2023
0d93619
Update Cargo.toml
gRoussac Oct 4, 2023
a799544
Update Cargo.toml
gRoussac Oct 4, 2023
81d90be
Update Cargo.toml
gRoussac Oct 4, 2023
01e667a
Update Cargo.toml
gRoussac Oct 4, 2023
97d00ea
Update Cargo.toml
gRoussac Oct 4, 2023
db73246
Change cargo toml to pull dev and not rustSDK-1.6
gRoussac Oct 17, 2023
6e829b1
Revert
gRoussac Oct 17, 2023
cf345ad
Add some code comments
gRoussac Oct 18, 2023
f9d312b
Add some code comments
gRoussac Oct 18, 2023
a77fc26
stash
gRoussac Nov 16, 2023
cb505c7
stash
gRoussac Nov 16, 2023
4b27b19
Merge branch 'rustSDK-1.6' into rustSDK-feat-1.6
gRoussac Nov 17, 2023
b341133
schemars
gRoussac Nov 17, 2023
d63bd8a
Fix schemars
gRoussac Nov 21, 2023
b2f07a1
Remove some formatting
gRoussac Nov 28, 2023
af5d888
Remove formatting
gRoussac Nov 28, 2023
c3d2820
avoid including dependencies required for bin target only when buildi…
gRoussac Nov 28, 2023
d5767ca
further restrict functions and tests included when std-fs-io feature …
Fraser999 Nov 29, 2023
a4906cb
extend CI tests
Fraser999 Nov 29, 2023
a2e4ef1
update patch section in manifest
Fraser999 Dec 18, 2023
9ff1da4
update deploy builder to not return invalid deploy
Fraser999 Dec 18, 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
25 changes: 17 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
[package]
name = "casper-client"
version = "2.0.0" # when updating, also update 'html_root_url' in lib.rs
authors = ["Marc Brinkmann <[email protected]>", "Fraser Hutchison <[email protected]>", "Zachary Showalter <[email protected]>"]
# when updating, also update 'html_root_url' in lib.rs
version = "2.0.0"
authors = [
"Marc Brinkmann <[email protected]>",
"Fraser Hutchison <[email protected]>",
"Zachary Showalter <[email protected]>",
]
edition = "2021"
description = "A client library and binary for interacting with the Casper network"
documentation = "https://docs.rs/casper-client"
Expand All @@ -11,6 +16,7 @@ repository = "https://github.com/casper-ecosystem/casper-client-rs"
license = "Apache-2.0"

[lib]
crate-type = ["cdylib", "rlib"]
name = "casper_client"
path = "lib/lib.rs"

Expand All @@ -20,11 +26,11 @@ path = "src/main.rs"
doc = false

[dependencies]
casper-hashing = { version = "2.0.0" }
async-trait = "0.1.59"
base16 = "0.2.1"
casper-hashing = "2.0.0"
casper-types = { version = "3.0.0", features = ["std"] }
clap = { version = "4", features = ["cargo", "deprecated", "wrap_help"] }
clap = { version = "4", features = ["cargo", "deprecated"] }
clap_complete = "4"
hex-buffer-serde = "0.4.0"
humantime = "2"
Expand All @@ -34,27 +40,30 @@ num-traits = "0.2.15"
once_cell = "1"
rand = "0.8.5"
reqwest = { version = "0.11.13", features = ["json"] }
schemars = "0.8"
schemars = "=0.8.5"
serde = { version = "1", default-features = false, features = ["derive"] }
serde_json = { version = "1", features = ["preserve_order"] }
thiserror = "1.0.34"
tokio = { version = "1.23.0", features = ["macros", "net", "rt-multi-thread", "sync", "time", ]}
tokio = { version = "1.23.0", features = ["macros", "rt", "sync", "time"] }
uint = "0.9.4"

[dev-dependencies]
tempfile = "3.7.1"

[features]
sdk = ["casper-types/sdk"]

[build-dependencies]
vergen = { version = "7", default-features = false, features = ["git"] }

[patch.crates-io]
casper-hashing = { git = "https://github.com/casper-network/casper-node", branch = "dev" }
casper-types = { git = "https://github.com/casper-network/casper-node", branch = "dev"}
casper-types = { git = "https://github.com/casper-network/casper-node", branch = "dev" }

[package.metadata.deb]
features = ["vendored-openssl"]
revision = "0"
assets = [["./target/release/casper-client", "/usr/bin/casper-client", "755"], ]
assets = [["./target/release/casper-client", "/usr/bin/casper-client", "755"]]
extended-description = """
Package for Casper Client to connect to Casper Node.

Expand Down
47 changes: 34 additions & 13 deletions lib/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ mod parse;
mod payment_str_params;
mod session_str_params;
mod simple_args;
#[cfg(feature = "sdk")]
pub use parse::account_identifier as parse_account_identifier;
#[cfg(feature = "sdk")]
pub use parse::purse_identifier as parse_purse_identifier;
#[cfg(feature = "sdk")]
pub use simple_args::insert_arg;

#[cfg(test)]
mod tests;

Expand All @@ -51,18 +58,18 @@ use crate::{
},
DictionaryItemIdentifier,
},
types::Deploy,
SuccessResponse,
};
#[cfg(doc)]
use crate::{Account, Block, Deploy, Error, StoredValue, Transfer};
use crate::{Account, Block, Error, StoredValue, Transfer};
#[cfg(doc)]
use casper_types::PublicKey;
pub use deploy_str_params::DeployStrParams;
pub use dictionary_item_str_params::DictionaryItemStrParams;
pub use error::CliError;
use json_args::JsonArg;
pub use json_args::{
help as json_args_help, Error as JsonArgsError, ErrorDetails as JsonArgsErrorDetails,
help as json_args_help, Error as JsonArgsError, ErrorDetails as JsonArgsErrorDetails, JsonArg,
};
pub use payment_str_params::PaymentStrParams;
pub use session_str_params::SessionStrParams;
Expand Down Expand Up @@ -120,17 +127,23 @@ pub async fn speculative_put_deploy(
/// `force` is true, and a file exists at `maybe_output_path`, it will be overwritten. If `force`
/// is false and a file exists at `maybe_output_path`, [`Error::FileAlreadyExists`] is returned
/// and the file will not be written.
/// With sdk feature file is not written
/// Returns the Deploy
pub fn make_deploy(
maybe_output_path: &str,
#[allow(unused_variables)] maybe_output_path: &str,
deploy_params: DeployStrParams<'_>,
session_params: SessionStrParams<'_>,
payment_params: PaymentStrParams<'_>,
force: bool,
) -> Result<(), CliError> {
let output = parse::output_kind(maybe_output_path, force);
#[allow(unused_variables)] force: bool,
) -> Result<Deploy, CliError> {
let deploy =
deploy::with_payment_and_session(deploy_params, payment_params, session_params, true)?;
crate::output_deploy(output, &deploy).map_err(CliError::from)
#[cfg(not(any(feature = "sdk")))]
{
let output = parse::output_kind(maybe_output_path, force);
let _ = crate::output_deploy(output, &deploy).map_err(CliError::from);
}
Ok(deploy)
}

/// Reads a previously-saved [`Deploy`] from a file, cryptographically signs it, and outputs it to a
Expand All @@ -140,6 +153,8 @@ pub fn make_deploy(
/// `force` is true, and a file exists at `maybe_output_path`, it will be overwritten. If `force`
/// is false and a file exists at `maybe_output_path`, [`Error::FileAlreadyExists`] is returned
/// and the file will not be written.
/// Method not available with the sdk feature, use deploy.sign() directly
#[cfg(not(any(feature = "sdk")))]
pub fn sign_deploy_file(
input_path: &str,
secret_key_path: &str,
Expand Down Expand Up @@ -273,16 +288,17 @@ pub async fn speculative_transfer(
/// `force` is true, and a file exists at `maybe_output_path`, it will be overwritten. If `force`
/// is false and a file exists at `maybe_output_path`, [`Error::FileAlreadyExists`] is returned
/// and the file will not be written.
/// With sdk feature file is not written
/// Returns the Deploy
pub fn make_transfer(
maybe_output_path: &str,
#[allow(unused_variables)] maybe_output_path: &str,
amount: &str,
target_account: &str,
transfer_id: &str,
deploy_params: DeployStrParams<'_>,
payment_params: PaymentStrParams<'_>,
force: bool,
) -> Result<(), CliError> {
let output = parse::output_kind(maybe_output_path, force);
#[allow(unused_variables)] force: bool,
) -> Result<Deploy, CliError> {
let deploy = deploy::new_transfer(
amount,
None,
Expand All @@ -292,7 +308,12 @@ pub fn make_transfer(
payment_params,
true,
)?;
crate::output_deploy(output, &deploy).map_err(CliError::from)
#[cfg(not(any(feature = "sdk")))]
{
let output = parse::output_kind(maybe_output_path, force);
let _ = crate::output_deploy(output, &deploy).map_err(CliError::from);
}
Ok(deploy)
}

/// Retrieves a [`Deploy`] from the network.
Expand Down
104 changes: 76 additions & 28 deletions lib/cli/deploy.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use casper_types::{account::AccountHash, AsymmetricType, PublicKey, UIntParseError, URef, U512};
use casper_types::{
account::AccountHash, AsymmetricType, PublicKey, SecretKey, UIntParseError, URef, U512,
};

use super::{parse, CliError, DeployStrParams, PaymentStrParams, SessionStrParams};
use crate::{
Expand All @@ -15,19 +17,6 @@ pub fn with_payment_and_session(
) -> Result<Deploy, CliError> {
let chain_name = deploy_params.chain_name.to_string();
let session = parse::session_executable_deploy_item(session_params)?;
let maybe_secret_key = if allow_unsigned_deploy && deploy_params.secret_key.is_empty() {
None
} else if deploy_params.secret_key.is_empty() && !allow_unsigned_deploy {
return Err(CliError::InvalidArgument {
context: "with_payment_and_session (secret_key, allow_unsigned_deploy)",
error: format!(
"allow_unsigned_deploy was {}, but no secret key was provided",
allow_unsigned_deploy
),
});
} else {
Some(parse::secret_key_from_file(deploy_params.secret_key)?)
};
let payment = parse::payment_executable_deploy_item(payment_params)?;
let timestamp = parse::timestamp(deploy_params.timestamp)?;
let ttl = parse::ttl(deploy_params.ttl)?;
Expand All @@ -38,6 +27,7 @@ pub fn with_payment_and_session(
.with_timestamp(timestamp)
.with_ttl(ttl);

let maybe_secret_key = get_maybe_secret_key(deploy_params.secret_key, allow_unsigned_deploy)?;
if let Some(secret_key) = &maybe_secret_key {
deploy_builder = deploy_builder.with_secret_key(secret_key);
}
Expand All @@ -63,21 +53,7 @@ pub fn new_transfer(
allow_unsigned_deploy: bool,
) -> Result<Deploy, CliError> {
let chain_name = deploy_params.chain_name.to_string();
let maybe_secret_key = if allow_unsigned_deploy && deploy_params.secret_key.is_empty() {
None
} else if deploy_params.secret_key.is_empty() && !allow_unsigned_deploy {
return Err(CliError::InvalidArgument {
context: "new_transfer (secret_key, allow_unsigned_deploy)",
error: format!(
"allow_unsigned_deploy was {}, but no secret key was provided",
allow_unsigned_deploy
),
});
} else {
Some(parse::secret_key_from_file(deploy_params.secret_key)?)
};
let payment = parse::payment_executable_deploy_item(payment_params)?;

let amount = U512::from_dec_str(amount).map_err(|err| CliError::FailedToParseUint {
context: "new_transfer amount",
error: UIntParseError::FromDecStr(err),
Expand Down Expand Up @@ -111,6 +87,8 @@ pub fn new_transfer(
.with_payment(payment)
.with_timestamp(timestamp)
.with_ttl(ttl);

let maybe_secret_key = get_maybe_secret_key(deploy_params.secret_key, allow_unsigned_deploy)?;
if let Some(secret_key) = &maybe_secret_key {
deploy_builder = deploy_builder.with_secret_key(secret_key);
}
Expand All @@ -123,3 +101,73 @@ pub fn new_transfer(
.map_err(crate::Error::from)?;
Ok(deploy)
}

/// Retrieves a `SecretKey` based on the provided secret key string and configuration options.
///
/// # Arguments
///
/// * `secret_key` - A string representing the secret key. If empty, a `None` option is returned.
/// * `allow_unsigned_deploy` - A boolean indicating whether unsigned deploys are allowed.
///
/// # Returns
///
/// Returns a `Result` containing an `Option<SecretKey>`. If a valid secret key is provided and the `sdk` feature is enabled,
/// the `Result` contains `Some(SecretKey)`. If the `sdk` feature is disabled, the `Result` contains `Some(SecretKey)` parsed from the provided file.
/// If `secret_key` is empty and `allow_unsigned_deploy` is `true`, the `Result` contains `None`. If `secret_key` is empty and `allow_unsigned_deploy` is `false`,
/// an `Err` variant with a `CliError::InvalidArgument` is returned.
///
/// # Errors
///
/// Returns an `Err` variant with a `CliError::Core` or `CliError::InvalidArgument` if there are issues with parsing the secret key.
///
/// # Examples
///
/// ```
/// use casper_client::CliError;
///
/// match get_maybe_secret_key("path/to/secret_key.pem", true) {
/// Ok(Some(secret_key)) => {
/// println!("Secret Key: {:?}", secret_key);
/// }
/// Ok(None) => {
/// println!("No secret key provided, unsigned deploys allowed.");
/// }
/// Err(error) => {
/// eprintln!("Error: {:?}", error);
/// }
/// }
/// ```
fn get_maybe_secret_key(
secret_key: &str,
allow_unsigned_deploy: bool,
) -> Result<Option<SecretKey>, CliError> {
if !secret_key.is_empty() {
#[cfg(feature = "sdk")]
{
let secret_key: SecretKey = match SecretKey::from_pem(secret_key) {
Ok(key) => key,
Err(error) => {
return Err(CliError::Core(crate::Error::CryptoError {
context: "secret key",
error,
}));
}
};
Ok(Some(secret_key))
}
#[cfg(not(feature = "sdk"))]
{
Ok(Some(parse::secret_key_from_file(secret_key)?))
}
} else if !allow_unsigned_deploy {
Err(CliError::InvalidArgument {
context: "with_payment_and_session (secret_key, allow_unsigned_deploy)",
error: format!(
"allow_unsigned_deploy was {}, but no secret key was provided",
allow_unsigned_deploy
),
})
} else {
Ok(None)
}
}
2 changes: 1 addition & 1 deletion lib/cli/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub enum CliError {
ConflictingArguments {
/// Contextual description of where this error occurred including relevant paths,
/// filenames, etc.
context: &'static str,
context: String,
/// Arguments passed, with their values.
args: Vec<String>,
},
Expand Down
3 changes: 2 additions & 1 deletion lib/cli/json_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ use casper_types::{
use crate::cli::CliError;
pub use error::{Error, ErrorDetails};

/// Represents a JSON argument with a name, type, and value.
#[derive(Clone, Serialize, Deserialize, Debug)]
pub(super) struct JsonArg {
pub struct JsonArg {
name: String,
#[serde(rename = "type")]
cl_type: CLType,
Expand Down
Loading
Loading