diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..f2033d86 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,66 @@ +name: ci + +on: + push: + branches: + - main + pull_request: + +env: + CARGO_TERM_COLOR: always + RUST_VERSION: nightly + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: ${{ env.RUST_VERSION }} + components: llvm-tools-preview + - run: cargo llvm-cov nextest --all-features --lcov --output-path lcov.info + - uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: lcov.info + + ensure-wasm: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: ${{ env.RUST_VERSION }} + target: wasm32-unknown-unknown + - run: cargo build -r --target wasm32-unknown-unknown -p account-sdk + + cairo-check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: software-mansion/setup-scarb@v1 + with: + scarb-version: "2.5.3" + - run: scarb fmt --check + - run: scarb test + + clippy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: ${{ env.RUST_VERSION }} + components: clippy + - run: cargo clippy --all-targets --all-features + + fmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: ${{ env.RUST_VERSION }} + components: rustfmt + - run: cargo +nightly fmt --check --all diff --git a/.github/workflows/release-dispatch.yml b/.github/workflows/release-dispatch.yml new file mode 100644 index 00000000..f060c096 --- /dev/null +++ b/.github/workflows/release-dispatch.yml @@ -0,0 +1,35 @@ +name: release-dispatch +on: + workflow_dispatch: + inputs: + version: + description: Version to release + required: true + type: string + +jobs: + propose-release: + permissions: + pull-requests: write + contents: write + runs-on: ubuntu-latest + container: + image: ghcr.io/dojoengine/dojo-dev:5d61184 + steps: + # Workaround described here: https://github.com/actions/checkout/issues/760 + - uses: actions/checkout@v3 + - run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + - run: cargo release version ${{ inputs.version }} --execute --no-confirm && cargo release replace --execute --no-confirm + - id: version_info + run: | + cargo install cargo-get + echo "version=$(cargo get workspace.package.version)" >> $GITHUB_OUTPUT + - uses: peter-evans/create-pull-request@v5 + with: + # We have to use a PAT in order to trigger ci + token: ${{ secrets.CREATE_PR_TOKEN }} + title: "Prepare release: v${{ steps.version_info.outputs.version }}" + commit-message: "Prepare release: v${{ steps.version_info.outputs.version }}" + branch: prepare-release + base: main + delete-branch: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..5fd3f387 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,198 @@ +name: release + +on: + pull_request: + types: [closed] + branches: + - main + +env: + CARGO_TERM_COLOR: always + RUST_VERSION: 1.74.0 + REGISTRY_IMAGE: ghcr.io/${{ github.repository }} + +jobs: + prepare: + if: github.event.pull_request.merged == true && github.event.pull_request.head.ref == 'prepare-release' + runs-on: ubuntu-latest + outputs: + tag_name: ${{ steps.release_info.outputs.tag_name }} + steps: + - uses: actions/checkout@v3 + - name: Get version + id: release_info + run: | + cargo install cargo-get + echo "tag_name=$(cargo get workspace.package.version)" >> $GITHUB_OUTPUT + + release: + name: ${{ matrix.job.target }} (${{ matrix.job.os }}) + needs: prepare + runs-on: ${{ matrix.job.os }} + env: + PLATFORM_NAME: ${{ matrix.job.platform }} + TARGET: ${{ matrix.job.target }} + ARCH: ${{ matrix.job.arch }} + strategy: + matrix: + job: + # The OS is used for the runner + # The platform is a generic platform name + # The target is used by Cargo + # The arch is either 386, arm64 or amd64 + # The svm target platform to use for the binary https://github.com/roynalnaruto/svm-rs/blob/84cbe0ac705becabdc13168bae28a45ad2299749/svm-builds/build.rs#L4-L24 + - os: ubuntu-20.04-4-cores + platform: linux + target: x86_64-unknown-linux-gnu + arch: amd64 + - os: ubuntu-20.04-8-cores + platform: linux + target: aarch64-unknown-linux-gnu + arch: arm64 + svm_target_platform: linux-aarch64 + - os: macos-latest-xlarge + platform: darwin + target: x86_64-apple-darwin + arch: amd64 + - os: macos-latest + platform: darwin + target: aarch64-apple-darwin + arch: arm64 + - os: windows-latest + platform: win32 + target: x86_64-pc-windows-msvc + arch: amd64 + + steps: + - uses: actions/checkout@v3 + + - uses: dtolnay/rust-toolchain@master + name: Rust Toolchain Setup + with: + targets: ${{ matrix.job.target }} + toolchain: ${{ env.RUST_VERSION }} + + - uses: Swatinem/rust-cache@v1 + with: + cache-on-failure: true + + - uses: arduino/setup-protoc@v2 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: "25.x" + + - name: Apple M1 setup + if: ${{ matrix.job.target == 'aarch64-apple-darwin' }} + run: | + echo "SDKROOT=$(xcrun -sdk macosx --show-sdk-path)" >> $GITHUB_ENV + echo "MACOSX_DEPLOYMENT_TARGET=$(xcrun -sdk macosx --show-sdk-platform-version)" >> $GITHUB_ENV + + - name: Linux ARM setup + if: ${{ matrix.job.target == 'aarch64-unknown-linux-gnu' }} + run: | + sudo apt-get update -y + sudo apt-get install -y gcc-aarch64-linux-gnu libssl-dev + echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV + + - name: Build binaries + run: cargo build --release --bins --target ${{ matrix.job.target }} + + - name: Archive binaries + id: artifacts + env: + VERSION_NAME: v${{ needs.prepare.outputs.tag_name }} + run: | + if [ "$PLATFORM_NAME" == "linux" ]; then + tar -czvf "dojo_${VERSION_NAME}_${PLATFORM_NAME}_${ARCH}.tar.gz" -C ./target/${TARGET}/release katana sozo torii dojo-language-server + echo "file_name=dojo_${VERSION_NAME}_${PLATFORM_NAME}_${ARCH}.tar.gz" >> $GITHUB_OUTPUT + elif [ "$PLATFORM_NAME" == "darwin" ]; then + # We need to use gtar here otherwise the archive is corrupt. + # See: https://github.com/actions/virtual-environments/issues/2619 + gtar -czvf "dojo_${VERSION_NAME}_${PLATFORM_NAME}_${ARCH}.tar.gz" -C ./target/${TARGET}/release katana sozo torii dojo-language-server + echo "file_name=dojo_${VERSION_NAME}_${PLATFORM_NAME}_${ARCH}.tar.gz" >> $GITHUB_OUTPUT + else + cd ./target/${TARGET}/release + 7z a -tzip "dojo_${VERSION_NAME}_${PLATFORM_NAME}_${ARCH}.zip" katana.exe sozo.exe torii.exe dojo-language-server.exe + mv "dojo_${VERSION_NAME}_${PLATFORM_NAME}_${ARCH}.zip" ../../../ + echo "file_name=dojo_${VERSION_NAME}_${PLATFORM_NAME}_${ARCH}.tar.gz" >> $GITHUB_OUTPUT + fi + shell: bash + + # We move binaries so they match $TARGETPLATFORM in the Docker build + - name: Move Binaries + if: ${{ env.PLATFORM_NAME == 'linux' }} + run: | + mkdir -p $PLATFORM_NAME/$ARCH + mv target/$TARGET/release/katana $PLATFORM_NAME/$ARCH + mv target/$TARGET/release/sozo $PLATFORM_NAME/$ARCH + mv target/$TARGET/release/torii $PLATFORM_NAME/$ARCH + shell: bash + + # Upload these for use with the Docker build later + - name: Upload docker binaries + uses: actions/upload-artifact@v3 + with: + name: binaries + path: ${{ env.PLATFORM_NAME }} + retention-days: 1 + + - name: Upload release artifacts + uses: actions/upload-artifact@v3 + with: + name: artifacts + path: ${{ steps.artifacts.outputs.file_name }} + retention-days: 1 + + create-draft-release: + runs-on: ubuntu-20.04-4-cores + needs: [prepare, release] + env: + GITHUB_USER: ${{ github.repository_owner }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + steps: + - uses: actions/checkout@v2 + - uses: actions/download-artifact@v3 + with: + name: artifacts + path: artifacts + - id: version_info + run: | + cargo install cargo-get + echo "version=$(cargo get workspace.package.version)" >> $GITHUB_OUTPUT + - name: Display structure of downloaded files + run: ls -R artifacts + - run: gh release create v${{ steps.version_info.outputs.version }} ./artifacts/*.gz --generate-notes --draft + + docker-build-and-push: + runs-on: ubuntu-20.04-4-cores + needs: [prepare, release] + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Download binaries + uses: actions/download-artifact@v3 + with: + name: binaries + path: artifacts/linux + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push docker image + uses: docker/build-push-action@v3 + with: + push: true + tags: ghcr.io/${{ github.repository }}:latest,ghcr.io/${{ github.repository }}:v${{ needs.prepare.outputs.tag_name }} + platforms: linux/amd64,linux/arm64 + build-contexts: | + artifacts=artifacts diff --git a/.gitignore b/.gitignore index d770d50d..230cd553 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,5 @@ Cargo.lock # Logs **/log/ + +lcov.info diff --git a/crates/account_sdk/src/felt_ser.rs b/crates/account_sdk/src/felt_ser.rs index 43b46205..0ef4ec98 100644 --- a/crates/account_sdk/src/felt_ser.rs +++ b/crates/account_sdk/src/felt_ser.rs @@ -395,8 +395,7 @@ mod tests { let serialized = vec![val.a, val.i.into(), val.x.into()]; let seq = (0..100).map(|_| val.clone()).collect::>(); let mut result = (0..100) - .map(|_| serialized.clone()) - .flatten() + .flat_map(|_| serialized.clone()) .collect::>(); result.insert(0, seq.len().into()); assert_eq!(to_felts(&seq), result); diff --git a/crates/account_sdk/src/tests/deployment_test.rs b/crates/account_sdk/src/tests/deployment_test.rs index 24b96523..c240074b 100644 --- a/crates/account_sdk/src/tests/deployment_test.rs +++ b/crates/account_sdk/src/tests/deployment_test.rs @@ -20,11 +20,11 @@ pub async fn create_account<'a>( SigningKey, ) { let provider = *from.provider(); - let class_hash = declare(provider, &from).await; + let class_hash = declare(provider, from).await; let private_key = SigningKey::from_random(); let deployed_address = deploy( provider, - &from, + from, private_key.verifying_key().scalar(), class_hash, ) @@ -53,13 +53,12 @@ pub async fn declare( client: &JsonRpcClient, account: &SingleOwnerAccount<&JsonRpcClient, LocalWallet>, ) -> FieldElement { - let DeclareTransactionResult { class_hash, .. } = - AccountDeclaration::cartridge_account(&client) - .declare(&account) - .await - .unwrap() - .wait_for_completion() - .await; + let DeclareTransactionResult { class_hash, .. } = AccountDeclaration::cartridge_account(client) + .declare(account) + .await + .unwrap() + .wait_for_completion() + .await; class_hash } @@ -72,8 +71,8 @@ pub async fn deploy( ) -> FieldElement { let DeployResult { deployed_address, .. - } = AccountDeployment::new(&client) - .deploy(vec![public_key], FieldElement::ZERO, &account, class_hash) + } = AccountDeployment::new(client) + .deploy(vec![public_key], FieldElement::ZERO, account, class_hash) .await .unwrap() .wait_for_completion() diff --git a/crates/account_sdk/src/tests/session/uitls.rs b/crates/account_sdk/src/tests/session/uitls.rs index 40fb8eba..aacb896c 100644 --- a/crates/account_sdk/src/tests/session/uitls.rs +++ b/crates/account_sdk/src/tests/session/uitls.rs @@ -12,12 +12,12 @@ use crate::{abigen::account::Call, tests::runners::TestnetRunner}; use crate::session_token::Session; -pub async fn create_session_account<'a, T>( - runner: &'a T, +pub async fn create_session_account( + runner: &T, ) -> ( - SessionAccount<&'a JsonRpcClient, LocalWallet>, + SessionAccount<&JsonRpcClient, LocalWallet>, SigningKey, - SingleOwnerAccount<&'a JsonRpcClient, LocalWallet>, + SingleOwnerAccount<&JsonRpcClient, LocalWallet>, ) where T: TestnetRunner, diff --git a/crates/cartridge_account/src/lib.cairo b/crates/cartridge_account/src/lib.cairo index 5247d258..aa668c08 100644 --- a/crates/cartridge_account/src/lib.cairo +++ b/crates/cartridge_account/src/lib.cairo @@ -240,7 +240,7 @@ mod Account { } fn _execute_single_call(call: Call) -> Span { - let Call{to, selector, calldata } = call; + let Call { to, selector, calldata } = call; starknet::call_contract_syscall(to, selector, calldata).unwrap() } } diff --git a/crates/webauthn/auth/src/deserializable_endpoints.cairo b/crates/webauthn/auth/src/deserializable_endpoints.cairo index 640b3e11..2dede7ce 100644 --- a/crates/webauthn/auth/src/deserializable_endpoints.cairo +++ b/crates/webauthn/auth/src/deserializable_endpoints.cairo @@ -18,13 +18,11 @@ fn verify_hashed_ecdsa_endpoint( verify_hashed_ecdsa(pub_key_point, msg_hash, r, s) } -fn expand_auth_data_endpoint( - auth_data: Array -) -> AuthenticatorData { +fn expand_auth_data_endpoint(auth_data: Array) -> AuthenticatorData { let data: Option = ImplArrayu8TryIntoAuthData::try_into(auth_data); return data.unwrap(); } fn extract_u256_from_u8_array_endpoint(bytes: Array, offset: u32) -> Option { extract_u256_from_u8_array(@bytes, offset) -} \ No newline at end of file +} diff --git a/crates/webauthn/session/src/tests.cairo b/crates/webauthn/session/src/tests.cairo index 0ff6179a..2a51044a 100644 --- a/crates/webauthn/session/src/tests.cairo +++ b/crates/webauthn/session/src/tests.cairo @@ -1,3 +1,2 @@ mod signature_deserialization; - diff --git a/crates/webauthn/tests/src/arg_builder.rs b/crates/webauthn/tests/src/arg_builder.rs index b24800bf..8c11616f 100644 --- a/crates/webauthn/tests/src/arg_builder.rs +++ b/crates/webauthn/tests/src/arg_builder.rs @@ -29,6 +29,12 @@ impl ArgsBuilder { } } +impl Default for ArgsBuilder { + fn default() -> Self { + Self::new() + } +} + pub trait FeltSerialize { fn to_felts(self) -> Vec; } diff --git a/crates/webauthn/tests/src/auth/expand_auth_data.rs b/crates/webauthn/tests/src/auth/expand_auth_data.rs index bdab39ff..eb46fe9a 100644 --- a/crates/webauthn/tests/src/auth/expand_auth_data.rs +++ b/crates/webauthn/tests/src/auth/expand_auth_data.rs @@ -91,7 +91,7 @@ impl FeltSerialize for AuthenticatorData { #[test] fn test_expand_auth_data_1() { - let d: Vec = (0_u8..32_u8).into_iter().collect(); + let d: Vec = (0_u8..32_u8).collect(); let auth_data = AuthenticatorData { rp_id_hash: d.try_into().unwrap(), flags: 0, diff --git a/crates/webauthn/tests/src/auth/verify_signature.rs b/crates/webauthn/tests/src/auth/verify_signature.rs index 184ed1f1..2645a81c 100644 --- a/crates/webauthn/tests/src/auth/verify_signature.rs +++ b/crates/webauthn/tests/src/auth/verify_signature.rs @@ -29,7 +29,7 @@ fn verify_signature( .add_array(hash.iter().cloned()) .add_array(auth_data.iter().cloned()) .add_struct(pub_key.to_felts()) - .add_array(r.into_iter().copied().chain(s.iter().copied())); + .add_array(r.iter().copied().chain(s.iter().copied())); let result: [Felt252; 2] = VERIFY_SIGNATURE.run(args.build()); result == [0.into(), 0.into()] } @@ -39,7 +39,7 @@ fn test_verify_signature_1() { let hash: &[u8] = b"hello world"; let auth_data = b"dummy auth data"; let signing_key = SigningKey::random(&mut OsRng); - let (signature, _) = signing_key.sign(&vec![auth_data, hash].concat()); + let (signature, _) = signing_key.sign(&[auth_data, hash].concat()); assert!(verify_signature(hash, auth_data, signing_key, signature)) } @@ -48,7 +48,7 @@ fn test_verify_signature_2() { let hash: &[u8] = b"1234567890987654321"; let auth_data = b"auuuuuuuuuuth daaaaataaaaaaaaaa"; let signing_key = SigningKey::random(&mut OsRng); - let (signature, _) = signing_key.sign(&vec![auth_data, hash].concat()); + let (signature, _) = signing_key.sign(&[auth_data, hash].concat()); assert!(verify_signature(hash, auth_data, signing_key, signature)) } @@ -58,11 +58,8 @@ fn test_verify_signature_should_fail_1() { let auth_data = b"dummy auth data"; let wrong_hash: &[u8] = b"definetly not hello world"; let signing_key = SigningKey::random(&mut OsRng); - let (signature, _) = signing_key.sign(&vec![auth_data, wrong_hash].concat()); - assert_eq!( - verify_signature(hash, auth_data, signing_key, signature), - false - ) + let (signature, _) = signing_key.sign(&[auth_data, wrong_hash].concat()); + assert!(!verify_signature(hash, auth_data, signing_key, signature),) } #[test] @@ -71,11 +68,13 @@ fn test_verify_signature_should_fail_2() { let auth_data = b"dummy auth data"; let signing_key = SigningKey::random(&mut OsRng); let other_signing_key = SigningKey::random(&mut OsRng); - let (signature, _) = signing_key.sign(&vec![auth_data, hash].concat()); - assert_eq!( - verify_signature(hash, auth_data, other_signing_key, signature), - false - ) + let (signature, _) = signing_key.sign(&[auth_data, hash].concat()); + assert!(!verify_signature( + hash, + auth_data, + other_signing_key, + signature + )) } proptest! { @@ -90,7 +89,7 @@ proptest! { .prop_map(|b| SigningKey::from(SecretKey::from_bytes(&b.into()).unwrap())) ), ) { - let (signature, _) = signing_key.sign(&vec![auth_data.clone(), hash.clone()].concat()); + let (signature, _) = signing_key.sign(&[auth_data.clone(), hash.clone()].concat()); assert!(verify_signature(&hash, &auth_data, signing_key, signature)) } } diff --git a/crates/webauthn/tests/src/prop_utils.rs b/crates/webauthn/tests/src/prop_utils.rs index abe182e0..0ff6a436 100644 --- a/crates/webauthn/tests/src/prop_utils.rs +++ b/crates/webauthn/tests/src/prop_utils.rs @@ -5,7 +5,7 @@ use proptest::prelude::*; pub struct Felt252Strategy; impl Felt252Strategy { - pub fn new() -> impl Strategy { + pub fn new_strategy() -> impl Strategy { prop::collection::vec(any::(), 32..=32).prop_map(|b| Felt252::from_bytes_be(&b)) } } diff --git a/crates/webauthn/tests/src/session/prop_signature_proofs.rs b/crates/webauthn/tests/src/session/prop_signature_proofs.rs index 021265be..95507b56 100644 --- a/crates/webauthn/tests/src/session/prop_signature_proofs.rs +++ b/crates/webauthn/tests/src/session/prop_signature_proofs.rs @@ -11,7 +11,7 @@ fn vec_vec_felt252_strategy( ) -> impl Strategy>, usize)> { ( prop::collection::vec( - prop::collection::vec(Felt252Strategy::new(), inner_len..=inner_len), + prop::collection::vec(Felt252Strategy::new_strategy(), inner_len..=inner_len), outer_len..=outer_len, ), Just(inner_len), diff --git a/crates/webauthn/tests/src/utils.rs b/crates/webauthn/tests/src/utils.rs index bb6c4f25..e5e70241 100644 --- a/crates/webauthn/tests/src/utils.rs +++ b/crates/webauthn/tests/src/utils.rs @@ -4,8 +4,8 @@ use cairo_args_runner::errors::SierraRunnerError; use cairo_args_runner::SuccessfulRun; use cairo_args_runner::{Arg, Felt252}; -pub const WEBAUTHN_SIERRA_TARGET: &'static str = "../../../target/dev/webauthn_auth.sierra.json"; -pub const SESSION_SIERRA_TARGET: &'static str = "../../../target/dev/webauthn_session.sierra.json"; +pub const WEBAUTHN_SIERRA_TARGET: &str = "../../../target/dev/webauthn_auth.sierra.json"; +pub const SESSION_SIERRA_TARGET: &str = "../../../target/dev/webauthn_session.sierra.json"; #[derive(Debug, Clone, Copy)] pub struct Function<'a, AP, RE>