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

Condor version #22

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
18 changes: 13 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
[workspace]
members = ["contract", "tests"]
resolver = "2"

members = [
"contract",
"tests",
]
[workspace.package]
edition = "2021"
homepage = "https://casperlabs.io"
license-file = "../LICENSE"
readme = "../README.md"
repository = "https://github.com/casper-ecosystem/hello-world"

[workspace.dependencies]
casper-types = { git = "https://github.com/casper-network/casper-node", branch = "feat-2.0" }

[profile.release]
lto = true
codegen-units = 1
lto = true
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ casper-client put-deploy \
--payment-amount 5000000000000 \
--session-path [CONTRACT PATH]/contract.wasm \
--session-arg "message:string='hello world'"
--session-arg "key-name:string='my-custom_key-name'"
```

After the deploy is successful, you can view the new NamedKey `special_value` in the faucet account details.
Expand Down
8 changes: 4 additions & 4 deletions contract/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[package]
name = "contract"
version = "0.1.0"
version = "0.2.0"
authors = ["darthsiroftardis <[email protected]>"]
edition = "2018"
edition = "2021"

[dependencies]
casper-contract = "3.0.0"
casper-types = "3.0.0"
casper-types.workspace = true
casper-contract = { git = "https://github.com/casper-network/casper-node", branch = "feat-2.0" }

[[bin]]
name = "contract"
Expand Down
23 changes: 14 additions & 9 deletions contract/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,30 @@ use alloc::string::String;
use casper_contract::contract_api::{runtime, storage};
use casper_types::{Key, URef};

const KEY_NAME: &str = "my-key-name";
const RUNTIME_ARG_NAME: &str = "message";
const RUNTIME_ARG_KEY_NAME: &str = "key-name";
const RUNTIME_ARG_MESSAGE: &str = "message";

fn store(value: String) {
fn store(value: String, key_name: String) {
// Store `value` under a new unforgeable reference.
let value_ref: URef = storage::new_uref(value);

// Wrap the unforgeable reference in a value of type `Key`.
let value_key: Key = value_ref.into();

// Store this key under the name "my-key-name" in caller context
runtime::put_key(KEY_NAME, value_key);
// Remove the key if already exists in account entity context
runtime::remove_key(&key_name);

// Store this key under the name "key-name" in caller context
runtime::put_key(&key_name, value_key);
}

// All session code must have a `call` entrypoint.
#[no_mangle]
pub extern "C" fn call() {
// This contract expects a single runtime argument to be provided. The arg is named "message"
// and will be of type `String`.
let value: String = runtime::get_named_arg(RUNTIME_ARG_NAME);
store(value);
// This contract expectstwo runtime arguments to be provided.
// The arg is named "message"and will be of type `String`.
let message: String = runtime::get_named_arg(RUNTIME_ARG_MESSAGE);
// The arg is named "key-name" and will be of type `String`.
let key_name: String = runtime::get_named_arg(RUNTIME_ARG_KEY_NAME);
store(message, key_name);
}
13 changes: 5 additions & 8 deletions tests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
[package]
name = "tests"
version = "0.1.0"
edition = "2018"
version = "0.2.0"
edition = "2021"

[dev-dependencies]
casper-engine-test-support = "5.0.0"
casper-contract = { version = "3.0.0", default-features = false, features = [
"test-support",
] }
casper-execution-engine = "5.0.0"
casper-types = "3.0.0"
casper-types.workspace = true
casper-engine-test-support = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0", default-features = false }
casper-execution-engine = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0", default-features = false }

[[bin]]
name = "integration-tests"
Expand Down
1 change: 1 addition & 0 deletions tests/rust-toolchain
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
stable
63 changes: 37 additions & 26 deletions tests/src/integration_tests.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,61 @@
fn main() {
panic!("Execute \"cargo test\" to test the contract, not \"cargo run\".");
}
#[cfg(test)]
mod tests {
use std::path::PathBuf;

use casper_engine_test_support::{
DeployItemBuilder, ExecuteRequestBuilder, InMemoryWasmTestBuilder, ARG_AMOUNT,
DEFAULT_ACCOUNT_ADDR, DEFAULT_PAYMENT, PRODUCTION_RUN_GENESIS_REQUEST,
utils::create_run_genesis_request, DeployItemBuilder, ExecuteRequestBuilder,
LmdbWasmTestBuilder, ARG_AMOUNT, DEFAULT_ACCOUNT_ADDR, DEFAULT_ACCOUNT_PUBLIC_KEY,
DEFAULT_PAYMENT,
};
use casper_execution_engine::core::{engine_state::Error as EngineStateError, execution};
use casper_types::{runtime_args, ApiError, Key, RuntimeArgs};
use casper_execution_engine::{engine_state::Error as CoreError, execution::ExecError};

// Define `KEY_NAME` constant to match that in the contract.
const KEY_NAME: &str = "my-key-name";
const VALUE: &str = "hello world";
const RUNTIME_ARG_NAME: &str = "message";
use casper_types::{runtime_args, ApiError, GenesisAccount, Key, Motes, RuntimeArgs, U512};

const RUNTIME_ARG_KEY_NAME: &str = "key-name";
const KEY_NAME_VALUE: &str = "my-custom_key-name";
const RUNTIME_ARG_MESSAGE: &str = "message";
const MESSAGE_VALUE: &str = "hello world";
const CONTRACT_WASM: &str = "contract.wasm";

#[test]
fn should_store_hello_world() {
let mut builder = InMemoryWasmTestBuilder::default();
let mut builder = LmdbWasmTestBuilder::default();
builder
.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST)
.run_genesis(create_run_genesis_request(vec![GenesisAccount::Account {
public_key: DEFAULT_ACCOUNT_PUBLIC_KEY.clone(),
balance: Motes::new(U512::from(5_000_000_000_000_u64)),
validator: None,
}]))
.commit();

// The test framework checks for compiled Wasm files in '<current working dir>/wasm'. Paths
// relative to the current working dir (e.g. 'wasm/contract.wasm') can also be used, as can
// absolute paths.
let session_code = PathBuf::from(CONTRACT_WASM);
let session_args = runtime_args! {
RUNTIME_ARG_NAME => VALUE,
RUNTIME_ARG_MESSAGE => MESSAGE_VALUE,
RUNTIME_ARG_KEY_NAME => KEY_NAME_VALUE
};

let deploy_item = DeployItemBuilder::new()
.with_empty_payment_bytes(runtime_args! {
.with_standard_payment(runtime_args! {
ARG_AMOUNT => *DEFAULT_PAYMENT
})
.with_session_code(session_code, session_args)
.with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])
.with_address(*DEFAULT_ACCOUNT_ADDR)
.build();

let execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();
let execute_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build();

// prepare assertions.
let result_of_query = builder.query(
None,
Key::Account(*DEFAULT_ACCOUNT_ADDR),
&[KEY_NAME.to_string()],
&[KEY_NAME_VALUE.to_string()],
);
assert!(result_of_query.is_err());

Expand All @@ -57,7 +67,7 @@ mod tests {
.query(
None,
Key::Account(*DEFAULT_ACCOUNT_ADDR),
&[KEY_NAME.to_string()],
&[KEY_NAME_VALUE.to_string()],
)
.expect("should be stored value.")
.as_cl_value()
Expand All @@ -66,7 +76,7 @@ mod tests {
.into_t::<String>()
.expect("should be string.");

assert_eq!(result_of_query, VALUE);
assert_eq!(result_of_query, MESSAGE_VALUE);
}

#[test]
Expand All @@ -75,33 +85,34 @@ mod tests {
let session_args = RuntimeArgs::new();

let deploy_item = DeployItemBuilder::new()
.with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
.with_standard_payment(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
.with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])
.with_address(*DEFAULT_ACCOUNT_ADDR)
.with_session_code(session_code, session_args)
.build();

let execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();
let execute_request = ExecuteRequestBuilder::from_deploy_item(&deploy_item).build();

let mut builder = InMemoryWasmTestBuilder::default();
let mut builder = LmdbWasmTestBuilder::default();
builder
.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST)
.run_genesis(create_run_genesis_request(vec![GenesisAccount::Account {
public_key: DEFAULT_ACCOUNT_PUBLIC_KEY.clone(),
balance: Motes::new(U512::from(5_000_000_000_000_u64)),
validator: None,
}]))
.commit();
builder.exec(execute_request).commit().expect_failure();

let actual_error = builder.get_error().expect("must have error");

assert!(
matches!(
actual_error,
EngineStateError::Exec(execution::Error::Revert(ApiError::MissingArgument))
CoreError::Exec(ExecError::Revert(ApiError::MissingArgument))
),
"Expected {:?}, received {:?}",
EngineStateError::Exec(execution::Error::Revert(ApiError::MissingArgument)),
CoreError::Exec(ExecError::Revert(ApiError::MissingArgument)),
actual_error
);
}
}

fn main() {
panic!("Execute \"cargo test\" to test the contract, not \"cargo run\".");
}
Loading