diff --git a/.github/workflows/ci-cep-85-client.yml b/.github/workflows/ci-cep-85-client.yml new file mode 100644 index 0000000..b9e4b1d --- /dev/null +++ b/.github/workflows/ci-cep-85-client.yml @@ -0,0 +1,65 @@ +name: ci-casper-cep-85-client + +on: + push: + branches: + - 'dev' + - 'feat-*' + - 'release-*' + + pull_request: + branches: + - 'dev' + - 'feat-*' + - 'release-*' + +jobs: + client-build: + strategy: + fail-fast: false + matrix: + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + node-version: [20.x] + os: [ubuntu-20.04, ubuntu-22.04] + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b #v3.0.2 + + - name: Swatinem cache + uses: Swatinem/rust-cache@cb2cf0cc7c5198d3364b9630e2c3d457f160790c #v1.4.0 + + - name: Install dependencies + run: sudo apt update && sudo apt install -y build-essential wabt + + - name: Setup + run: make prepare + + - name: Prepare WASMs + run: make setup-test + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@5b949b50c3461bbcd5a540b150c368278160234a #v3.4.0 + with: + node-version: ${{ matrix.node-version }} + + - name: Install + working-directory: ./client-js + run: npm install + + - name: Copy & convert WASMs + working-directory: ./client-js + run: npm run wasms:convert + + - name: Audits + working-directory: ./client-js + run: npm audit --omit=dev + + - name: Lints + working-directory: ./client-js + run: npm run lint + + - name: Test + working-directory: ./client-js + run: npm test diff --git a/.github/workflows/ci-cep-85.yml b/.github/workflows/ci-cep-85.yml new file mode 100644 index 0000000..f4d2b4a --- /dev/null +++ b/.github/workflows/ci-cep-85.yml @@ -0,0 +1,40 @@ +name: ci-cep-85 + +on: + push: + branches: + - 'dev' + - 'feat-*' + - 'release-*' + + pull_request: + branches: + - 'dev' + - 'feat-*' + - 'release-*' + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + strategy: + matrix: + os: [ubuntu-20.04, ubuntu-22.04] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b #v3.0.2 + + - uses: Swatinem/rust-cache@cb2cf0cc7c5198d3364b9630e2c3d457f160790c #v1.4.0 + + - name: Install dependencies + run: sudo apt update && sudo apt install -y build-essential wabt + + - name: Setup + run: make prepare + + - name: Run clippy and fmt + run: make check-lint + + - name: Run tests + run: make test diff --git a/.github/workflows/nightly-scheduled-test.yml b/.github/workflows/nightly-scheduled-test.yml new file mode 100644 index 0000000..02bc18b --- /dev/null +++ b/.github/workflows/nightly-scheduled-test.yml @@ -0,0 +1,41 @@ +name: nightly-scheduled-test + +on: + schedule: + # * is a special character in YAML so you have to quote this string + # runs every day at midnight + - cron: '0 0 * * *' + +jobs: + nightly-make-test: + strategy: + matrix: + os: [ubuntu-20.04, ubuntu-22.04] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b #v3.0.2 + + - uses: Swatinem/rust-cache@cb2cf0cc7c5198d3364b9630e2c3d457f160790c #v1.4.0 + + - name: Install dependencies + run: sudo apt update && sudo apt install -y build-essential wabt + + - name: Setup + run: make prepare + + - name: Run tests + run: make test + + - name: Slack Notification + uses: ravsamhq/notify-slack-action@4ed28566c2bdcdaee6dca2b46b9666d01b4ed8a4 #v1.10.0 + if: always() + with: + status: ${{ job.status }} + notification_title: '*{repo}*' + message_format: '{emoji} *{workflow}* *{status_message}* in <{repo_url}|{repo}@{branch}> on <{commit_url}|{commit_sha}>' + footer: '<{run_url}|View Run>' + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + + - name: Fake Commit after 50 days + uses: gautamkrishnar/keepalive-workflow@790c7f09285a59b09bb578c85e271c6ff2af97c4 #v1.1.0 diff --git a/.github/workflows/publish-cep-85-client.yml b/.github/workflows/publish-cep-85-client.yml new file mode 100644 index 0000000..5253bad --- /dev/null +++ b/.github/workflows/publish-cep-85-client.yml @@ -0,0 +1,49 @@ +name: publish-casper-cep85-client + +on: + release: + types: [created] + +jobs: + publish: + runs-on: ubuntu-22.04 + strategy: + matrix: + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + node-version: [20.x] + + steps: + - name: Checkout + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b #v3.0.2 + + - name: Swatinem cache + uses: Swatinem/rust-cache@cb2cf0cc7c5198d3364b9630e2c3d457f160790c #v1.4.0 + + - name: Install dependencies + run: sudo apt update && sudo apt install -y build-essential wabt + + - name: Setup + run: make prepare + + - name: Prepare WASMs + run: make setup-test + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@5b949b50c3461bbcd5a540b150c368278160234a #v3.4.0 + with: + node-version: ${{ matrix.node-version }} + registry-url: 'https://registry.npmjs.org' + + - name: Install + working-directory: ./client-js + run: npm install + + - name: Copy & convert WASMs + working-directory: ./client-js + run: npm run wasms:convert + + - name: Publish to NPM + working-directory: ./client-js + run: npm publish --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/publish-cep-85-contracts.yml b/.github/workflows/publish-cep-85-contracts.yml new file mode 100644 index 0000000..6d88d4b --- /dev/null +++ b/.github/workflows/publish-cep-85-contracts.yml @@ -0,0 +1,32 @@ +name: publish-cep-85-contracts + +on: + push: + tags: + - 'v*' + +jobs: + publish-contract-tarball: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b #v3.0.2 + + - uses: Swatinem/rust-cache@cb2cf0cc7c5198d3364b9630e2c3d457f160790c #v1.4.0 + + - name: Install dependencies + run: sudo apt update && sudo apt install -y build-essential wabt + + - name: Setup + run: make prepare + + - name: Build wasm contracts + run: make build-contract + + - name: Create tarball + run: ./ci/package_wasm.sh + + - name: Upload tarball to release + uses: svenstaro/upload-release-action@133984371c30d34e38222a64855679a414cb7575 #v2.3.0 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: /tmp/ci_package_wasm_${{ github.ref_name }}/cep-85-wasm.tar.gz diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 34a171f..0000000 --- a/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: rust -script: - - make prepare - - make check-lint - - make test diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index 369c518..0000000 --- a/Cargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[workspace] -members = ["contract", "test-contract", "tests"] -default-members = ["contract", "test-contract", "tests"] - -[profile.release] -codegen-units = 1 -lto = true diff --git a/Makefile b/Makefile index 5bd6d3e..549dbdb 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ ALL_CONTRACTS = cep85 cep85-test-contract -CONTRACT_TARGET_DIR = target/wasm32-unknown-unknown/release -PINNED_TOOLCHAIN := $(shell cat rust-toolchain) +CONTRACT_TARGET_DIR = contracts/target/wasm32-unknown-unknown/release +PINNED_TOOLCHAIN := $(shell cat contracts/rust-toolchain) prepare: rustup target add wasm32-unknown-unknown @@ -9,34 +9,37 @@ prepare: .PHONY: build-contract build-contract: - cargo build --release --target wasm32-unknown-unknown $(patsubst %,-p %, $(ALL_CONTRACTS)) + cd contracts/cep85 && cargo build --release + wasm-strip $(CONTRACT_TARGET_DIR)/cep85.wasm + +.PHONY: build-all-contracts +build-all-contracts: + cd contracts && cargo build --release $(patsubst %,-p %, $(ALL_CONTRACTS)) $(foreach WASM, $(ALL_CONTRACTS), wasm-strip $(CONTRACT_TARGET_DIR)/$(subst -,_,$(WASM)).wasm ;) -test: build-contract +setup-test: build-all-contracts mkdir -p tests/wasm cp $(CONTRACT_TARGET_DIR)/cep85.wasm tests/wasm cp $(CONTRACT_TARGET_DIR)/cep85_test_contract.wasm tests/wasm + +test: setup-test cd tests && cargo test clippy: - cd contract && cargo clippy --target wasm32-unknown-unknown --bins -- -D warnings - cd contract && cargo clippy --lib -- -D warnings - cd contract && cargo clippy --no-default-features --lib -- -D warnings - cd test-contract && cargo clippy --target wasm32-unknown-unknown -- -D warnings + cd contracts && cargo clippy --bins -- -D warnings + cd contracts && cargo clippy --lib -- -D warnings + cd contracts && cargo clippy --lib --no-default-features -- -D warnings cd tests && cargo clippy --all-targets -- -D warnings check-lint: clippy - cd contract && cargo fmt -- --check - cd test-contract && cargo fmt -- --check - cd tests && cargo fmt -- --check + cd contracts && cargo fmt -- --check + cd tests && cargo +$(PINNED_TOOLCHAIN) fmt -- --check -lint: clippy - cd contract && cargo fmt - cd test-contract && cargo fmt - cd tests && cargo fmt +format: + cd contracts && cargo fmt + cd tests && cargo +$(PINNED_TOOLCHAIN) fmt clean: - cd contract && cargo clean - cd test-contract && cargo clean + cd contracts && cargo clean cd tests && cargo clean rm -rf tests/wasm diff --git a/ci/package_wasm.sh b/ci/package_wasm.sh new file mode 100644 index 0000000..63890e3 --- /dev/null +++ b/ci/package_wasm.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +set -e + +BUILD_ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." >/dev/null 2>&1 && pwd)" +IGNORE='test_contract' +WASM_FILE_PATH_ARRAY=($(cat "$BUILD_ROOT_DIR/Makefile" | grep 'wasm-strip' | awk -F' ' '{print $2}')) +TAG=${GITHUB_REF_NAME:-local} +TEMP_DIR="/tmp/ci_package_wasm_$TAG" +TARBALL="cep-85-wasm.tar.gz" + +# Hygiene for local debugging. Won't apply to CI. +if [ -d "$TEMP_DIR" ]; then + rm -rf "$TEMP_DIR" +fi + +# Create temporary directory for staging tarball +mkdir -p "$TEMP_DIR" + +if [ -d "$TEMP_DIR" ]; then + # Loop over the contracts + for wasm_path in "${WASM_FILE_PATH_ARRAY[@]}"; do + # Ignore test-contract, used only in testing + if [[ "$wasm_path" != *"$IGNORE"* ]]; then + # Copy the other wasm files if they exist + if [ -f "$wasm_path" ]; then + echo "copying $wasm_path to $TEMP_DIR" + cp "$wasm_path" "$TEMP_DIR/" + fi + fi + done + + # Move to the staging directory + pushd "$TEMP_DIR" > /dev/null + echo "" + echo "creating $TEMP_DIR/$TARBALL" + echo "" + # create the tarball + tar -czf "$TARBALL" *.wasm --remove-files + # Move back + popd > /dev/null +fi + +echo "success!" \ No newline at end of file diff --git a/client-js/package.json b/client-js/package.json index ac90352..0e59398 100644 --- a/client-js/package.json +++ b/client-js/package.json @@ -16,7 +16,6 @@ "wasms:convert": "ts-node scripts/copy-and-convert-wasms.ts" }, "keywords": [], - "author": "Jan Hoffmann ", "license": "ISC", "devDependencies": { "@types/jest": "^29.5.11", @@ -47,4 +46,4 @@ "@make-software/ces-js-parser": "^1.3.3", "casper-js-sdk": "^2.15.3" } -} +} \ No newline at end of file diff --git a/contract/.cargo/config.toml b/contracts/.cargo/config.toml similarity index 100% rename from contract/.cargo/config.toml rename to contracts/.cargo/config.toml diff --git a/contracts/Cargo.toml b/contracts/Cargo.toml new file mode 100644 index 0000000..6c66eaa --- /dev/null +++ b/contracts/Cargo.toml @@ -0,0 +1,17 @@ +[workspace] +members = ["cep85", "test"] +resolver = "2" + +[workspace.package] +edition = "2021" +homepage = "https://casperlabs.io" +license-file = "../LICENSE" +readme = "../README.md" +repository = "https://github.com/casper-ecosystem/cep-85" + +[workspace.dependencies] +casper-types = "3.0.0" + +[profile.release] +codegen-units = 1 +lto = true diff --git a/contract/Cargo.toml b/contracts/cep85/Cargo.toml similarity index 68% rename from contract/Cargo.toml rename to contracts/cep85/Cargo.toml index 62853f6..d9f8c53 100644 --- a/contract/Cargo.toml +++ b/contracts/cep85/Cargo.toml @@ -1,17 +1,16 @@ [package] name = "cep85" version = "1.0.0" -edition = "2018" description = "A library for developing CEP-85 tokens for the Casper network." -readme = "README.md" -documentation = "https://docs.rs/casper-cep-85" -homepage = "https://casperlabs.io" -repository = "https://github.com/casper-ecosystem/cep-85" -license-file = "../LICENSE" +edition.workspace = true +homepage.workspace = true +license-file.workspace = true +readme.workspace = true +repository.workspace = true [dependencies] casper-contract = { version = "3.0.0", optional = true } -casper-types = "3.0.0" +casper-types.workspace = true casper-event-standard = { version = "0.4.0", default-features = false } hex = { version = "0.4.3", default-features = false } diff --git a/contract/src/balances.rs b/contracts/cep85/src/balances.rs similarity index 100% rename from contract/src/balances.rs rename to contracts/cep85/src/balances.rs diff --git a/contract/src/constants.rs b/contracts/cep85/src/constants.rs similarity index 100% rename from contract/src/constants.rs rename to contracts/cep85/src/constants.rs diff --git a/contract/src/entry_points.rs b/contracts/cep85/src/entry_points.rs similarity index 100% rename from contract/src/entry_points.rs rename to contracts/cep85/src/entry_points.rs diff --git a/contract/src/error.rs b/contracts/cep85/src/error.rs similarity index 100% rename from contract/src/error.rs rename to contracts/cep85/src/error.rs diff --git a/contract/src/events.rs b/contracts/cep85/src/events.rs similarity index 90% rename from contract/src/events.rs rename to contracts/cep85/src/events.rs index aae3dd9..d3345a7 100644 --- a/contract/src/events.rs +++ b/contracts/cep85/src/events.rs @@ -1,11 +1,14 @@ -use crate::{ - constants::ARG_EVENTS_MODE, modalities::EventsMode, security::SecurityBadge, - utils::get_stored_value, -}; +use crate::security::SecurityBadge; +#[cfg(feature = "contract-support")] +use crate::{constants::ARG_EVENTS_MODE, modalities::EventsMode, utils::get_stored_value}; use alloc::{collections::BTreeMap, string::String, vec::Vec}; +#[cfg(feature = "contract-support")] use casper_contract::unwrap_or_revert::UnwrapOrRevert; -use casper_event_standard::{emit, Event, Schemas}; +use casper_event_standard::Event; +#[cfg(feature = "contract-support")] +use casper_event_standard::{emit, Schemas}; use casper_types::{Key, U256}; +#[cfg(feature = "contract-support")] use core::convert::TryFrom; #[derive(Debug)] @@ -22,6 +25,7 @@ pub enum Event { Upgrade(Upgrade), } +#[cfg(feature = "contract-support")] pub fn record_event_dictionary(event: Event) { let events_mode: EventsMode = EventsMode::try_from(get_stored_value::(ARG_EVENTS_MODE)).unwrap_or_revert(); @@ -178,6 +182,7 @@ impl Upgrade { } } +#[cfg(feature = "contract-support")] fn ces(event: Event) { match event { Event::Mint(ev) => emit(ev), @@ -193,6 +198,7 @@ fn ces(event: Event) { } } +#[cfg(feature = "contract-support")] pub fn init_events() { let events_mode = EventsMode::try_from(get_stored_value::(ARG_EVENTS_MODE)).unwrap_or_revert(); diff --git a/contract/src/lib.rs b/contracts/cep85/src/lib.rs similarity index 77% rename from contract/src/lib.rs rename to contracts/cep85/src/lib.rs index 086bfc9..313b05d 100644 --- a/contract/src/lib.rs +++ b/contracts/cep85/src/lib.rs @@ -5,19 +5,16 @@ extern crate alloc; pub mod constants; pub mod entry_points; pub mod error; +pub mod events; pub mod modalities; +pub mod security; +pub mod utils; #[cfg(feature = "contract-support")] pub mod balances; #[cfg(feature = "contract-support")] -pub mod events; -#[cfg(feature = "contract-support")] pub mod operators; #[cfg(feature = "contract-support")] -pub mod security; -#[cfg(feature = "contract-support")] pub mod supply; #[cfg(feature = "contract-support")] pub mod uri; -#[cfg(feature = "contract-support")] -pub mod utils; diff --git a/contract/src/main.rs b/contracts/cep85/src/main.rs similarity index 99% rename from contract/src/main.rs rename to contracts/cep85/src/main.rs index c5c9520..adcb3ec 100644 --- a/contract/src/main.rs +++ b/contracts/cep85/src/main.rs @@ -260,11 +260,10 @@ pub extern "C" fn make_dictionary_item_key() { None => { let operator: Option = get_optional_named_arg_with_user_errors(ARG_OPERATOR, Cep85Error::InvalidOperator); - let dictionary_item_key = match operator { + match operator { Some(operator) => utils_make_dictionary_item_key(&owner, &operator), None => revert(Cep85Error::InvalidOperator), - }; - dictionary_item_key + } } }; diff --git a/contract/src/modalities.rs b/contracts/cep85/src/modalities.rs similarity index 98% rename from contract/src/modalities.rs rename to contracts/cep85/src/modalities.rs index f14a366..39ad203 100644 --- a/contract/src/modalities.rs +++ b/contracts/cep85/src/modalities.rs @@ -5,7 +5,6 @@ use casper_types::{ }; use crate::error::Cep85Error; -use core::convert::TryFrom; #[repr(u8)] #[derive(PartialEq, Eq)] diff --git a/contract/src/operators.rs b/contracts/cep85/src/operators.rs similarity index 100% rename from contract/src/operators.rs rename to contracts/cep85/src/operators.rs diff --git a/contract/src/security.rs b/contracts/cep85/src/security.rs similarity index 86% rename from contract/src/security.rs rename to contracts/cep85/src/security.rs index 3eb73f9..0061aaa 100644 --- a/contract/src/security.rs +++ b/contracts/cep85/src/security.rs @@ -1,10 +1,16 @@ -use alloc::{collections::BTreeMap, vec, vec::Vec}; +#[cfg(feature = "contract-support")] +use alloc::collections::BTreeMap; +use alloc::{vec, vec::Vec}; +#[cfg(feature = "contract-support")] use casper_contract::{contract_api::runtime::revert, unwrap_or_revert::UnwrapOrRevert}; +#[cfg(feature = "contract-support")] +use casper_types::Key; use casper_types::{ bytesrepr::{self, FromBytes, ToBytes}, - CLTyped, Key, + CLTyped, }; +#[cfg(feature = "contract-support")] use crate::{ constants::DICT_SECURITY_BADGES, error::Cep85Error, @@ -53,6 +59,7 @@ impl FromBytes for SecurityBadge { } } +#[cfg(feature = "contract-support")] pub fn sec_check(allowed_badge_list: Vec) { let (caller, caller_package) = get_verified_caller(); let caller_badge = get_security_badge(&caller); @@ -69,6 +76,7 @@ pub fn sec_check(allowed_badge_list: Vec) { revert(Cep85Error::InsufficientRights); } +#[cfg(feature = "contract-support")] fn get_security_badge(entity: &Key) -> Option { get_dictionary_value_from_key( DICT_SECURITY_BADGES, @@ -76,6 +84,7 @@ fn get_security_badge(entity: &Key) -> Option { ) } +#[cfg(feature = "contract-support")] pub fn change_sec_badge(badge_map: &BTreeMap) { for (&user, &badge) in badge_map { set_dictionary_value_for_key( diff --git a/contract/src/supply.rs b/contracts/cep85/src/supply.rs similarity index 100% rename from contract/src/supply.rs rename to contracts/cep85/src/supply.rs diff --git a/contract/src/uri.rs b/contracts/cep85/src/uri.rs similarity index 100% rename from contract/src/uri.rs rename to contracts/cep85/src/uri.rs diff --git a/contract/src/utils.rs b/contracts/cep85/src/utils.rs similarity index 89% rename from contract/src/utils.rs rename to contracts/cep85/src/utils.rs index 6d91b19..779333f 100644 --- a/contract/src/utils.rs +++ b/contracts/cep85/src/utils.rs @@ -1,33 +1,36 @@ +#[cfg(feature = "contract-support")] use crate::{ constants::{ARG_TRANSFER_FILTER_CONTRACT, ARG_TRANSFER_FILTER_METHOD}, error::Cep85Error, }; -use alloc::{ - borrow::ToOwned, - format, - string::{String, ToString}, - vec, - vec::Vec, -}; +#[cfg(feature = "contract-support")] +use alloc::{borrow::ToOwned, string::ToString, vec, vec::Vec}; +use alloc::{format, string::String}; +#[cfg(feature = "contract-support")] use casper_contract::{ contract_api::{self, runtime, storage}, ext_ffi, unwrap_or_revert::UnwrapOrRevert, }; +use casper_types::U256; +#[cfg(feature = "contract-support")] use casper_types::{ account::AccountHash, api_error, bytesrepr::{self, FromBytes, ToBytes}, system::CallStackElement, - ApiError, CLTyped, ContractHash, ContractPackageHash, Key, URef, U256, + ApiError, CLTyped, ContractHash, ContractPackageHash, Key, URef, }; +#[cfg(feature = "contract-support")] use core::{convert::TryInto, mem::MaybeUninit}; +#[cfg(feature = "contract-support")] pub enum Caller { Session(AccountHash), StoredCaller(ContractHash, ContractPackageHash), } +#[cfg(feature = "contract-support")] pub fn get_verified_caller() -> (Key, Option) { let get_verified_caller: Result = match *runtime::get_call_stack() .iter() @@ -57,6 +60,7 @@ pub fn get_verified_caller() -> (Key, Option) { } } +#[cfg(feature = "contract-support")] pub fn get_stored_value(name: &str) -> T where T: FromBytes + CLTyped, @@ -66,6 +70,7 @@ where value } +#[cfg(feature = "contract-support")] pub fn get_named_arg_with_user_errors( name: &str, missing: Cep85Error, @@ -97,6 +102,7 @@ pub fn get_named_arg_with_user_errors( bytesrepr::deserialize(arg_bytes).map_err(|_| invalid) } +#[cfg(feature = "contract-support")] pub fn get_optional_named_arg_with_user_errors( name: &str, invalid: Cep85Error, @@ -107,6 +113,7 @@ pub fn get_optional_named_arg_with_user_errors( } } +#[cfg(feature = "contract-support")] pub fn get_stored_value_with_user_errors( name: &str, missing: Cep85Error, @@ -116,6 +123,7 @@ pub fn get_stored_value_with_user_errors( read_with_user_errors(uref, missing, invalid) } +#[cfg(feature = "contract-support")] pub fn stringify_key(key: Key) -> String { match key { Key::Account(account_hash) => account_hash.to_string(), @@ -124,6 +132,7 @@ pub fn stringify_key(key: Key) -> String { } } +#[cfg(feature = "contract-support")] pub fn make_dictionary_item_key( key: &T, value: &V, @@ -137,6 +146,7 @@ pub fn make_dictionary_item_key( hex::encode(bytes) } +#[cfg(feature = "contract-support")] pub fn get_dictionary_value_from_key( dictionary_name: &str, key: &str, @@ -153,6 +163,7 @@ pub fn get_dictionary_value_from_key( } } +#[cfg(feature = "contract-support")] pub fn set_dictionary_value_for_key( dictionary_name: &str, key: &str, @@ -166,6 +177,7 @@ pub fn set_dictionary_value_for_key( storage::dictionary_put::(seed_uref, key, *value) } +#[cfg(feature = "contract-support")] pub fn get_transfer_filter_contract() -> Option { get_stored_value_with_user_errors( ARG_TRANSFER_FILTER_CONTRACT, @@ -174,6 +186,7 @@ pub fn get_transfer_filter_contract() -> Option { ) } +#[cfg(feature = "contract-support")] pub fn get_transfer_filter_method() -> Option { get_stored_value_with_user_errors( ARG_TRANSFER_FILTER_METHOD, @@ -186,6 +199,7 @@ pub fn replace_token_id_in_uri(raw_uri: &str, id: &U256) -> String { raw_uri.replace("{id}", &format!("{}", id)) } +#[cfg(feature = "contract-support")] fn get_uref(name: &str) -> URef { let key = runtime::get_key(name) .ok_or(ApiError::MissingKey) @@ -193,12 +207,14 @@ fn get_uref(name: &str) -> URef { key.try_into().unwrap_or_revert() } +#[cfg(feature = "contract-support")] fn get_uref_with_user_errors(name: &str, missing: Cep85Error, invalid: Cep85Error) -> URef { let key = get_key_with_user_errors(name, missing, invalid); key.into_uref() .unwrap_or_revert_with(Cep85Error::UnexpectedKeyVariant) } +#[cfg(feature = "contract-support")] fn get_key_with_user_errors(name: &str, missing: Cep85Error, invalid: Cep85Error) -> Key { let (name_ptr, name_size, _bytes) = to_ptr(name); let mut key_bytes = vec![0u8; Key::max_serialized_length()]; @@ -222,6 +238,7 @@ fn get_key_with_user_errors(name: &str, missing: Cep85Error, invalid: Cep85Error bytesrepr::deserialize(key_bytes).unwrap_or_revert_with(invalid) } +#[cfg(feature = "contract-support")] fn read_with_user_errors( uref: URef, missing: Cep85Error, @@ -245,6 +262,7 @@ fn read_with_user_errors( bytesrepr::deserialize(value_bytes).unwrap_or_revert_with(invalid) } +#[cfg(feature = "contract-support")] fn read_host_buffer(size: usize) -> Result, ApiError> { let mut dest: Vec = if size == 0 { Vec::new() @@ -256,6 +274,7 @@ fn read_host_buffer(size: usize) -> Result, ApiError> { Ok(dest) } +#[cfg(feature = "contract-support")] fn read_host_buffer_into(dest: &mut [u8]) -> Result { let mut bytes_written = MaybeUninit::uninit(); let ret = unsafe { @@ -268,6 +287,7 @@ fn read_host_buffer_into(dest: &mut [u8]) -> Result { Ok(unsafe { bytes_written.assume_init() }) } +#[cfg(feature = "contract-support")] fn to_ptr(t: T) -> (*const u8, usize, Vec) { let bytes = t.into_bytes().unwrap_or_revert(); let ptr = bytes.as_ptr(); @@ -275,6 +295,7 @@ fn to_ptr(t: T) -> (*const u8, usize, Vec) { (ptr, size, bytes) } +#[cfg(feature = "contract-support")] fn get_named_arg_size(name: &str) -> Option { let mut arg_size: usize = 0; let ret = unsafe { diff --git a/contracts/rust-toolchain b/contracts/rust-toolchain new file mode 100644 index 0000000..f9e5e5e --- /dev/null +++ b/contracts/rust-toolchain @@ -0,0 +1 @@ +nightly-2023-03-25 diff --git a/contracts/test/Cargo.toml b/contracts/test/Cargo.toml new file mode 100644 index 0000000..86ae4aa --- /dev/null +++ b/contracts/test/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "cep85-test-contract" +version = "1.0.0" +edition.workspace = true +homepage.workspace = true +license-file.workspace = true +readme.workspace = true +repository.workspace = true + +[dependencies] +cep85 = { path = "../cep85", default-features = false } +casper-contract = { version = "3.0.0", optional = true, default-features = false } +casper-types.workspace = true + +[[bin]] +name = "cep85_test_contract" +path = "src/main.rs" +bench = false +doctest = false +test = false + +[features] +default = ["cep85/contract-support", "casper-contract/no-std-helpers"] diff --git a/test-contract/src/constants.rs b/contracts/test/src/constants.rs similarity index 100% rename from test-contract/src/constants.rs rename to contracts/test/src/constants.rs diff --git a/test-contract/src/lib.rs b/contracts/test/src/lib.rs similarity index 100% rename from test-contract/src/lib.rs rename to contracts/test/src/lib.rs diff --git a/test-contract/src/main.rs b/contracts/test/src/main.rs similarity index 100% rename from test-contract/src/main.rs rename to contracts/test/src/main.rs diff --git a/test-contract/src/utils.rs b/contracts/test/src/utils.rs similarity index 100% rename from test-contract/src/utils.rs rename to contracts/test/src/utils.rs diff --git a/rustfmt.toml b/rustfmt.toml index 3d2e76e..b16fb7d 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,4 +1,4 @@ wrap_comments = true comment_width = 100 imports_granularity = "Crate" -edition = "2018" +edition = "2021" diff --git a/test-contract/Cargo.toml b/test-contract/Cargo.toml deleted file mode 100644 index 4863d17..0000000 --- a/test-contract/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "cep85-test-contract" -version = "1.0.0" -edition = "2018" - -[[bin]] -name = "cep85_test_contract" -path = "src/main.rs" -bench = false -doctest = false -test = false - -[dependencies] -cep85 = { path = "../contract" } -casper-contract = "3.0.0" -casper-types = "3.0.0" diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 67e5bd7..c93137a 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -1,20 +1,15 @@ [package] name = "tests" version = "1.0.0" -edition = "2018" +edition = "2021" [dev-dependencies] -cep85 = { path = "../contract", default-features = false } -cep85-test-contract = { path = "../test-contract", default-features = false } -casper-contract = { version = "3.0.0", default-features = false, features = [ - "test-support", - "std", -] } -casper-engine-test-support = { version = "5.0.0", features = ["test-support"] } +cep85 = { path = "../contracts/cep85", default-features = false } +cep85-test-contract = { path = "../contracts/test", default-features = false } +casper-engine-test-support = "5.0.0" casper-execution-engine = "5.0.0" casper-types = "3.0.0" casper-event-standard = { version = "0.4.0", default-features = false } -once_cell = { version = "1.16.0", default-features = false } [lib] name = "tests" diff --git a/tests/src/allowance.rs b/tests/src/allowance.rs index 40c804f..d3b6a74 100644 --- a/tests/src/allowance.rs +++ b/tests/src/allowance.rs @@ -19,7 +19,7 @@ fn should_not_allow_self_approval() { mut builder, TestContext { cep85_token, - test_accounts, + ref test_accounts, cep85_test_contract_package, .. }, @@ -63,7 +63,7 @@ fn should_allow_approval_of_an_account() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -154,7 +154,7 @@ fn should_remove_approval_of_an_account() { mut builder, TestContext { cep85_token, - test_accounts, + ref test_accounts, cep85_test_contract_package, .. }, @@ -312,7 +312,7 @@ fn should_not_transfer_from_account_to_account_without_allowance() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -385,7 +385,7 @@ fn should_not_batch_transfer_from_account_to_account_without_allowance() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -455,7 +455,7 @@ fn should_transfer_from_account_to_account_with_allowance() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -532,7 +532,7 @@ fn should_batch_transfer_from_account_to_account_with_allowance() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -608,7 +608,7 @@ fn should_not_transfer_from_account_to_account_through_contract_without_allowanc TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -682,7 +682,7 @@ fn should_not_batch_transfer_from_account_to_account_through_contract_without_al cep85_token, cep85_test_contract, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -768,7 +768,7 @@ fn should_transfer_from_account_to_account_through_contract_with_allowance() { cep85_token, cep85_test_contract, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -850,7 +850,7 @@ fn should_transfer_from_account_to_account_through_package_with_allowance() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -935,7 +935,7 @@ fn should_batch_transfer_from_account_to_account_through_contract_with_allowance cep85_token, cep85_test_contract, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -1016,7 +1016,7 @@ fn should_batch_transfer_from_account_to_account_through_package_with_allowance( TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -1098,7 +1098,7 @@ fn should_transfer_from_account_to_contract_through_contract_with_allowance() { cep85_token, cep85_test_contract, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -1180,7 +1180,7 @@ fn should_transfer_from_account_to_contract_through_package_with_allowance() { cep85_token, cep85_test_contract, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -1262,7 +1262,7 @@ fn should_batch_transfer_from_account_to_contract_through_contract_with_allowanc cep85_token, cep85_test_contract, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -1343,7 +1343,7 @@ fn should_batch_transfer_from_account_to_contract_through_package_with_allowance cep85_token, cep85_test_contract, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -1422,7 +1422,7 @@ fn should_make_dictionary_item_key_for_dict_operators_queries() { mut builder, TestContext { cep85_token, - test_accounts, + ref test_accounts, .. }, ) = setup(); diff --git a/tests/src/balances.rs b/tests/src/balances.rs index a6d8d87..35fb412 100644 --- a/tests/src/balances.rs +++ b/tests/src/balances.rs @@ -20,7 +20,7 @@ fn should_check_balance_of() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -60,7 +60,7 @@ fn should_check_balance_of_batch() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -103,7 +103,7 @@ fn should_error_on_balance_of_batch_args_len_difference() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); diff --git a/tests/src/burn.rs b/tests/src/burn.rs index 0b4a19d..44eab81 100644 --- a/tests/src/burn.rs +++ b/tests/src/burn.rs @@ -1361,7 +1361,7 @@ fn should_allow_contract_as_operator_to_burn_token() { cep85_token, cep85_test_contract, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup_with_args( @@ -1470,7 +1470,7 @@ fn should_allow_contract_as_operator_to_batch_burn_token() { cep85_token, cep85_test_contract, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup_with_args( @@ -1579,7 +1579,7 @@ fn should_allow_contract_package_as_operator_to_burn_token() { cep85_token, cep85_test_contract, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup_with_args( @@ -1688,7 +1688,7 @@ fn should_allow_contract_package_as_operator_to_batch_burn_token() { cep85_token, cep85_test_contract, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup_with_args( diff --git a/tests/src/events.rs b/tests/src/events.rs index 6d43002..092cf38 100644 --- a/tests/src/events.rs +++ b/tests/src/events.rs @@ -76,7 +76,7 @@ fn should_record_events_in_events_mode() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup_with_args( @@ -132,7 +132,7 @@ fn should_not_record_events_in_no_events_mode() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); diff --git a/tests/src/mint.rs b/tests/src/mint.rs index 56439aa..9831a61 100644 --- a/tests/src/mint.rs +++ b/tests/src/mint.rs @@ -19,7 +19,7 @@ fn should_mint_nft() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -63,7 +63,7 @@ fn should_mint_fungible_token() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -108,7 +108,7 @@ fn should_batch_mint() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -160,7 +160,7 @@ fn should_not_mint_above_total_supply() { mut builder, TestContext { cep85_token, - test_accounts, + ref test_accounts, cep85_test_contract_package, .. }, @@ -246,7 +246,7 @@ fn should_not_batch_mint_above_total_supply() { mut builder, TestContext { cep85_token, - test_accounts, + ref test_accounts, cep85_test_contract_package, .. }, diff --git a/tests/src/security.rs b/tests/src/security.rs index 20b6074..b56688b 100644 --- a/tests/src/security.rs +++ b/tests/src/security.rs @@ -23,7 +23,7 @@ fn should_test_security_no_rights() { mut builder, TestContext { cep85_token, - test_accounts, + ref test_accounts, .. }, ) = setup_with_args( @@ -110,7 +110,7 @@ fn should_test_security_meta_rights() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup_with_args( @@ -203,7 +203,7 @@ fn should_test_security_minter_rights() { mut builder, TestContext { cep85_token, - test_accounts, + ref test_accounts, .. }, ) = setup_with_args( @@ -270,7 +270,7 @@ fn should_test_security_burner_rights() { mut builder, TestContext { cep85_token, - test_accounts, + ref test_accounts, .. }, ) = setup_with_args( @@ -378,7 +378,7 @@ fn should_test_change_security() { mut builder, TestContext { cep85_token, - test_accounts, + ref test_accounts, .. }, ) = setup_with_args( diff --git a/tests/src/transfer.rs b/tests/src/transfer.rs index 8afd3d3..477dfd4 100644 --- a/tests/src/transfer.rs +++ b/tests/src/transfer.rs @@ -19,7 +19,7 @@ fn should_transfer_full_owned_amount() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -91,7 +91,7 @@ fn should_batch_transfer_full_owned_amount() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -172,7 +172,7 @@ fn should_not_transfer_more_than_owned_balance() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -252,7 +252,7 @@ fn should_not_batch_transfer_more_than_owned_balance() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -512,7 +512,7 @@ fn should_verify_zero_amount_transfer_is_noop() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -593,7 +593,7 @@ fn should_verify_zero_amount_batch_transfer_is_noop() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -682,7 +682,7 @@ fn should_transfer_account_to_account() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -754,7 +754,7 @@ fn should_batch_transfer_account_to_account() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -836,7 +836,7 @@ fn should_transfer_account_to_contract_package() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -908,7 +908,7 @@ fn should_batch_transfer_account_to_contract_package() { TestContext { cep85_token, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -1141,7 +1141,7 @@ fn should_transfer_account_to_contract() { cep85_token, cep85_test_contract, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); @@ -1214,7 +1214,7 @@ fn should_batch_transfer_account_to_contract_() { cep85_token, cep85_test_contract, cep85_test_contract_package, - test_accounts, + ref test_accounts, .. }, ) = setup(); diff --git a/tests/src/utility/installer_request_builders.rs b/tests/src/utility/installer_request_builders.rs index 2622c41..09a26cd 100644 --- a/tests/src/utility/installer_request_builders.rs +++ b/tests/src/utility/installer_request_builders.rs @@ -1,8 +1,3 @@ -use std::{ - collections::HashMap, - convert::{TryFrom, TryInto}, -}; - use super::{ constants::{ ACCOUNT_USER_1, ACCOUNT_USER_2, CEP85_CONTRACT_WASM, CEP85_TEST_CONTRACT_WASM, @@ -44,6 +39,7 @@ use cep85_test_contract::constants::{ ENTRY_POINT_CHECK_TOTAL_SUPPLY_OF, ENTRY_POINT_CHECK_TOTAL_SUPPLY_OF_BATCH, ENTRY_POINT_CHECK_URI, RESULT_KEY, }; +use std::collections::HashMap; #[derive(Clone)] pub struct TestContext { @@ -53,6 +49,10 @@ pub struct TestContext { pub test_accounts: HashMap<[u8; 32], AccountHash>, } +impl Drop for TestContext { + fn drop(&mut self) {} +} + fn default_args() -> RuntimeArgs { runtime_args! { ARG_NAME => TOKEN_NAME, @@ -155,8 +155,7 @@ pub fn get_test_result( let enabled_versions = contract_package.enabled_versions(); let (_version, contract_hash) = enabled_versions .iter() - .rev() - .next() + .next_back() .expect("should have latest version"); builder.get_value(*contract_hash, RESULT_KEY) @@ -606,27 +605,25 @@ pub fn cep85_transfer_from<'a>( let call_package = direct_call_test_contract.is_none() || direct_call_test_contract == Some(false); if call_package { - if let Ok(contract_package_hash) = ContractPackageHash::try_from(*hash_bytes) { - let args = runtime_args! { - ARG_FROM => *from, - ARG_TO => *to, - ARG_ID => ids[0], - ARG_AMOUNT => amounts[0], - ARG_DATA => data, - }; - - ExecuteRequestBuilder::versioned_contract_call_by_hash( - *sender, - contract_package_hash, - None, - ENTRY_POINT_CHECK_SAFE_TRANSFER_FROM, - args, - ) - .build() - } else { - panic!("Unknown variant"); - } - } else if let Ok(contract_hash) = ContractHash::try_from(*hash_bytes) { + let contract_package_hash = ContractPackageHash::from(*hash_bytes); + let args = runtime_args! { + ARG_FROM => *from, + ARG_TO => *to, + ARG_ID => ids[0], + ARG_AMOUNT => amounts[0], + ARG_DATA => data, + }; + + ExecuteRequestBuilder::versioned_contract_call_by_hash( + *sender, + contract_package_hash, + None, + ENTRY_POINT_CHECK_SAFE_TRANSFER_FROM, + args, + ) + .build() + } else { + let contract_hash = ContractHash::from(*hash_bytes); let args = runtime_args! { ARG_FROM => *from, ARG_TO => *to, @@ -642,8 +639,6 @@ pub fn cep85_transfer_from<'a>( args, ) .build() - } else { - panic!("Unknown variant"); } } _ => panic!("Unknown variant"), @@ -724,25 +719,23 @@ pub fn cep85_batch_transfer_from<'a>( let call_package = direct_call_test_contract.is_none() || direct_call_test_contract == Some(false); if call_package { - if let Ok(contract_package_hash) = ContractPackageHash::try_from(*hash_bytes) { - ExecuteRequestBuilder::versioned_contract_call_by_hash( - *sender, - contract_package_hash, - None, - ENTRY_POINT_CHECK_SAFE_BATCH_TRANSFER_FROM, - runtime_args! { - ARG_FROM => *from, - ARG_TO => *to, - ARG_IDS => ids, - ARG_AMOUNTS => amounts, - ARG_DATA => data, - }, - ) - .build() - } else { - panic!("Unknown variant"); - } - } else if let Ok(contract_hash) = ContractHash::try_from(*hash_bytes) { + let contract_package_hash = ContractPackageHash::from(*hash_bytes); + ExecuteRequestBuilder::versioned_contract_call_by_hash( + *sender, + contract_package_hash, + None, + ENTRY_POINT_CHECK_SAFE_BATCH_TRANSFER_FROM, + runtime_args! { + ARG_FROM => *from, + ARG_TO => *to, + ARG_IDS => ids, + ARG_AMOUNTS => amounts, + ARG_DATA => data, + }, + ) + .build() + } else { + let contract_hash = ContractHash::from(*hash_bytes); ExecuteRequestBuilder::contract_call_by_hash( *sender, contract_hash, @@ -756,8 +749,6 @@ pub fn cep85_batch_transfer_from<'a>( }, ) .build() - } else { - panic!("Unknown variant"); } } _ => panic!("Unknown variant"),