├── .dockerignore ├── .editorconfig ├── .envrc ├── .github ├── ISSUE_TEMPLATE │ ├── ask-a-question.md │ ├── report-a-bug.md │ └── suggest-a-feature.md ├── dependabot.yml ├── templates │ ├── free-space │ │ └── action.yaml │ └── setup-worker │ │ └── action.yaml └── workflows │ ├── build-runtime.yaml │ ├── build_docker.yml │ ├── check.yml │ ├── publish-docker.yml │ ├── simulate.yml │ └── try-runtime.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── docker ├── scripts │ ├── healthcheck.sh │ └── inject_bootnodes.sh └── trappist-parachain.dockerfile ├── docs ├── media │ ├── trappist-topology.png │ └── xcm-use-cases.png └── rust-setup.md ├── integration-tests ├── README.md ├── asset-registry │ └── 0_reserve_transfer.yml └── asset-trap │ ├── 0_init.yml │ ├── 1_trap_claim_native_asset.yml │ ├── 2_trap_claim_reserved_asset.yml │ └── 3_trap_claim_native_and_reserved.yml ├── node ├── Cargo.toml ├── build.rs ├── src │ ├── benchmarking.rs │ ├── chain_spec │ │ ├── mod.rs │ │ ├── stout.rs │ │ └── trappist.rs │ ├── cli.rs │ ├── command.rs │ ├── main.rs │ ├── rpc.rs │ └── service.rs └── tests │ ├── benchmark_storage_works.rs │ ├── common.rs │ ├── polkadot_argument_parsing.rs │ ├── polkadot_mdns_issue.rs │ ├── purge_chain_works.rs │ └── running_the_node_and_interrupt.rs ├── pallets ├── asset-registry │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── benchmarking.rs │ │ ├── lib.rs │ │ ├── mock.rs │ │ ├── tests.rs │ │ └── weights.rs ├── benchmarks │ ├── Cargo.toml │ └── src │ │ ├── benchmarking.rs │ │ ├── lib.rs │ │ └── weights.rs └── withdraw-teleport │ ├── Cargo.toml │ └── src │ ├── benchmarking.rs │ ├── lib.rs │ ├── mock.rs │ └── weights.rs ├── primitives └── xcm │ ├── Cargo.toml │ └── src │ └── lib.rs ├── runtime ├── stout │ ├── Cargo.toml │ ├── build.rs │ └── src │ │ ├── constants.rs │ │ ├── contracts.rs │ │ ├── lib.rs │ │ └── xcm_config.rs └── trappist │ ├── Cargo.toml │ ├── build.rs │ └── src │ ├── constants.rs │ ├── contracts.rs │ ├── impls.rs │ ├── lib.rs │ ├── weights │ ├── block_weights.rs │ ├── cumulus_pallet_xcmp_queue.rs │ ├── extrinsic_weights.rs │ ├── frame_system.rs │ ├── mod.rs │ ├── pallet_asset_registry.rs │ ├── pallet_assets.rs │ ├── pallet_balances.rs │ ├── pallet_collator_selection.rs │ ├── pallet_collective.rs │ ├── pallet_contracts.rs │ ├── pallet_democracy.rs │ ├── pallet_identity.rs │ ├── pallet_message_queue.rs │ ├── pallet_multisig.rs │ ├── pallet_preimage.rs │ ├── pallet_safe_mode.rs │ ├── pallet_scheduler.rs │ ├── pallet_session.rs │ ├── pallet_timestamp.rs │ ├── pallet_treasury.rs │ ├── pallet_tx_pause.rs │ ├── pallet_uniques.rs │ ├── pallet_utility.rs │ ├── pallet_withdraw_teleport.rs │ ├── trappist_runtime_benchmarks.rs │ └── xcm │ │ ├── mod.rs │ │ ├── pallet_xcm_benchmarks_fungible.rs │ │ └── pallet_xcm_benchmarks_generic.rs │ └── xcm_config.rs ├── rust-toolchain.toml ├── rustfmt.toml ├── scripts ├── docker_run.sh ├── hrmp_helper.sh └── init.sh ├── shell.nix ├── templates ├── file_header.txt ├── frame-weight-template.hbs └── xcm-bench-template.hbs ├── xcm-simulator ├── Cargo.toml └── src │ ├── lib.rs │ ├── parachains │ ├── asset_reserve.rs │ ├── mod.rs │ ├── stout.rs │ ├── template.rs │ └── trappist.rs │ ├── relay_chain.rs │ └── tests │ ├── misc.rs │ ├── mod.rs │ ├── xcm_asset_trap.rs │ └── xcm_use_cases.rs └── zombienet ├── full_network.toml ├── stout_rococo.toml ├── trappist_rococo.toml └── trappist_stout.toml /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | **/*.txt 3 | **/*.md 4 | 5 | # dotfiles in the repo root 6 | /.* 7 | target/ 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style=space 5 | indent_size=2 6 | tab_width=2 7 | end_of_line=lf 8 | charset=utf-8 9 | trim_trailing_whitespace=true 10 | insert_final_newline = true 11 | 12 | [*.{rs,toml}] 13 | indent_style=tab 14 | indent_size=tab 15 | tab_width=4 16 | max_line_length=100 17 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | # If lorri exists, better try it first. 2 | if has lorri; then 3 | eval "$(lorri direnv)" 4 | else 5 | # Otherwise fall back to pure nix 6 | use nix 7 | fi 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/ask-a-question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Ask a Question 3 | about: Ask a question about this template. 4 | title: "" 5 | labels: question 6 | assignees: "" 7 | --- 8 | 9 | **Question** 10 | 11 | _Please include information such as the following: is your question to clarify an existing resource 12 | or are you asking about something new? what are you trying to accomplish? where have you looked for 13 | answers?_ 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/report-a-bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Report a Bug 3 | about: Report a problem with this template. 4 | title: "" 5 | labels: bug 6 | assignees: "" 7 | --- 8 | 9 | **Description** 10 | 11 | _Tell us what happened. In particular, be specific about any changes you made to this template. 12 | Ideally, provide a link to your project's GitHub repository. Please note that we are not able to 13 | support all conceivable changes to this template project, but the more information you are able to 14 | provide the more equipped we will be to help._ 15 | 16 | **Steps to Reproduce** 17 | 18 | _Replace the example steps below with actual steps to reproduce the bug you're reporting._ 19 | 20 | 1. Go to '...' 21 | 2. Click on '....' 22 | 3. Scroll down to '....' 23 | 4. See error 24 | 25 | **Expected vs. Actual Behavior** 26 | 27 | _What did you expect to happen after you followed the steps you described in the last section? What 28 | actually happened?_ 29 | 30 | **Environment** 31 | 32 | _Describe the environment in which you encountered this bug. Use the list below as a starting point 33 | and add additional information if you think it's relevant._ 34 | 35 | - Operating system: 36 | - Template version/tag: 37 | - Rust version (run `rustup show`): 38 | 39 | **Logs, Errors or Screenshots** 40 | 41 | _Please provide the text of any logs or errors that you experienced; if 42 | applicable, provide screenshots to help illustrate the problem._ 43 | 44 | **Additional Information** 45 | 46 | _Please add any other details that you think may help us solve your problem._ 47 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/suggest-a-feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Suggest a Feature 3 | about: Suggest a new feature or an improvement to an existing feature for this template. 4 | title: "" 5 | labels: enhancement 6 | assignees: "" 7 | --- 8 | 9 | **Motivation** 10 | 11 | _Describe the need or frustration that motivated you to make this suggestion. Please note that the 12 | goal of this project is to provide a general-purpose template project, so please take care when 13 | suggesting features that may be specific to a particular use case._ 14 | 15 | **Suggested Solution** 16 | 17 | _Describe your suggested solution to the need or frustration that you are experiencing._ 18 | 19 | **Alternatives** 20 | 21 | _Describe any alternative solutions or features you considered and why you believe your suggested 22 | solution is preferable._ 23 | 24 | **Additional Information** 25 | 26 | _Provide any additional information that you believe may help us evaluate your suggestion._ 27 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: '/' 5 | schedule: 6 | interval: daily 7 | -------------------------------------------------------------------------------- /.github/templates/free-space/action.yaml: -------------------------------------------------------------------------------- 1 | name: free-space 2 | description: | 3 | This action frees up disk space on the runner. 4 | 5 | runs: 6 | using: "composite" 7 | 8 | steps: 9 | - name: Remove Android library 10 | shell: bash 11 | run: sudo rm -rf /usr/local/lib/android 12 | 13 | - name: Remove .NET runtime 14 | shell: bash 15 | run: sudo rm -rf /usr/share/dotnet 16 | 17 | - name: Remove CodeQL 18 | shell: bash 19 | run: sudo rm -rf /opt/hostedtoolcache/CodeQL 20 | 21 | - name: Removes cached Docker images 22 | shell: bash 23 | run: sudo docker image prune --all --force -------------------------------------------------------------------------------- /.github/templates/setup-worker/action.yaml: -------------------------------------------------------------------------------- 1 | name: setup-worker 2 | description: | 3 | This action sets up a worker for use in other actions. It installs the 4 | necessary dependencies for building the project. 5 | 6 | runs: 7 | using: "composite" 8 | 9 | steps: 10 | - name: Setup Ubuntu dependencies 11 | shell: bash 12 | run: sudo apt update && sudo apt install -y git clang curl libssl-dev llvm libudev-dev cmake protobuf-compiler 13 | 14 | - name: Rust Setup 15 | uses: actions-rs/toolchain@v1 16 | with: 17 | profile: minimal 18 | toolchain: stable 19 | target: wasm32-unknown-unknown 20 | override: true 21 | components: rustfmt, clippy, rust-src 22 | -------------------------------------------------------------------------------- /.github/workflows/build-runtime.yaml: -------------------------------------------------------------------------------- 1 | name: Build Deterministic Runtimes 2 | 3 | on: 4 | release: 5 | types: [published] 6 | workflow_dispatch: 7 | 8 | jobs: 9 | srtool: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: write 13 | strategy: 14 | matrix: 15 | runtime: ["trappist", "stout"] 16 | steps: 17 | - name: Checkout sources 18 | uses: actions/checkout@v4 19 | 20 | - name: Cache runtime target dir 21 | uses: actions/cache@v4 22 | with: 23 | path: "${{ github.workspace }}/runtime/${{ matrix.runtime }}/target" 24 | key: srtool-target-${{ matrix.runtime }}-${{ github.sha }} 25 | restore-keys: | 26 | srtool-target-${{ matrix.runtime }}- 27 | srtool-target- 28 | 29 | - name: Build ${{ matrix.runtime }} runtime 30 | id: srtool_build 31 | uses: chevdor/srtool-actions@v0.9.2 32 | with: 33 | chain: ${{ matrix.runtime }} 34 | 35 | - name: Store srtool digest to disk 36 | run: | 37 | echo '${{ steps.srtool_build.outputs.json }}' | jq . > ${{ matrix.runtime }}-srtool-digest.json 38 | 39 | # Manual trigger: add artifacts to run 40 | - name: Copy artifacts 41 | if: github.event_name != 'release' 42 | run: cp `dirname ${{ steps.srtool_build.outputs.wasm }}`/*.wasm ./ 43 | - name: Archive Runtime 44 | if: github.event_name != 'release' 45 | uses: actions/upload-artifact@v4 46 | with: 47 | name: ${{ matrix.runtime }}-runtime-${{ github.sha }} 48 | path: | 49 | ${{ matrix.chain }}*.wasm 50 | ${{ matrix.runtime }}-srtool-digest.json 51 | 52 | # Release published: add artifacts to release 53 | - name: Add artifacts to release 54 | if: github.event_name == 'release' 55 | uses: softprops/action-gh-release@v1 56 | with: 57 | append_body: true 58 | body: | 59 | ## Runtime: `${{ matrix.runtime }}` 60 | ``` 61 | 🏋️ Runtime Size: ${{ fromJSON(steps.srtool_build.outputs.json).runtimes.compressed.subwasm.size }} bytes 62 | 🔥 Core Version: ${{ fromJSON(steps.srtool_build.outputs.json).runtimes.compressed.subwasm.core_version.specName }}-${{ fromJSON(steps.srtool_build.outputs.json).runtimes.compressed.subwasm.core_version.specVersion }} 63 | 🎁 Metadata version: V${{ fromJSON(steps.srtool_build.outputs.json).runtimes.compressed.subwasm.metadata_version }} 64 | 🗳️ system.setCode hash: ${{ fromJSON(steps.srtool_build.outputs.json).runtimes.compressed.subwasm.proposal_hash }} 65 | 🗳️ authorizeUpgrade hash: ${{ fromJSON(steps.srtool_build.outputs.json).runtimes.compressed.subwasm.parachain_authorize_upgrade_hash }} 66 | 🗳️ Blake2-256 hash: ${{ fromJSON(steps.srtool_build.outputs.json).runtimes.compressed.subwasm.blake2_256 }} 67 | 📦 IPFS: ${{ fromJSON(steps.srtool_build.outputs.json).runtimes.compressed.subwasm.ipfs_hash }} 68 | ``` 69 | files: | 70 | ${{ steps.srtool_build.outputs.wasm_compressed }} 71 | ${{ matrix.runtime }}-srtool-digest.json -------------------------------------------------------------------------------- /.github/workflows/build_docker.yml: -------------------------------------------------------------------------------- 1 | name: Build Docker image 2 | 3 | on: 4 | pull_request: 5 | branches: [master] 6 | 7 | jobs: 8 | build_docker: 9 | name: Build Docker image 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Check out the repo 13 | uses: actions/checkout@v4 14 | 15 | - name: Extract metadata (tags, labels) for Docker 16 | id: meta 17 | uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5.5.0 18 | with: 19 | images: paritytech/trappist 20 | 21 | - name: Build Docker image 22 | uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 #v5.1.0 23 | with: 24 | file: docker/trappist-parachain.dockerfile 25 | push: false 26 | tags: ${{ steps.meta.outputs.tags }} 27 | labels: ${{ steps.meta.outputs.labels }} 28 | -------------------------------------------------------------------------------- /.github/workflows/check.yml: -------------------------------------------------------------------------------- 1 | name: Check Build and Tests 2 | 3 | # Controls when the action will run. 4 | on: 5 | # Triggers the workflow on push or pull request events but only for the master branch 6 | push: 7 | branches: [ main ] 8 | pull_request: 9 | 10 | # Allows you to run this workflow manually from the Actions tab 11 | workflow_dispatch: 12 | 13 | env: 14 | CARGO_INCREMENTAL: 0 15 | POLKA_VERSION: 1.0.0 16 | 17 | jobs: 18 | lint: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v4 22 | 23 | - name: Setup worker 24 | uses: "./.github/templates/setup-worker" 25 | 26 | - name: Check formatting 27 | run: cargo fmt --all -- --check 28 | 29 | check: 30 | needs: lint 31 | runs-on: ubuntu-latest 32 | steps: 33 | - uses: actions/checkout@v4 34 | 35 | - name: Setup worker 36 | uses: "./.github/templates/setup-worker" 37 | 38 | - name: Cache Build artefacts 39 | uses: Swatinem/rust-cache@v2.7.3 40 | with: 41 | cache-on-failure: true 42 | shared-key: ${{ env.POLKA_VERSION }}-release 43 | 44 | - name: Check Build Trappist node 45 | run: | 46 | SKIP_WASM_BUILD=1 cargo check --release --locked 47 | 48 | test: 49 | needs: lint 50 | runs-on: ubuntu-latest 51 | steps: 52 | - uses: actions/checkout@v4 53 | 54 | # Tests with benchmarks require a lot of disk space 55 | - name: Free Disk Space 56 | uses: "./.github/templates/free-space" 57 | 58 | - name: Setup worker 59 | uses: "./.github/templates/setup-worker" 60 | 61 | - name: Cache Build artefacts 62 | uses: Swatinem/rust-cache@v2.7.3 63 | with: 64 | cache-on-failure: true 65 | shared-key: ${{ env.POLKA_VERSION }}-debug 66 | 67 | - name: Run Trappist tests 68 | run: | 69 | cargo test --workspace --exclude stout-runtime --no-default-features --features trappist/trappist-runtime,std,runtime-benchmarks --locked --jobs 1 70 | -------------------------------------------------------------------------------- /.github/workflows/publish-docker.yml: -------------------------------------------------------------------------------- 1 | name: Publish Docker image 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | # Allows you to run this workflow manually from the Actions tab 8 | workflow_dispatch: 9 | 10 | jobs: 11 | push_to_registry: 12 | name: Push Docker image to Docker Hub 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Check out the repo 16 | uses: actions/checkout@v4 17 | 18 | - name: Log in to Docker Hub 19 | uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 20 | with: 21 | username: ${{ secrets.DOCKER_USERNAME }} 22 | password: ${{ secrets.DOCKER_PASSWORD }} 23 | 24 | - name: Extract metadata (tags, labels) for Docker 25 | id: meta 26 | uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5.5.0 27 | with: 28 | images: paritytech/trappist 29 | 30 | - name: Build and push Docker image 31 | uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 #v5.1.0 32 | with: 33 | file: docker/trappist-parachain.dockerfile 34 | push: true 35 | tags: ${{ steps.meta.outputs.tags }} 36 | labels: ${{ steps.meta.outputs.labels }} 37 | -------------------------------------------------------------------------------- /.github/workflows/simulate.yml: -------------------------------------------------------------------------------- 1 | name: XCM Simulator 2 | 3 | # Controls when the action will run. 4 | on: 5 | # Triggers the workflow on push or pull request events but only for the master branch 6 | push: 7 | branches: [ master ] 8 | pull_request: 9 | branches: [ master ] 10 | 11 | # Allows you to run this workflow manually from the Actions tab 12 | workflow_dispatch: 13 | 14 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 15 | jobs: 16 | simulate: 17 | # The type of runner that the job will run on 18 | runs-on: ubuntu-20.04 19 | defaults: 20 | run: 21 | working-directory: xcm-simulator 22 | env: 23 | NIGHTLY: nightly-2022-11-02 # Fix version to prevent cache misses with nightly changes 24 | SKIP_WASM_BUILD: '1' # Skip for all steps, so no wasm32-unknown-unknown target required 25 | 26 | # Steps represent a sequence of tasks that will be executed as part of the job 27 | steps: 28 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 29 | - uses: actions/checkout@v4 30 | 31 | - name: Set-Up 32 | run: sudo apt update && sudo apt install -y git clang curl libssl-dev llvm libudev-dev cmake protobuf-compiler 33 | 34 | - name: Install Rust 35 | uses: actions-rs/toolchain@v1 36 | with: 37 | profile: minimal 38 | toolchain: stable 39 | 40 | - name: Install Nightly 41 | uses: actions-rs/toolchain@v1 42 | with: 43 | profile: minimal 44 | toolchain: ${{ env.NIGHTLY }} 45 | override: true 46 | 47 | - name: Cache Build artefacts 48 | uses: actions/cache@v4 49 | with: 50 | path: | 51 | ~/.cargo/bin/ 52 | ~/.cargo/registry/index/ 53 | ~/.cargo/registry/cache/ 54 | ~/.cargo/git/db/ 55 | target/ 56 | xcm-simulator/target/ 57 | key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }} 58 | restore-keys: ${{ runner.os }}-cargo-test 59 | 60 | # Install cargo-nextest, 60% faster than cargo test and support for junit output format 61 | - name: Install cargo-nextest 62 | run: if ! which cargo-nextest &> /dev/null; then cargo install cargo-nextest; fi 63 | 64 | # Create profile with JUnit output enabled 65 | - name: Configure CI 66 | run: mkdir .config && echo -e "[profile.ci.junit]\npath = \"junit.xml\"" > .config/nextest.toml 67 | 68 | # Run all tests in solution using CI profile created above 69 | - name: Run tests 70 | run: cargo nextest run "tests::" --release --profile ci 71 | 72 | # Report test results 73 | - name: Report test results 74 | uses: dorny/test-reporter@v1 75 | if: success() || failure() # run this step even if previous step failed 76 | with: 77 | name: results 78 | path: target/nextest/ci/junit.xml 79 | reporter: jest-junit 80 | working-directory: 'xcm-simulator' 81 | -------------------------------------------------------------------------------- /.github/workflows/try-runtime.yml: -------------------------------------------------------------------------------- 1 | # Test storage migration using try-runtime on PRs with label "migration" 2 | name: Test storage migration 3 | 4 | on: 5 | pull_request: 6 | types: [labeled, synchronize] 7 | push: 8 | branches: [ main ] 9 | 10 | jobs: 11 | try_runtime: 12 | if: contains(github.event.pull_request.labels.*.name, 'migration') 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Check out the repo 16 | uses: actions/checkout@v4 17 | 18 | - name: Setup worker 19 | uses: "./.github/templates/setup-worker" 20 | 21 | - name: Cache Build artefacts 22 | uses: actions/cache/restore@v4 23 | id: cargo-cache 24 | with: 25 | path: | 26 | ~/.cargo/bin/ 27 | ~/.cargo/registry/index/ 28 | ~/.cargo/registry/cache/ 29 | ~/.cargo/git/db/ 30 | target/ 31 | key: ${{ runner.os }}-cargo-release-${{ env.POLKA_VERSION }}-${{ hashFiles('**/Cargo.lock') }} 32 | restore-keys: ${{ runner.os }}-cargo-release-${{ env.POLKA_VERSION }} 33 | 34 | - name: Install try-runtime 35 | run: | 36 | echo "---------- Downloading try-runtime CLI ----------" 37 | curl -sL https://github.com/paritytech/try-runtime-cli/releases/download/v0.4.0/try-runtime-x86_64-unknown-linux-musl -o try-runtime 38 | chmod +x ./try-runtime 39 | 40 | - run: | 41 | echo "Found label runtime_migration. Running tests" 42 | echo "---------- Running try-runtime for Trappist ----------" 43 | cargo build -p trappist --locked --release --no-default-features --features trappist/trappist-runtime,try-runtime && \ 44 | ./try-runtime --runtime ./target/release/wbuild/trappist-runtime/target/wasm32-unknown-unknown/release/trappist_runtime.wasm \ 45 | on-runtime-upgrade --checks pre-and-post --no-idempotency-checks live --uri wss://rococo-trappist-try-runtime-node.parity-chains.parity.io:443 46 | env: 47 | RUST_LOG: remote-ext=debug,runtime=debug 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | **/target/ 4 | # These are backup files generated by rustfmt 5 | **/*.rs.bk 6 | 7 | .DS_Store 8 | 9 | # The cache for docker container dependency 10 | .cargo 11 | 12 | # The cache for chain data in container 13 | .local 14 | 15 | # direnv cache 16 | .direnv 17 | 18 | # Log files 19 | *.log 20 | 21 | # Binaries 22 | **/bin/ 23 | 24 | # zombienet binaries 25 | zombienet-macos 26 | zombienet-linux 27 | 28 | # IDEs 29 | .vscode/ 30 | .idea/ 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Trappist 2 | 3 | [![Check Set-Up & Build](https://github.com/paritytech/trappist/actions/workflows/check.yml/badge.svg)](https://github.com/paritytech/trappist/actions/workflows/check.yml) 4 | [![XCM Simulator](https://github.com/paritytech/trappist/actions/workflows/simulate.yml/badge.svg)](https://github.com/paritytech/trappist/actions/workflows/simulate.yml) 5 | 6 | **Trappist** is a web3 developer playground for experimenting with [cross-chain applications and services](https://polkadot.network/cross-chain-communication/) built on the technologies spearheaded by the [Polkadot Network](https://polkadot.network/), namely: 7 | * [Substrate](https://substrate.io/), a Blockchain framework that enables developers to quickly and easily build future proof blockchains optimized for any use case. 8 | * [Cumulus](https://github.com/paritytech/polkadot-sdk/tree/master/cumulus), a set of tools for writing Substrate-based Polkadot parachains. 9 | * [XCM](https://polkadot.network/cross-chain-communication/), a common language for secure messaging across Polkadot parachains, and with external networks via bridges. 10 | * [Rococo](https://polkadot.network/blog/statemint-becomes-first-common-good-parachain-on-polkadot/), Polkadot’s Parachain Testnet. 11 | * [Statemint](https://polkadot.network/blog/statemint-becomes-first-common-good-parachain-on-polkadot/), Polkadot's common good parachain which provides functionality for deploying and transferring assets — both Fungible and Non-Fungible Tokens (NFTs). 12 | * [Contracts Pallet](https://github.com/paritytech/polkadot-sdk/tree/master/substrate/frame/contracts), enable WebAssembly smart-contracts executions. 13 | * [ink!](https://paritytech.github.io/ink/), an eDSL to write smart contracts in Rust for blockchains built on the Substrate framework. 14 | 15 | Altogether those technologies enable an array of exciting cross-chain applications & services: 16 | 17 | ![XCM use cases](/docs/media/xcm-use-cases.png) 18 | 19 | 20 | This repository contains the source code of **Trappist**, a feature-rich parachain for exploring and learning about cross-chain applications and services, along with a script to run a complete local multi-chain environment that includes: 21 | * Rococo relay-chain 22 | * Statemine common good asset parachain 23 | * Trappist feature-rich parachain 24 | * An additional parachain capable to execute ink! smart contracts. 25 | 26 | All these pre-configured to allow cross-chain communication via XCM messages on HRMP channels. 27 | 28 | ![Trappist topology](/docs/media/trappist-topology.png) 29 | 30 | ### Why "Trappist" ? 31 | 32 | The term **Trappist** refers to a [style of beers](https://en.wikipedia.org/wiki/Trappist_beer) brewed in Abbeys by Trappist monks, and is generally associated with authenticity, craftsmanship, integrity and tradition. Aside from any religious consideration, we like to think we put as much care in crafting Blockchain software as monks brewing high-quality beer 🍺. 33 | 34 | As Trappist breweries are not intended to be profit-making ventures, this project is non-commercial, open-source software focused solely on experimentation and knowledge sharing with people interested in learning about decentralized technologies. 35 | 36 | ## Getting Started 37 | 38 | Follow the steps below to get started. 39 | 40 | ### Build Trappist collator 41 | 42 | #### Using Nix 43 | 44 | Install [nix](https://nixos.org/) and optionally [direnv](https://github.com/direnv/direnv) and 45 | [lorri](https://github.com/target/lorri) for a fully plug and play experience for setting up the 46 | development environment. To get all the correct dependencies activate direnv `direnv allow` and 47 | lorri `lorri shell`. 48 | 49 | #### Rust Setup 50 | 51 | First, complete the [basic Rust setup instructions](./docs/rust-setup.md). 52 | 53 | 54 | #### Build 55 | 56 | Use the following command to build the Trappist collator binary: 57 | 58 | ```bash 59 | cargo build --release 60 | ``` 61 | 62 | ### XCM Playground via Zombienet 63 | 64 | Create a `bin` directory into the root of this repository and place the following binaries inside of it: 65 | - `polkadot` (which you can download from [the releases](https://github.com/paritytech/polkadot-sdk/releases)) 66 | - `polkadot-parachain` (which you will build from [cumulus](https://github.com/paritytech/polkadot-sdk)) 67 | 68 | Download the [latest release of zombienet](https://github.com/paritytech/zombienet/releases/) into the root of this repository and make it executable: 69 | ```bash 70 | $ chmod +x zombienet-linux # OR 71 | $ chmod +x zombienet-macos 72 | ``` 73 | 74 | Then, start the **Trappist** playground with: 75 | ```bash 76 | ./zombienet-linux -p native spawn ./zombienet/trappist_rococo.toml 77 | ``` 78 | You can also run: 79 | ```bash 80 | # To start Trappist and Stout together 81 | ./zombienet-linux -p native spawn ./zombienet/full_network.toml 82 | # To only run stout 83 | ./zombienet-linux -p native spawn ./zombienet/stout_rococo.toml 84 | ``` 85 | ### Integration Tests 86 | [parachains-integration-tests](https://github.com/paritytech/parachains-integration-tests) is a tool meant for XCM message execution in a locally spawned network. Tests are written as YAML files and converted into [Mocha](https://mochajs.org/) tests with [Chai](https://www.chaijs.com/) assertions. 87 | 88 | The [integration-tests](./integration-tests) directory has tests on Trappist use cases and instructions on how to run them. 89 | 90 | ### XCM Simulator 91 | The [XCM simulator](./xcm-simulator) can be used to further explore XCM message execution across the various runtimes used by Trappist. 92 | Each Trappist use case is written as a Rust unit test, allowing interactive debugging/exploration of message flows and instruction execution. 93 | Each `execute_with` closure scope within a test can be considered as a block on the corresponding chain, with messages being dispatched to the destination chains via a mock message queue as the closure goes out of scope. 94 | All XCM-specific traces from the interactions are also collected in a single place for easier inspection. 95 | 96 | You can run all tests with: 97 | ``` 98 | cd xcm-simulator && cargo test --release tests::; cd .. 99 | ``` 100 | 101 | ## License 102 | Trappist is licensed under [Apache 2](LICENSE). 103 | -------------------------------------------------------------------------------- /docker/scripts/healthcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | head () { 6 | polkadot-js-api --ws ws://172.28.1.1:9944 query.parachains.heads 100 |\ 7 | jq -r .heads 8 | } 9 | 10 | start=$(head) 11 | sleep 60 12 | end=$(head) 13 | 14 | [ "$start" != "$end" ] 15 | -------------------------------------------------------------------------------- /docker/scripts/inject_bootnodes.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # this script runs the trappist-node after fetching 4 | # appropriate bootnode IDs 5 | # 6 | # this is _not_ a general-purpose script; it is closely tied to the 7 | # root docker-compose.yml 8 | 9 | set -e -o pipefail 10 | 11 | ctpc="/usr/bin/trappist-node" 12 | 13 | if [ ! -x "$ctpc" ]; then 14 | echo "FATAL: $ctpc does not exist or is not executable" 15 | exit 1 16 | fi 17 | 18 | # name the variable with the incoming args so it isn't overwritten later by function calls 19 | args=( "$@" ) 20 | 21 | alice="172.28.1.1" 22 | bob="172.28.1.2" 23 | p2p_port="30333" 24 | rpc_port="9933" 25 | 26 | 27 | get_id () { 28 | node="$1" 29 | /wait-for-it.sh "$node:$rpc_port" -t 10 -s -- \ 30 | curl -sS \ 31 | -H 'Content-Type: application/json' \ 32 | --data '{"id":1,"jsonrpc":"2.0","method":"system_networkState"}' \ 33 | "$node:$rpc_port" |\ 34 | jq -r '.result.peerId' 35 | } 36 | 37 | bootnode () { 38 | node="$1" 39 | id=$(get_id "$node") 40 | if [ -z "$id" ]; then 41 | echo >&2 "failed to get id for $node" 42 | exit 1 43 | fi 44 | echo "/ip4/$node/tcp/$p2p_port/p2p/$id" 45 | } 46 | 47 | args+=( "--" "--bootnodes=$(bootnode "$alice")" "--bootnodes=$(bootnode "$bob")" ) 48 | 49 | set -x 50 | "$ctpc" "${args[@]}" 51 | -------------------------------------------------------------------------------- /docker/trappist-parachain.dockerfile: -------------------------------------------------------------------------------- 1 | # This file is sourced from https://github.com/paritytech/polkadot-sdk/blob/master/scripts/ci/dockerfiles/polkadot/polkadot_builder.Dockerfile 2 | FROM docker.io/paritytech/ci-unified:latest as builder 3 | 4 | WORKDIR /trappist 5 | COPY . /trappist 6 | 7 | RUN cargo build --release 8 | 9 | # the collator stage is normally built once, cached, and then ignored, but can 10 | # be specified with the --target build flag. This adds some extra tooling to the 11 | # image, which is required for a launcher script. The script simply adds two 12 | # arguments to the list passed in: 13 | # 14 | # --bootnodes /ip4/127.0.0.1/tcp/30333/p2p/PEER_ID 15 | # 16 | # with the appropriate ip and ID for both Alice and Bob 17 | FROM debian:bullseye-slim as collator 18 | RUN apt-get update && apt-get install jq curl bash -y && \ 19 | curl -sSo /wait-for-it.sh https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh && \ 20 | chmod +x /wait-for-it.sh && \ 21 | curl -sL https://deb.nodesource.com/setup_12.x | bash - && \ 22 | apt-get install -y nodejs && \ 23 | npm install --global yarn && \ 24 | yarn global add @polkadot/api-cli@0.10.0-beta.14 25 | COPY --from=builder \ 26 | /trappist/target/release/trappist-node /usr/bin 27 | COPY ./docker/scripts/inject_bootnodes.sh /usr/bin 28 | CMD ["/usr/bin/inject_bootnodes.sh"] 29 | COPY ./docker/scripts/healthcheck.sh /usr/bin/ 30 | HEALTHCHECK --interval=300s --timeout=75s --start-period=30s --retries=3 \ 31 | CMD ["/usr/bin/healthcheck.sh"] 32 | 33 | # the runtime stage is normally built once, cached, and ignored, but can be 34 | # specified with the --target build flag. This just preserves one of the builder's 35 | # outputs, which can then be moved into a volume at runtime 36 | FROM debian:bullseye-slim as runtime 37 | COPY --from=builder \ 38 | /trappist/target/release/wbuild/trappist-runtime/trappist_runtime.wasm \ 39 | /var/opt/ 40 | CMD ["cp", "-v", "/var/opt/trappist_runtime.wasm", "/runtime/"] 41 | 42 | FROM debian:bullseye-slim 43 | COPY --from=builder \ 44 | /trappist/target/release/trappist-node /usr/bin 45 | 46 | CMD ["/usr/bin/trappist-node"] 47 | -------------------------------------------------------------------------------- /docs/media/trappist-topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paritytech/trappist/a07b7e84224c53d16dbd1d5e3fb8797f33d12723/docs/media/trappist-topology.png -------------------------------------------------------------------------------- /docs/media/xcm-use-cases.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paritytech/trappist/a07b7e84224c53d16dbd1d5e3fb8797f33d12723/docs/media/xcm-use-cases.png -------------------------------------------------------------------------------- /integration-tests/README.md: -------------------------------------------------------------------------------- 1 | [`parachains-integration-tests`](https://github.com/paritytech/parachains-integration-tests) is a tool designed to test interactions between Substrate blockchains. 2 | 3 | Trappist uses it to ensure the correctness of some of its features. 4 | 5 | # Setup 6 | 7 | Install `parachains-integration-tests` into your system: 8 | ``` 9 | $ yarn global add @parity/parachains-integration-tests 10 | ``` 11 | 12 | # Usage 13 | 14 | Please refer to the [project's `README.md`](https://github.com/paritytech/parachains-integration-tests#how-to-use) for an extensive description of how to write YAML test files and how to execute tests. 15 | 16 | For example, to use zombienet and perform a reserve transfer that tests the functionality of `asset-registry` pallet: 17 | ``` 18 | $ parachains-integration-tests -m zombienet-test -c xcm-playground.toml -t integration-tests/asset-registry/0_reserve_transfer.yml 19 | ``` 20 | -------------------------------------------------------------------------------- /integration-tests/asset-trap/1_trap_claim_native_asset.yml: -------------------------------------------------------------------------------- 1 | --- 2 | settings: 3 | chains: 4 | relay_chain: 5 | wsPort: 9900 6 | trappist_parachain: &trappist_parachain 7 | wsPort: 9920 8 | variables: 9 | common: 10 | amount_to_trap: &amount_to_trap 10000000000000 11 | require_weight_at_most: &weight_at_most [ 2000000000 ] 12 | chains: 13 | trappist_parachain: 14 | signer: &tp_signer //Alice 15 | bob_account: &tp_bob_acc '0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48' 16 | 17 | tests: 18 | - name: Simplest possible way to trap and claim a native asset 19 | its: 20 | - name: Trap native asset 21 | actions: 22 | - extrinsics: 23 | - chain: *trappist_parachain 24 | signer: *tp_signer 25 | pallet: polkadotXcm 26 | call: execute 27 | args: [ 28 | { 29 | v2: [ 30 | { 31 | WithdrawAsset: [ 32 | { 33 | id: { 34 | Concrete: { 35 | parents: 0, 36 | interior: Here 37 | } 38 | }, 39 | fun: { 40 | Fungible: *amount_to_trap 41 | } 42 | } 43 | ] 44 | }, 45 | ] 46 | }, 47 | *weight_at_most, # maxWeight 48 | ] 49 | events: 50 | - name: polkadotXcm.Attempted 51 | attributes: 52 | - type: XcmV2TraitsOutcome 53 | xcmOutcome: Complete 54 | value: 1,000,000,000 55 | 56 | - name: polkadotXcm.AssetsTrapped 57 | attributes: 58 | - type: XcmV1MultiLocation 59 | value: { 60 | parents: 0, 61 | interior: 62 | {X1: 63 | {AccountId32: 64 | { 65 | network: "Polkadot", 66 | id: "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d" 67 | } 68 | } 69 | } 70 | } 71 | - type: XcmVersionedMultiAssets 72 | value: { 73 | V1: [ 74 | { 75 | id: { Concrete: {parents: 0, interior: Here}}, 76 | fun: { Fungible: *amount_to_trap} 77 | } 78 | ] 79 | } 80 | 81 | - name: Claim native asset 82 | actions: 83 | - extrinsics: 84 | - chain: *trappist_parachain 85 | signer: *tp_signer 86 | pallet: polkadotXcm 87 | call: execute 88 | args: [ 89 | { 90 | v2: [ 91 | { 92 | ClaimAsset: { 93 | assets: [ 94 | { 95 | id: { 96 | Concrete: { 97 | parents: 0, 98 | interior: Here 99 | } 100 | }, 101 | fun: { 102 | Fungible: *amount_to_trap 103 | } 104 | } 105 | ], 106 | ticket: { 107 | parents: 0, 108 | interior: { 109 | Here 110 | } 111 | } 112 | } 113 | }, 114 | { 115 | DepositAsset: { 116 | assets: { 117 | Wild: All 118 | }, 119 | maxAssets: 1, 120 | beneficiary: { 121 | parents: 0, 122 | interior: { 123 | X1: { 124 | AccountId32: { 125 | network: null, 126 | id: *tp_bob_acc 127 | } 128 | } 129 | } 130 | } 131 | } 132 | } 133 | ] 134 | }, 135 | *weight_at_most, 136 | ] 137 | events: 138 | - name: polkadotXcm.Attempted 139 | attributes: 140 | - type: XcmV2TraitsOutcome 141 | xcmOutcome: Complete 142 | value: 2,000,000,000 143 | - name: polkadotXcm.AssetsClaimed 144 | attributes: 145 | - type: XcmV1MultiLocation 146 | value: { 147 | parents: 0, 148 | interior: 149 | {X1: 150 | {AccountId32: 151 | { 152 | network: Polkadot, id: "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d" 153 | } 154 | } 155 | } 156 | } 157 | - type: XcmVersionedMultiAssets 158 | value: { 159 | V1: [ 160 | { 161 | id: {Concrete: {parents: 0, interior: Here}}, 162 | fun: {Fungible: *amount_to_trap} 163 | } 164 | ] 165 | } 166 | -------------------------------------------------------------------------------- /node/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "trappist" 3 | version = "1.0.0" 4 | description = "A versatile Proof-of-Authority (PoA) Blockchain network." 5 | authors = { workspace = true } 6 | license = { workspace = true } 7 | homepage = { workspace = true } 8 | repository = { workspace = true } 9 | edition = { workspace = true } 10 | default-run = "trappist-node" 11 | 12 | [package.metadata.docs.rs] 13 | targets = ["x86_64-unknown-linux-gnu"] 14 | 15 | [[bin]] 16 | name = "trappist-node" 17 | path = "src/main.rs" 18 | 19 | [dependencies] 20 | async-trait = { workspace = true } 21 | clap = { workspace = true } 22 | parity-scale-codec = { workspace = true } 23 | futures = { workspace = true } 24 | hex-literal = { workspace = true } 25 | log = { workspace = true, features = ["std"] } 26 | serde = { workspace = true } 27 | serde_json = { workspace = true } 28 | 29 | # Local Dependencies 30 | trappist-runtime = { workspace = true, optional = true } 31 | stout-runtime = { workspace = true, optional = true } 32 | jsonrpsee = { workspace = true, features = ["server"] } 33 | 34 | # Substrate 35 | frame-benchmarking = { workspace = true, features = ["std"] } 36 | frame-benchmarking-cli = { workspace = true } 37 | sp-runtime = { workspace = true } 38 | sp-io = { workspace = true, features = ["std"] } 39 | sp-core = { workspace = true, features = ["std"] } 40 | sp-consensus = { workspace = true } 41 | sp-session = { workspace = true, features = ["std"] } 42 | sc-consensus = { workspace = true } 43 | sc-cli = { workspace = true } 44 | sc-client-api = { workspace = true } 45 | sc-executor = { workspace = true } 46 | sc-service = { workspace = true } 47 | sc-telemetry = { workspace = true } 48 | sc-transaction-pool = { workspace = true } 49 | sp-transaction-pool = { workspace = true, features = ["std"] } 50 | sc-network = { workspace = true } 51 | sc-network-sync = { workspace = true } 52 | sc-basic-authorship = { workspace = true } 53 | sp-timestamp = { workspace = true, features = ["std"] } 54 | sp-inherents = { workspace = true } 55 | sp-blockchain = { workspace = true } 56 | sp-block-builder = { workspace = true, features = ["std"] } 57 | sp-keyring = { workspace = true } 58 | sp-keystore = { workspace = true, features = ["std"] } 59 | sc-chain-spec = { workspace = true } 60 | sc-rpc = { workspace = true } 61 | sc-tracing = { workspace = true } 62 | sp-offchain = { workspace = true, features = ["std"] } 63 | sp-api = { workspace = true, features = ["std"] } 64 | sp-consensus-aura = { workspace = true, features = ["std"] } 65 | sc-sysinfo = { workspace = true } 66 | substrate-prometheus-endpoint = { workspace = true } 67 | sc-transaction-pool-api = { workspace = true } 68 | frame-system = { workspace = true } 69 | substrate-frame-rpc-system = { workspace = true } 70 | pallet-asset-tx-payment = { workspace = true } 71 | pallet-transaction-payment-rpc = { workspace = true } 72 | substrate-state-trie-migration-rpc = { workspace = true } 73 | 74 | # Polkadot 75 | polkadot-cli = { workspace = true } 76 | polkadot-primitives = { workspace = true } 77 | polkadot-service = { workspace = true } 78 | xcm = { workspace = true, features = ["std"] } 79 | 80 | # Cumulus 81 | cumulus-client-cli = { workspace = true } 82 | cumulus-client-collator = { workspace = true } 83 | cumulus-client-consensus-aura = { workspace = true } 84 | cumulus-client-consensus-relay-chain = { workspace = true } 85 | cumulus-client-consensus-common = { workspace = true } 86 | cumulus-client-consensus-proposer = { workspace = true } 87 | cumulus-client-service = { workspace = true } 88 | cumulus-client-network = { workspace = true } 89 | cumulus-primitives-core = { workspace = true, features = ["std"] } 90 | cumulus-primitives-parachain-inherent = { workspace = true } 91 | cumulus-relay-chain-interface = { workspace = true } 92 | 93 | parachains-common = { workspace = true } 94 | 95 | [build-dependencies] 96 | substrate-build-script-utils = { workspace = true } 97 | 98 | [dev-dependencies] 99 | assert_cmd = { workspace = true } 100 | nix = { workspace = true } 101 | tempfile = "3.3.0" 102 | tokio = { workspace = true } 103 | wait-timeout = { workspace = true } 104 | # purge_chain_works works with rococo-local and needs to allow this 105 | polkadot-cli = { workspace = true } 106 | 107 | [features] 108 | default = ["trappist-runtime", "stout-runtime"] 109 | runtime-benchmarks = [ 110 | "trappist-runtime/runtime-benchmarks", 111 | "frame-benchmarking-cli/runtime-benchmarks", 112 | "stout-runtime/runtime-benchmarks", 113 | "polkadot-cli/runtime-benchmarks" 114 | ] 115 | try-runtime = [ 116 | "trappist-runtime/try-runtime", 117 | ] 118 | parameterized-consensus-hook = [] 119 | -------------------------------------------------------------------------------- /node/build.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed}; 19 | 20 | fn main() { 21 | generate_cargo_keys(); 22 | rerun_if_git_head_changed(); 23 | } 24 | -------------------------------------------------------------------------------- /node/src/chain_spec/mod.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use parachains_common::{AccountId, Signature}; 19 | use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup}; 20 | use serde::{Deserialize, Serialize}; 21 | use sp_core::{Pair, Public}; 22 | use sp_runtime::traits::{IdentifyAccount, Verify}; 23 | 24 | #[cfg(feature = "stout-runtime")] 25 | pub mod stout; 26 | 27 | #[cfg(feature = "trappist-runtime")] 28 | pub mod trappist; 29 | 30 | /// The default XCM version to set in genesis config. 31 | const SAFE_XCM_VERSION: u32 = xcm::prelude::XCM_VERSION; 32 | 33 | /// Generic extensions for Parachain ChainSpecs. 34 | #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)] 35 | #[serde(deny_unknown_fields)] 36 | pub struct Extensions { 37 | /// The relay chain of the Parachain. 38 | pub relay_chain: String, 39 | /// The id of the Parachain. 40 | pub para_id: u32, 41 | } 42 | 43 | impl Extensions { 44 | /// Try to get the extension from the given `ChainSpec`. 45 | pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> { 46 | sc_chain_spec::get_extension(chain_spec.extensions()) 47 | } 48 | } 49 | 50 | /// Helper function to generate a crypto pair from seed 51 | pub fn get_public_from_seed(seed: &str) -> ::Public { 52 | TPublic::Pair::from_string(&format!("//{seed}"), None) 53 | .expect("static values are valid; qed") 54 | .public() 55 | } 56 | 57 | type AccountPublic = ::Signer; 58 | 59 | /// Helper function to generate an account ID from seed 60 | pub fn get_account_id_from_seed(seed: &str) -> AccountId 61 | where 62 | AccountPublic: From<::Public>, 63 | { 64 | AccountPublic::from(get_public_from_seed::(seed)).into_account() 65 | } 66 | 67 | /// Generate collator keys from seed. 68 | /// 69 | /// This function's return type must always match the session keys of the chain in tuple format. 70 | pub fn get_collator_keys_from_seed(seed: &str) -> ::Public { 71 | get_public_from_seed::(seed) 72 | } 73 | -------------------------------------------------------------------------------- /node/src/chain_spec/stout.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use crate::chain_spec::{ 19 | get_account_id_from_seed, get_collator_keys_from_seed, Extensions, SAFE_XCM_VERSION, 20 | }; 21 | use cumulus_primitives_core::ParaId; 22 | 23 | use sc_service::ChainType; 24 | 25 | use sp_core::sr25519; 26 | use stout_runtime::{ 27 | constants::currency::EXISTENTIAL_DEPOSIT, AccountId, AuraId, Balance, SessionKeys, 28 | }; 29 | 30 | const DEFAULT_PROTOCOL_ID: &str = "stout"; 31 | 32 | /// Specialized `ChainSpec` for the normal parachain runtime. 33 | pub type ChainSpec = sc_service::GenericChainSpec; 34 | 35 | const STOUT_PARA_ID: u32 = 3000; 36 | 37 | /// Generate the session keys from individual elements. 38 | /// 39 | /// The input must be a tuple of individual keys (a single arg for now since we have just one key). 40 | fn session_keys(aura: AuraId) -> SessionKeys { 41 | SessionKeys { aura } 42 | } 43 | 44 | pub fn stout_local_testnet_config() -> ChainSpec { 45 | // Give your stout currency a unit name and decimal places 46 | let mut properties = sc_chain_spec::Properties::new(); 47 | properties.insert("tokenSymbol".into(), "STOUT".into()); 48 | properties.insert("tokenDecimals".into(), 12.into()); 49 | properties.insert("ss58Format".into(), 42.into()); 50 | 51 | ChainSpec::builder( 52 | trappist_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), 53 | Extensions { 54 | relay_chain: "rococo-local".into(), // You MUST set this to the correct network! 55 | para_id: STOUT_PARA_ID, 56 | }, 57 | ) 58 | .with_name("Stout Local") 59 | .with_id("stout_local") 60 | .with_chain_type(ChainType::Local) 61 | .with_genesis_config_patch(testnet_genesis( 62 | // initial collators. 63 | vec![ 64 | ( 65 | get_account_id_from_seed::("Alice"), 66 | get_collator_keys_from_seed::("Alice"), 67 | ), 68 | ( 69 | get_account_id_from_seed::("Bob"), 70 | get_collator_keys_from_seed::("Bob"), 71 | ), 72 | ], 73 | vec![ 74 | get_account_id_from_seed::("Alice"), 75 | get_account_id_from_seed::("Bob"), 76 | get_account_id_from_seed::("Charlie"), 77 | get_account_id_from_seed::("Dave"), 78 | get_account_id_from_seed::("Eve"), 79 | get_account_id_from_seed::("Ferdie"), 80 | ], 81 | get_account_id_from_seed::("Alice"), 82 | STOUT_PARA_ID.into(), 83 | )) 84 | .with_protocol_id(DEFAULT_PROTOCOL_ID) 85 | .with_properties(properties) 86 | .build() 87 | } 88 | 89 | /// Configure initial storage state for FRAME modules. 90 | pub fn testnet_genesis( 91 | invulnerables: Vec<(AccountId, AuraId)>, 92 | endowed_accounts: Vec, 93 | root_key: AccountId, 94 | id: ParaId, 95 | ) -> serde_json::Value { 96 | let balances: Vec<(sp_runtime::AccountId32, Balance)> = endowed_accounts 97 | .iter() 98 | .map(|x| (x.clone(), 1_000_000_000_000_000_000)) 99 | .collect::>(); 100 | serde_json::json!({ 101 | "balances": { 102 | "balances": balances 103 | }, 104 | "parachainInfo": { 105 | "parachainId": id, 106 | }, 107 | "collatorSelection": { 108 | "invulnerables": invulnerables.iter().cloned().map(|(acc, _)| acc).collect::>(), 109 | "candidacyBond": EXISTENTIAL_DEPOSIT * 16, 110 | }, 111 | "session": { 112 | "keys": invulnerables 113 | .into_iter() 114 | .map(|(acc, aura)| { 115 | ( 116 | acc.clone(), // account id 117 | acc, // validator id 118 | session_keys(aura), // session keys 119 | ) 120 | }) 121 | .collect::>(), 122 | }, 123 | "sudo": { "key": Some(root_key) }, 124 | "polkadotXcm": { 125 | "safeXcmVersion": Some(SAFE_XCM_VERSION), 126 | }, 127 | } 128 | ) 129 | } 130 | -------------------------------------------------------------------------------- /node/src/cli.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use std::path::PathBuf; 19 | 20 | /// Sub-commands supported by the collator. 21 | #[derive(Debug, clap::Subcommand)] 22 | pub enum Subcommand { 23 | /// Key management CLI utilities 24 | #[command(subcommand)] 25 | Key(sc_cli::KeySubcommand), 26 | 27 | /// Build a chain specification. 28 | BuildSpec(sc_cli::BuildSpecCmd), 29 | 30 | /// Validate blocks. 31 | CheckBlock(sc_cli::CheckBlockCmd), 32 | 33 | /// Export blocks. 34 | ExportBlocks(sc_cli::ExportBlocksCmd), 35 | 36 | /// Export the state of a given block into a chain spec. 37 | ExportState(sc_cli::ExportStateCmd), 38 | 39 | /// Import blocks. 40 | ImportBlocks(sc_cli::ImportBlocksCmd), 41 | 42 | /// Revert the chain to a previous state. 43 | Revert(sc_cli::RevertCmd), 44 | 45 | /// Remove the whole chain. 46 | PurgeChain(cumulus_client_cli::PurgeChainCmd), 47 | 48 | /// Export the genesis state of the parachain. 49 | ExportGenesisState(cumulus_client_cli::ExportGenesisStateCommand), 50 | 51 | /// Export the genesis wasm of the parachain. 52 | ExportGenesisWasm(cumulus_client_cli::ExportGenesisWasmCommand), 53 | 54 | /// Sub-commands concerned with benchmarking. 55 | /// The pallet benchmarking moved to the `pallet` sub-command. 56 | #[command(subcommand)] 57 | Benchmark(frame_benchmarking_cli::BenchmarkCmd), 58 | } 59 | 60 | #[derive(Debug, clap::Parser)] 61 | #[command( 62 | propagate_version = true, 63 | args_conflicts_with_subcommands = true, 64 | subcommand_negates_reqs = true 65 | )] 66 | pub struct Cli { 67 | #[command(subcommand)] 68 | pub subcommand: Option, 69 | 70 | #[command(flatten)] 71 | pub run: cumulus_client_cli::RunCmd, 72 | 73 | /// Disable automatic hardware benchmarks. 74 | /// 75 | /// By default these benchmarks are automatically ran at startup and measure 76 | /// the CPU speed, the memory bandwidth and the disk speed. 77 | /// 78 | /// The results are then printed out in the logs, and also sent as part of 79 | /// telemetry, if telemetry is enabled. 80 | #[arg(long)] 81 | pub no_hardware_benchmarks: bool, 82 | 83 | /// Relay chain arguments 84 | #[arg(raw = true)] 85 | pub relaychain_args: Vec, 86 | } 87 | 88 | #[derive(Debug)] 89 | pub struct RelayChainCli { 90 | /// The actual relay chain cli object. 91 | pub base: polkadot_cli::RunCmd, 92 | 93 | /// Optional chain id that should be passed to the relay chain. 94 | pub chain_id: Option, 95 | 96 | /// The base path that should be used by the relay chain. 97 | pub base_path: Option, 98 | } 99 | 100 | impl RelayChainCli { 101 | /// Parse the relay chain CLI parameters using the para chain `Configuration`. 102 | pub fn new<'a>( 103 | para_config: &sc_service::Configuration, 104 | relay_chain_args: impl Iterator, 105 | ) -> Self { 106 | let extension = crate::chain_spec::Extensions::try_get(&*para_config.chain_spec); 107 | let chain_id = extension.map(|e| e.relay_chain.clone()); 108 | let base_path = para_config.base_path.path().join("polkadot"); 109 | Self { 110 | base_path: Some(base_path), 111 | chain_id, 112 | base: clap::Parser::parse_from(relay_chain_args), 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /node/src/main.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! Trappist Node CLI. 19 | 20 | #![warn(missing_docs)] 21 | #![warn(unused_extern_crates)] 22 | 23 | mod chain_spec; 24 | #[macro_use] 25 | mod service; 26 | mod benchmarking; 27 | mod cli; 28 | mod command; 29 | mod rpc; 30 | 31 | fn main() -> sc_cli::Result<()> { 32 | command::run() 33 | } 34 | -------------------------------------------------------------------------------- /node/src/rpc.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #![warn(missing_docs)] 19 | 20 | use std::sync::Arc; 21 | 22 | use parachains_common::{AccountId, Balance, Block, Nonce}; 23 | use sc_client_api::AuxStore; 24 | pub use sc_rpc::DenyUnsafe; 25 | use sc_transaction_pool_api::TransactionPool; 26 | use sp_api::ProvideRuntimeApi; 27 | use sp_block_builder::BlockBuilder; 28 | use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; 29 | 30 | /// A type representing all RPC extensions. 31 | pub type RpcExtension = jsonrpsee::RpcModule<()>; 32 | 33 | /// Full client dependencies 34 | pub struct FullDeps { 35 | /// The client instance to use. 36 | pub client: Arc, 37 | /// Transaction pool instance. 38 | pub pool: Arc

, 39 | /// Whether to deny unsafe calls 40 | pub deny_unsafe: DenyUnsafe, 41 | } 42 | 43 | /// Instantiate all RPC extensions. 44 | pub fn create_full( 45 | deps: FullDeps, 46 | backend: Arc, 47 | ) -> Result> 48 | where 49 | C: ProvideRuntimeApi 50 | + HeaderBackend 51 | + AuxStore 52 | + HeaderMetadata 53 | + Send 54 | + Sync 55 | + 'static, 56 | C::Api: substrate_frame_rpc_system::AccountNonceApi, 57 | C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, 58 | C::Api: BlockBuilder, 59 | P: TransactionPool + Sync + Send + 'static, 60 | B: sc_client_api::Backend + Send + Sync + 'static, 61 | B::State: sc_client_api::backend::StateBackend>, 62 | { 63 | use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; 64 | use substrate_frame_rpc_system::{System, SystemApiServer}; 65 | use substrate_state_trie_migration_rpc::{StateMigration, StateMigrationApiServer}; 66 | 67 | let mut module = RpcExtension::new(()); 68 | let FullDeps { client, pool, deny_unsafe } = deps; 69 | 70 | module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?; 71 | module.merge(TransactionPayment::new(client.clone()).into_rpc())?; 72 | module.merge(StateMigration::new(client.clone(), backend, deny_unsafe).into_rpc())?; 73 | 74 | Ok(module) 75 | } 76 | -------------------------------------------------------------------------------- /node/tests/benchmark_storage_works.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #![cfg(feature = "runtime-benchmarks")] 19 | 20 | use assert_cmd::cargo::cargo_bin; 21 | use std::{ 22 | path::Path, 23 | process::{Command, ExitStatus}, 24 | }; 25 | use tempfile::tempdir; 26 | 27 | /// The runtimes that this command supports. 28 | static RUNTIMES: [&'static str; 3] = ["westmint", "statemine", "statemint"]; 29 | 30 | /// The `benchmark storage` command works for the dev runtimes. 31 | #[test] 32 | #[ignore] 33 | fn benchmark_storage_works() { 34 | for runtime in RUNTIMES { 35 | let tmp_dir = tempdir().expect("could not create a temp dir"); 36 | let base_path = tmp_dir.path(); 37 | let runtime = format!("{}-dev", runtime); 38 | 39 | // Benchmarking the storage works and creates the weight file. 40 | assert!(benchmark_storage("rocksdb", &runtime, base_path).success()); 41 | assert!(base_path.join("rocksdb_weights.rs").exists()); 42 | 43 | assert!(benchmark_storage("paritydb", &runtime, base_path).success()); 44 | assert!(base_path.join("paritydb_weights.rs").exists()); 45 | } 46 | } 47 | 48 | /// Invoke the `benchmark storage` sub-command for the given database and runtime. 49 | fn benchmark_storage(db: &str, runtime: &str, base_path: &Path) -> ExitStatus { 50 | Command::new(cargo_bin("polkadot-parachain")) 51 | .args(&["benchmark", "storage", "--chain", runtime]) 52 | .arg("--db") 53 | .arg(db) 54 | .arg("--weight-path") 55 | .arg(base_path) 56 | .args(["--state-version", "0"]) 57 | .args(["--warmups", "0"]) 58 | .args(["--add", "100", "--mul", "1.2", "--metric", "p75"]) 59 | .status() 60 | .unwrap() 61 | } 62 | -------------------------------------------------------------------------------- /node/tests/common.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #![cfg(unix)] 19 | 20 | use assert_cmd::cargo::cargo_bin; 21 | use nix::{ 22 | sys::signal::{kill, Signal}, 23 | unistd::Pid, 24 | }; 25 | use std::{ 26 | io::{BufRead, BufReader, Read}, 27 | ops::{Deref, DerefMut}, 28 | path::Path, 29 | process::{self, Child, Command, ExitStatus}, 30 | }; 31 | use tokio::time::{sleep, Duration}; 32 | 33 | /// Wait for the given `child` the given number of `secs`. 34 | /// 35 | /// Returns the `Some(exit status)` or `None` if the process did not finish in the given time. 36 | pub fn wait_for(child: &mut Child, secs: u64) -> Result { 37 | let result = wait_timeout::ChildExt::wait_timeout(child, Duration::from_secs(5.min(secs))) 38 | .map_err(|_| ())?; 39 | if let Some(exit_status) = result { 40 | Ok(exit_status) 41 | } else { 42 | if secs > 5 { 43 | eprintln!("Child process taking over 5 seconds to exit gracefully"); 44 | let result = wait_timeout::ChildExt::wait_timeout(child, Duration::from_secs(secs - 5)) 45 | .map_err(|_| ())?; 46 | if let Some(exit_status) = result { 47 | return Ok(exit_status); 48 | } 49 | } 50 | eprintln!("Took too long to exit (> {} seconds). Killing...", secs); 51 | let _ = child.kill(); 52 | child.wait().unwrap(); 53 | Err(()) 54 | } 55 | } 56 | 57 | /// Run the node for a while (till the RPC is up + 30 secs) 58 | /// TODO: needs to be revisited to hit the RPC 59 | pub async fn run_node_for_a_while(base_path: &Path, args: &[&str], signal: Signal) { 60 | let mut cmd = Command::new(cargo_bin("polkadot-parachain")) 61 | .stdout(process::Stdio::piped()) 62 | .stderr(process::Stdio::piped()) 63 | .arg("-d") 64 | .arg(base_path) 65 | .args(args) 66 | .spawn() 67 | .unwrap(); 68 | 69 | let stderr = cmd.stderr.take().unwrap(); 70 | 71 | let mut child = KillChildOnDrop(cmd); 72 | // TODO: use this instead of the timeout going forward? 73 | let (_, _) = find_ws_url_from_output(stderr); 74 | 75 | // TODO: Revisit this to find a better approach for collators 76 | sleep(Duration::from_secs(120)).await; 77 | 78 | assert!(child.try_wait().unwrap().is_none(), "the process should still be running"); 79 | 80 | // Stop the process 81 | kill(Pid::from_raw(child.id().try_into().unwrap()), signal).unwrap(); 82 | assert!(wait_for(&mut child, 40).map(|x| x.success()).unwrap()); 83 | } 84 | 85 | pub struct KillChildOnDrop(pub Child); 86 | 87 | impl Drop for KillChildOnDrop { 88 | fn drop(&mut self) { 89 | let _ = self.0.kill(); 90 | } 91 | } 92 | 93 | impl Deref for KillChildOnDrop { 94 | type Target = Child; 95 | 96 | fn deref(&self) -> &Self::Target { 97 | &self.0 98 | } 99 | } 100 | 101 | impl DerefMut for KillChildOnDrop { 102 | fn deref_mut(&mut self) -> &mut Self::Target { 103 | &mut self.0 104 | } 105 | } 106 | 107 | /// Read the WS address from the output. 108 | /// 109 | /// This is hack to get the actual bound sockaddr because 110 | /// substrate assigns a random port if the specified port was already bound. 111 | pub fn find_ws_url_from_output(read: impl Read + Send) -> (String, String) { 112 | let mut data = String::new(); 113 | 114 | let ws_url = BufReader::new(read) 115 | .lines() 116 | .find_map(|line| { 117 | let line = 118 | line.expect("failed to obtain next line from stdout for WS address discovery"); 119 | 120 | data.push_str(&line); 121 | data.push_str("\n"); 122 | 123 | // does the line contain our port (we expect this specific output from substrate). 124 | let sock_addr = match line.split_once("Running JSON-RPC WS server: addr=") { 125 | None => return None, 126 | Some((_, after)) => after.split_once(",").unwrap().0, 127 | }; 128 | 129 | Some(format!("ws://{}", sock_addr)) 130 | }) 131 | .unwrap_or_else(|| { 132 | eprintln!("Output:\n{}", data); 133 | panic!("We should get a WebSocket address") 134 | }); 135 | 136 | (ws_url, data) 137 | } 138 | -------------------------------------------------------------------------------- /node/tests/polkadot_argument_parsing.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use tempfile::tempdir; 19 | 20 | mod common; 21 | 22 | #[tokio::test] 23 | #[cfg(unix)] 24 | #[ignore] 25 | async fn polkadot_argument_parsing() { 26 | use nix::sys::signal::Signal::{SIGINT, SIGTERM}; 27 | let base_dir = tempdir().expect("could not create a temp dir"); 28 | 29 | let args = &[ 30 | "--", 31 | "--dev", 32 | "--bootnodes", 33 | "/ip4/127.0.0.1/tcp/30333/p2p/Qmbx43psh7LVkrYTRXisUpzCubbgYojkejzAgj5mteDnxy", 34 | "--bootnodes", 35 | "/ip4/127.0.0.1/tcp/50500/p2p/Qma6SpS7tzfCrhtgEVKR9Uhjmuv55ovC3kY6y6rPBxpWde", 36 | ]; 37 | 38 | common::run_node_for_a_while(base_dir.path(), args, SIGINT).await; 39 | common::run_node_for_a_while(base_dir.path(), args, SIGTERM).await; 40 | } 41 | -------------------------------------------------------------------------------- /node/tests/polkadot_mdns_issue.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use tempfile::tempdir; 19 | 20 | mod common; 21 | 22 | #[tokio::test] 23 | #[cfg(unix)] 24 | #[ignore] 25 | async fn interrupt_polkadot_mdns_issue_test() { 26 | use nix::sys::signal::Signal::{SIGINT, SIGTERM}; 27 | 28 | let base_dir = tempdir().expect("could not create a temp dir"); 29 | 30 | let args = &["--", "--dev"]; 31 | 32 | common::run_node_for_a_while(base_dir.path(), args, SIGINT).await; 33 | common::run_node_for_a_while(base_dir.path(), args, SIGTERM).await; 34 | } 35 | -------------------------------------------------------------------------------- /node/tests/purge_chain_works.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use assert_cmd::cargo::cargo_bin; 19 | use nix::sys::signal::SIGINT; 20 | use std::process::Command; 21 | use tempfile::tempdir; 22 | 23 | mod common; 24 | 25 | #[tokio::test] 26 | #[cfg(unix)] 27 | #[ignore] 28 | async fn purge_chain_works() { 29 | // Check that both databases are deleted 30 | 31 | let base_dir = tempdir().expect("could not create a temp dir"); 32 | let base_dir_path = format!("{}/polkadot", base_dir.path().display()); 33 | 34 | let args = &["--", "--dev", "-d", &base_dir_path]; 35 | 36 | common::run_node_for_a_while(base_dir.path(), args, SIGINT).await; 37 | 38 | assert!(base_dir.path().join("chains/local_testnet/db/full").exists()); 39 | assert!(base_dir.path().join("polkadot/chains/dev/db/full").exists()); 40 | 41 | let status = Command::new(cargo_bin("polkadot-parachain")) 42 | .args(&["purge-chain", "-d"]) 43 | .arg(base_dir.path()) 44 | .arg("-y") 45 | .status() 46 | .unwrap(); 47 | assert!(status.success()); 48 | 49 | // Make sure that the `parachain_local_testnet` chain folder exists, but the `db` is deleted. 50 | assert!(base_dir.path().join("chains/local_testnet").exists()); 51 | assert!(!base_dir.path().join("chains/local_testnet/db/full").exists()); 52 | // assert!(base_path.path().join("polkadot/chains/dev").exists()); 53 | // assert!(!base_path.path().join("polkadot/chains/dev/db").exists()); 54 | } 55 | -------------------------------------------------------------------------------- /node/tests/running_the_node_and_interrupt.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use tempfile::tempdir; 19 | 20 | mod common; 21 | 22 | #[tokio::test] 23 | #[cfg(unix)] 24 | #[ignore] 25 | async fn running_the_node_works_and_can_be_interrupted() { 26 | use nix::sys::signal::Signal::{SIGINT, SIGTERM}; 27 | 28 | let base_dir = tempdir().expect("could not create a temp dir"); 29 | 30 | let args = &["--", "--dev"]; 31 | 32 | common::run_node_for_a_while(base_dir.path(), args, SIGINT).await; 33 | common::run_node_for_a_while(base_dir.path(), args, SIGTERM).await; 34 | } 35 | -------------------------------------------------------------------------------- /pallets/asset-registry/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pallet-asset-registry" 3 | version = "0.0.1" 4 | description = "Trappist pallet for XCM Asset Registry." 5 | authors = { workspace = true } 6 | license = { workspace = true } 7 | homepage = { workspace = true } 8 | repository = { workspace = true } 9 | edition = { workspace = true } 10 | 11 | [package.metadata.docs.rs] 12 | targets = ["x86_64-unknown-linux-gnu"] 13 | 14 | [dependencies] 15 | parity-scale-codec = { workspace = true, features = ["derive"] } 16 | scale-info = { workspace = true } 17 | sp-runtime = { workspace = true } 18 | sp-std = { workspace = true } 19 | frame-benchmarking = { workspace = true, optional = true } 20 | frame-support = { workspace = true } 21 | frame-system = { workspace = true } 22 | 23 | xcm = { workspace = true } 24 | 25 | xcm-primitives = { workspace = true } 26 | 27 | [dev-dependencies] 28 | sp-core = { workspace = true } 29 | sp-io = { workspace = true } 30 | sp-runtime = { workspace = true } 31 | pallet-assets = { workspace = true } 32 | pallet-balances = { workspace = true } 33 | 34 | xcm = { workspace = true } 35 | xcm-simulator = { workspace = true } 36 | xcm-executor = { workspace = true } 37 | xcm-builder = { workspace = true } 38 | pallet-xcm = { workspace = true } 39 | polkadot-core-primitives = { workspace = true } 40 | polkadot-runtime-parachains = { workspace = true } 41 | polkadot-parachain-primitives = { workspace = true } 42 | 43 | parachain-info = { workspace = true } 44 | parachains-common = { workspace = true } 45 | pallet-message-queue = { workspace = true } 46 | cumulus-pallet-xcmp-queue = { workspace = true } 47 | cumulus-primitives-core = { workspace = true } 48 | 49 | [features] 50 | default = ["std"] 51 | std = [ 52 | "parity-scale-codec/std", 53 | "sp-runtime/std", 54 | "sp-std/std", 55 | "frame-benchmarking?/std", 56 | "frame-support/std", 57 | "frame-system/std", 58 | "scale-info/std", 59 | "xcm-primitives/std", 60 | "xcm/std", 61 | "xcm-executor/std", 62 | "xcm-builder/std", 63 | "pallet-xcm/std", 64 | "polkadot-core-primitives/std", 65 | "polkadot-runtime-parachains/std", 66 | "polkadot-parachain-primitives/std", 67 | "parachain-info/std", 68 | "parachains-common/std", 69 | "pallet-message-queue/std", 70 | "cumulus-pallet-xcmp-queue/std", 71 | "cumulus-primitives-core/std", 72 | ] 73 | runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] 74 | try-runtime = ["frame-support/try-runtime"] 75 | -------------------------------------------------------------------------------- /pallets/asset-registry/README.md: -------------------------------------------------------------------------------- 1 | # Asset Registry Pallet 2 | 3 | ## Overview 4 | 5 | Successful Reserve-based transfers rely on the Runtime having its `xcm_executor::Config` properly set. 6 | More specifically, its `AssetTransactor` type needs a `FungiblesAdapter` with a `ConvertedConcreteAssetId` that is able to convert the foreign `MultiLocation` into a local `AssetId`. 7 | 8 | The `asset-registry` pallet provides a solution to this problem by implementing a trait (`AssetMultiLocationGetter`) that converts between `AssetId` and `MultiLocation` (and vice-versa). 9 | 10 | This trait is used by a struct (`AsAssetMultiLocation`) that is added to the runtime (as an extra XCM primitive) and used as the `xcm_executor::traits::Convert` implementor needed by the `ConvertedConcreteAssetId` of `FungiblesAdapter`. 11 | 12 | The pallet needs to be used in conjunction with the [`xcm-primitives` crate](https://github.com/paritytech/trappist/tree/master/primitives/xcm) or an equivalent implementation. 13 | 14 | ## Configuration 15 | 16 | ### Types 17 | * `Event` – The overarching event type. 18 | * `ReserveAssetModifierOrigin` – The origin that's allowed to register and unregister reserve assets. 19 | * `Assets` – The assets type. 20 | 21 | ## Extrinsics 22 | 23 |

24 |

register_reserve_asset

25 | 26 | Register a new Reserve Asset. 27 | 28 | #### Parameters 29 | * `origin` – Origin for the call. Must be signed. 30 | * `asset_id` – ID of the Asset. Asset with this ID must exist on the local `Assets` pallet. 31 | * `asset_multi_location` – `MultiLocation` of the Reserve Asset. 32 | 33 | #### Errors 34 | * `AssetDoesNotExist` – The Asset ID does not exist on the local `Assets` pallet. 35 | * `AssetAlreadyRegistered` – The Asset ID is already registered. 36 | * `WrongMultiLocation` – Provided Reserve Asset `MultiLocation` is invalid. 37 | 38 |
39 | 40 |
41 |

unregister_reserve_asset

42 | 43 | Unregister a Reserve Asset. 44 | 45 | #### Parameters 46 | * `origin` – Origin for the call. Must be signed. 47 | * `asset_id` – ID of the asset. Asset with this ID must exist on the local `Assets` pallet. 48 | 49 | #### Errors 50 | * `AssetIsNotRegistered` – The Asset ID is not registered, and therefore cannot be unregistered. 51 | 52 |
53 | 54 | ## How to add `pallet-asset-registry` to a runtime 55 | 56 | ### Runtime's `Cargo.toml` 57 | 58 | Add `pallet-assets`, `pallet-asset-registry` and `xcm-primitives` to the dependencies: 59 | ```toml 60 | [dependencies.pallet-assets] 61 | version = "4.0.0-dev" 62 | default-features = false 63 | git = "https://github.com/paritytech/polkadot-sdk.git" 64 | branch = "polkadot-v0.9.43" 65 | 66 | [dependencies.pallet-asset-registry] 67 | version = "0.0.1" 68 | default-features = false 69 | git = "https://github.com/paritytech/trappist.git" 70 | branch = "master" 71 | 72 | [dependencies.xcm-primitives] 73 | version = "0.1.0" 74 | default-features = false 75 | git = "https://github.com/paritytech/trappist.git" 76 | branch = "master" 77 | ``` 78 | 79 | Update the runtime's `std` feature: 80 | ```toml 81 | std = [ 82 | # --snip-- 83 | "pallet-assets/std", 84 | "pallet-asset-registry/std", 85 | # --snip-- 86 | ] 87 | ``` 88 | 89 | ### Runtime's `lib.rs` 90 | Configure the `assets` pallet: 91 | ```rust 92 | pub type AssetBalance = Balance; 93 | pub type AssetId = u32; 94 | 95 | impl pallet_assets::Config for Runtime { 96 | type Event = Event; 97 | type Balance = AssetBalance; 98 | type AssetId = AssetId; 99 | type AssetIdParameter = u32; 100 | type Currency = Balances; 101 | type ForceOrigin = EnsureRoot; 102 | type AssetDeposit = ConstU128<1>; 103 | type AssetAccountDeposit = ConstU128<10>; 104 | type MetadataDepositBase = ConstU128<1>; 105 | type MetadataDepositPerByte = ConstU128<1>; 106 | type ApprovalDeposit = ConstU128<1>; 107 | type StringLimit = ConstU32<50>; 108 | type Freezer = (); 109 | type Extra = (); 110 | type WeightInfo = (); 111 | type RemoveItemsLimit = ConstU32<5>; 112 | #[cfg(feature = "runtime-benchmarks")] 113 | type BenchmarkHelper = (); 114 | } 115 | ``` 116 | 117 | Configure the `asset-registry` pallet: 118 | ```rust 119 | impl pallet_asset_registry::Config for Runtime { 120 | type Event = Event; 121 | type ReserveAssetModifierOrigin = frame_system::EnsureRoot; 122 | type Assets = Assets; 123 | } 124 | ``` 125 | 126 | Add the configured pallets to the `construct_runtime` macro call. 127 | ```rust 128 | construct_runtime!( 129 | pub enum Runtime where 130 | // --snip-- 131 | { 132 | // --snip--- 133 | Assets: pallet_assets, 134 | AssetRegistry: pallet_asset_registry::{Pallet, Call, Storage, Event}, 135 | // --snip--- 136 | } 137 | ); 138 | ``` 139 | 140 | ### Runtime's `xcm_config.rs` 141 | Add a new `FungiblesAdapter`: 142 | ```rust 143 | pub type ReservedFungiblesTransactor = FungiblesAdapter< 144 | Assets, 145 | ConvertedConcreteAssetId< 146 | AssetId, 147 | Balance, 148 | AsAssetMultiLocation, 149 | JustTry, 150 | >, 151 | LocationToAccountId, 152 | AccountId, 153 | Nothing, 154 | CheckingAccount, 155 | >; 156 | ``` 157 | 158 | Add the new `FungiblesAdapter` to the `AssetTransactors` tuple: 159 | ```rust 160 | pub type AssetTransactors = ( 161 | // snip 162 | ReservedFungiblesTransactor, 163 | // snip 164 | ); 165 | ``` 166 | 167 | Make sure the `AssetTransactors` tuple is set as `AssetTransactor` type for `XcmConfig`: 168 | ```rust 169 | pub struct XcmConfig; 170 | impl xcm_executor::Config for XcmConfig { 171 | // snip 172 | type AssetTransactor = AssetTransactors; 173 | // snip 174 | } 175 | ``` 176 | 177 | ### Node's `chain_spec.rs` 178 | Add genesis configuration for assets pallet. 179 | ```rust 180 | fn testnet_genesis( 181 | wasm_binary: &[u8], 182 | initial_authorities: Vec<(AuraId, GrandpaId)>, 183 | root_key: AccountId, 184 | endowed_accounts: Vec, 185 | _enable_println: bool, 186 | ) -> GenesisConfig { 187 | GenesisConfig { 188 | // --snip-- 189 | assets: AssetsConfig { 190 | assets: vec![], 191 | accounts: vec![], 192 | metadata: vec![], 193 | }, 194 | } 195 | } 196 | ``` 197 | -------------------------------------------------------------------------------- /pallets/asset-registry/src/benchmarking.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | // Copyright (C) Parity Technologies (UK) Ltd. 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | //! Benchmarking setup for pallet-asset-registry 18 | use super::*; 19 | 20 | #[allow(unused)] 21 | use crate::Pallet as AssetRegistry; 22 | use frame_benchmarking::benchmarks; 23 | use frame_support::assert_ok; 24 | use frame_system::RawOrigin; 25 | use xcm::opaque::latest::{ 26 | Junction::{GeneralIndex, PalletInstance, Parachain}, 27 | Junctions, MultiLocation, 28 | }; 29 | 30 | benchmarks! { 31 | register_reserve_asset { 32 | let asset_id = T::BenchmarkHelper::get_registered_asset(); 33 | let asset_multi_location = MultiLocation { 34 | parents: 1, 35 | interior: Junctions::X3(Parachain(Default::default()), PalletInstance(Default::default()), GeneralIndex(Default::default())) 36 | }; 37 | }: _(RawOrigin::Root, asset_id.clone(), asset_multi_location) 38 | verify { 39 | assert_eq!(AssetIdMultiLocation::::get(asset_id), Some(asset_multi_location)); 40 | } 41 | 42 | unregister_reserve_asset { 43 | let asset_id = T::BenchmarkHelper::get_registered_asset(); 44 | let asset_multi_location = MultiLocation { 45 | parents: 1, 46 | interior: Junctions::X3(Parachain(Default::default()), PalletInstance(Default::default()), GeneralIndex(Default::default())) 47 | }; 48 | assert_ok!(AssetRegistry::::register_reserve_asset(RawOrigin::Root.into(), asset_id.clone(), asset_multi_location)); 49 | assert!(AssetIdMultiLocation::::contains_key(asset_id.clone())); 50 | }: _(RawOrigin::Root, asset_id.clone()) 51 | verify { 52 | assert_eq!(AssetIdMultiLocation::::get(asset_id), None); 53 | } 54 | 55 | impl_benchmark_test_suite!(AssetRegistry, crate::mock::new_test_ext(), crate::mock::Test); 56 | } 57 | -------------------------------------------------------------------------------- /pallets/asset-registry/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #![cfg_attr(not(feature = "std"), no_std)] 19 | 20 | /// Edit this file to define custom logic or remove it if it is not needed. 21 | /// Learn more about FRAME and the core library of Substrate FRAME pallets: 22 | /// 23 | pub use pallet::*; 24 | 25 | #[cfg(test)] 26 | mod mock; 27 | #[cfg(test)] 28 | mod tests; 29 | 30 | #[cfg(feature = "runtime-benchmarks")] 31 | mod benchmarking; 32 | pub mod weights; 33 | pub use weights::*; 34 | 35 | #[frame_support::pallet] 36 | pub mod pallet { 37 | use super::*; 38 | use frame_support::{pallet_prelude::*, traits::tokens::fungibles::Inspect}; 39 | use frame_system::pallet_prelude::*; 40 | 41 | use xcm::latest::{ 42 | Junction::{AccountId32, AccountKey20, GeneralIndex, PalletInstance, Parachain}, 43 | MultiLocation, 44 | }; 45 | 46 | #[pallet::pallet] 47 | pub struct Pallet(_); 48 | 49 | type AssetIdOf = 50 | <::Assets as Inspect<::AccountId>>::AssetId; 51 | 52 | #[cfg(feature = "runtime-benchmarks")] 53 | pub trait BenchmarkHelper { 54 | fn get_registered_asset() -> AssetId; 55 | } 56 | 57 | #[pallet::config] 58 | pub trait Config: frame_system::Config { 59 | type RuntimeEvent: From> + IsType<::RuntimeEvent>; 60 | type ReserveAssetModifierOrigin: EnsureOrigin; 61 | type Assets: Inspect; 62 | type WeightInfo: WeightInfo; 63 | /// Helper trait for benchmarks. 64 | #[cfg(feature = "runtime-benchmarks")] 65 | type BenchmarkHelper: BenchmarkHelper>; 66 | } 67 | 68 | #[pallet::storage] 69 | pub type AssetIdMultiLocation = 70 | StorageMap<_, Blake2_128Concat, AssetIdOf, MultiLocation>; 71 | 72 | #[pallet::storage] 73 | pub type AssetMultiLocationId = 74 | StorageMap<_, Blake2_128Concat, MultiLocation, AssetIdOf>; 75 | 76 | #[pallet::event] 77 | #[pallet::generate_deposit(pub(super) fn deposit_event)] 78 | pub enum Event { 79 | ReserveAssetRegistered { asset_id: AssetIdOf, asset_multi_location: MultiLocation }, 80 | ReserveAssetUnregistered { asset_id: AssetIdOf, asset_multi_location: MultiLocation }, 81 | } 82 | 83 | #[pallet::error] 84 | pub enum Error { 85 | /// The Asset ID is already registered 86 | AssetAlreadyRegistered, 87 | /// The Asset ID does not exist 88 | AssetDoesNotExist, 89 | /// The Asset ID is not registered 90 | AssetIsNotRegistered, 91 | /// Invalid MultiLocation 92 | WrongMultiLocation, 93 | } 94 | 95 | #[pallet::call] 96 | impl Pallet { 97 | #[pallet::call_index(0)] 98 | #[pallet::weight(::WeightInfo::register_reserve_asset())] 99 | pub fn register_reserve_asset( 100 | origin: OriginFor, 101 | asset_id: AssetIdOf, 102 | asset_multi_location: MultiLocation, 103 | ) -> DispatchResult { 104 | T::ReserveAssetModifierOrigin::ensure_origin(origin)?; 105 | 106 | // verify asset exists on pallet-assets 107 | ensure!(T::Assets::asset_exists(asset_id.clone()), Error::::AssetDoesNotExist); 108 | 109 | // verify asset is not yet registered 110 | ensure!( 111 | !AssetIdMultiLocation::::contains_key(asset_id.clone()), 112 | Error::::AssetAlreadyRegistered 113 | ); 114 | 115 | // verify MultiLocation is valid 116 | ensure!( 117 | Self::valid_asset_location(&asset_multi_location), 118 | Error::::WrongMultiLocation 119 | ); 120 | 121 | // register asset_id => asset_multi_location 122 | AssetIdMultiLocation::::insert(asset_id.clone(), asset_multi_location); 123 | // register asset_multi_location => asset_id 124 | AssetMultiLocationId::::insert(asset_multi_location, asset_id.clone()); 125 | 126 | Self::deposit_event(Event::ReserveAssetRegistered { asset_id, asset_multi_location }); 127 | Ok(()) 128 | } 129 | 130 | #[pallet::call_index(1)] 131 | #[pallet::weight(::WeightInfo::unregister_reserve_asset())] 132 | pub fn unregister_reserve_asset( 133 | origin: OriginFor, 134 | asset_id: AssetIdOf, 135 | ) -> DispatchResult { 136 | T::ReserveAssetModifierOrigin::ensure_origin(origin)?; 137 | 138 | // remove asset_id => asset_multi_location, while getting the value 139 | let asset_multi_location = 140 | AssetIdMultiLocation::::mutate_exists(asset_id.clone(), Option::take) 141 | .ok_or(Error::::AssetIsNotRegistered)?; 142 | // remove asset_multi_location => asset_id 143 | AssetMultiLocationId::::remove(asset_multi_location); 144 | 145 | Self::deposit_event(Event::ReserveAssetUnregistered { asset_id, asset_multi_location }); 146 | Ok(()) 147 | } 148 | } 149 | 150 | impl Pallet { 151 | //Validates that the location points to an asset (Native, Frame based, Erc20) as described 152 | // in the xcm-format: https://github.com/paritytech/xcm-format#concrete-identifiers 153 | fn valid_asset_location(location: &MultiLocation) -> bool { 154 | let (split_multilocation, last_junction) = location.split_last_interior(); 155 | 156 | let check = matches!( 157 | last_junction, 158 | Some(AccountId32 { .. }) 159 | | Some(AccountKey20 { .. }) 160 | | Some(PalletInstance(_)) 161 | | Some(Parachain(_)) | None 162 | ); 163 | 164 | check 165 | | match last_junction { 166 | Some(GeneralIndex(_)) => { 167 | let penultimate = split_multilocation.last(); 168 | matches!(penultimate, Some(PalletInstance(_))) 169 | }, 170 | _ => false, 171 | } 172 | } 173 | } 174 | 175 | impl xcm_primitives::AssetMultiLocationGetter> for Pallet { 176 | fn get_asset_multi_location(asset_id: AssetIdOf) -> Option { 177 | AssetIdMultiLocation::::get(asset_id) 178 | } 179 | 180 | fn get_asset_id(asset_type: &MultiLocation) -> Option> { 181 | AssetMultiLocationId::::get(asset_type) 182 | } 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /pallets/asset-registry/src/mock.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use crate as pallet_asset_registry; 19 | use frame_support::traits::{AsEnsureOriginWithArg, ConstU16, ConstU64}; 20 | use frame_system as system; 21 | use sp_core::H256; 22 | use sp_runtime::{ 23 | traits::{BlakeTwo256, ConstU32, IdentityLookup}, 24 | BuildStorage, 25 | }; 26 | 27 | type Block = frame_system::mocking::MockBlock; 28 | 29 | frame_support::parameter_types! { 30 | pub const StatemineParaIdInfo: u32 = 1000u32; 31 | pub const StatemineAssetsInstanceInfo: u8 = 50u8; 32 | pub const StatemineAssetIdInfo: u128 = 1u128; 33 | } 34 | 35 | // Configure a mock runtime to test the pallet. 36 | frame_support::construct_runtime!( 37 | pub struct Test { 38 | System: frame_system, 39 | AssetRegistry: pallet_asset_registry::{Pallet, Call, Storage, Event}, 40 | Assets: pallet_assets::{Pallet, Call, Storage, Event}, 41 | Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, 42 | } 43 | ); 44 | 45 | impl system::Config for Test { 46 | type RuntimeEvent = RuntimeEvent; 47 | type BaseCallFilter = frame_support::traits::Everything; 48 | type BlockWeights = (); 49 | type BlockLength = (); 50 | type RuntimeOrigin = RuntimeOrigin; 51 | type RuntimeCall = RuntimeCall; 52 | type Nonce = u64; 53 | type Hash = H256; 54 | type Hashing = BlakeTwo256; 55 | type AccountId = u64; 56 | type Lookup = IdentityLookup; 57 | type Block = Block; 58 | type BlockHashCount = ConstU64<250>; 59 | type DbWeight = (); 60 | type Version = (); 61 | type PalletInfo = PalletInfo; 62 | type AccountData = pallet_balances::AccountData; 63 | type OnNewAccount = (); 64 | type OnKilledAccount = (); 65 | type SystemWeightInfo = (); 66 | type SS58Prefix = ConstU16<42>; 67 | type OnSetCode = (); 68 | type MaxConsumers = ConstU32<16>; 69 | } 70 | 71 | #[cfg(feature = "runtime-benchmarks")] 72 | pub struct MockAssetRegistryBenchmarkHelper; 73 | #[cfg(feature = "runtime-benchmarks")] 74 | impl pallet_asset_registry::BenchmarkHelper for MockAssetRegistryBenchmarkHelper { 75 | fn get_registered_asset() -> u32 { 76 | LOCAL_ASSET_ID 77 | } 78 | } 79 | 80 | impl pallet_asset_registry::Config for Test { 81 | type RuntimeEvent = RuntimeEvent; 82 | type ReserveAssetModifierOrigin = frame_system::EnsureRoot; 83 | type Assets = Assets; 84 | type WeightInfo = pallet_asset_registry::weights::SubstrateWeight; 85 | #[cfg(feature = "runtime-benchmarks")] 86 | type BenchmarkHelper = MockAssetRegistryBenchmarkHelper; 87 | } 88 | 89 | impl pallet_balances::Config for Test { 90 | type RuntimeEvent = RuntimeEvent; 91 | type WeightInfo = (); 92 | type Balance = u64; 93 | type DustRemoval = (); 94 | type ExistentialDeposit = ConstU64<1>; 95 | type AccountStore = System; 96 | type ReserveIdentifier = [u8; 8]; 97 | type RuntimeHoldReason = (); 98 | type FreezeIdentifier = (); 99 | type MaxLocks = (); 100 | type MaxReserves = (); 101 | type MaxHolds = ConstU32<3>; 102 | type MaxFreezes = ConstU32<0>; 103 | type RuntimeFreezeReason = (); 104 | } 105 | 106 | impl pallet_assets::Config for Test { 107 | type RuntimeEvent = RuntimeEvent; 108 | type Balance = u64; 109 | type RemoveItemsLimit = ConstU32<5>; 110 | type AssetId = u32; 111 | type AssetIdParameter = u32; 112 | type Currency = Balances; 113 | type CreateOrigin = AsEnsureOriginWithArg>; 114 | type ForceOrigin = frame_system::EnsureRoot; 115 | type AssetDeposit = ConstU64<1>; 116 | type AssetAccountDeposit = ConstU64<10>; 117 | type MetadataDepositBase = ConstU64<1>; 118 | type MetadataDepositPerByte = ConstU64<1>; 119 | type ApprovalDeposit = ConstU64<1>; 120 | type StringLimit = ConstU32<50>; 121 | type Freezer = (); 122 | type Extra = (); 123 | type CallbackHandle = (); 124 | type WeightInfo = (); 125 | #[cfg(feature = "runtime-benchmarks")] 126 | type BenchmarkHelper = (); 127 | } 128 | 129 | pub const LOCAL_ASSET_ID: u32 = 10; 130 | 131 | // Build genesis storage according to the mock runtime. 132 | pub fn new_test_ext() -> sp_io::TestExternalities { 133 | let mut storage = system::GenesisConfig::::default().build_storage().unwrap(); 134 | 135 | let config: pallet_assets::GenesisConfig = pallet_assets::GenesisConfig { 136 | assets: vec![ 137 | // id, owner, is_sufficient, min_balance 138 | (LOCAL_ASSET_ID, 0, true, 1), 139 | ], 140 | metadata: vec![ 141 | // id, name, symbol, decimals 142 | (LOCAL_ASSET_ID, "Token Name".into(), "TOKEN".into(), 10), 143 | ], 144 | accounts: vec![ 145 | // id, account_id, balance 146 | (LOCAL_ASSET_ID, 1, 100), 147 | ], 148 | }; 149 | config.assimilate_storage(&mut storage).unwrap(); 150 | storage.into() 151 | } 152 | -------------------------------------------------------------------------------- /pallets/asset-registry/src/tests.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use frame_support::{assert_noop, assert_ok}; 19 | use xcm::latest::prelude::*; 20 | 21 | use crate::{mock::*, AssetIdMultiLocation, AssetMultiLocationId, Error}; 22 | 23 | const STATEMINE_ASSET_MULTI_LOCATION: MultiLocation = MultiLocation { 24 | parents: 1, 25 | interior: X3( 26 | Parachain(StatemineParaIdInfo::get()), 27 | PalletInstance(StatemineAssetsInstanceInfo::get()), 28 | GeneralIndex(StatemineAssetIdInfo::get()), 29 | ), 30 | }; 31 | 32 | mod register_reserve_assest { 33 | use super::*; 34 | 35 | #[test] 36 | fn register_reserve_asset_works() { 37 | new_test_ext().execute_with(|| { 38 | assert_ok!(AssetRegistry::register_reserve_asset( 39 | RuntimeOrigin::root(), 40 | LOCAL_ASSET_ID, 41 | STATEMINE_ASSET_MULTI_LOCATION, 42 | )); 43 | 44 | assert_eq!( 45 | AssetIdMultiLocation::::get(LOCAL_ASSET_ID), 46 | Some(STATEMINE_ASSET_MULTI_LOCATION) 47 | ); 48 | assert_eq!( 49 | AssetMultiLocationId::::get(STATEMINE_ASSET_MULTI_LOCATION), 50 | Some(LOCAL_ASSET_ID) 51 | ); 52 | }); 53 | } 54 | 55 | #[test] 56 | fn cannot_register_unexisting_asset() { 57 | new_test_ext().execute_with(|| { 58 | let unexisting_asset_id = 9999; 59 | 60 | assert_noop!( 61 | AssetRegistry::register_reserve_asset( 62 | RuntimeOrigin::root(), 63 | unexisting_asset_id, 64 | STATEMINE_ASSET_MULTI_LOCATION, 65 | ), 66 | Error::::AssetDoesNotExist 67 | ); 68 | }); 69 | } 70 | 71 | #[test] 72 | fn cannot_double_register() { 73 | new_test_ext().execute_with(|| { 74 | assert_ok!(AssetRegistry::register_reserve_asset( 75 | RuntimeOrigin::root(), 76 | LOCAL_ASSET_ID, 77 | STATEMINE_ASSET_MULTI_LOCATION, 78 | )); 79 | 80 | assert_noop!( 81 | AssetRegistry::register_reserve_asset( 82 | RuntimeOrigin::root(), 83 | LOCAL_ASSET_ID, 84 | STATEMINE_ASSET_MULTI_LOCATION, 85 | ), 86 | Error::::AssetAlreadyRegistered 87 | ); 88 | }); 89 | } 90 | 91 | #[test] 92 | fn valid_locations_succeed() { 93 | let native_frame_based_currency = 94 | MultiLocation { parents: 1, interior: X2(Parachain(1000), PalletInstance(1)) }; 95 | let multiasset_pallet_instance = MultiLocation { 96 | parents: 1, 97 | interior: X3(Parachain(1000), PalletInstance(1), GeneralIndex(2)), 98 | }; 99 | let relay_native_currency = MultiLocation { parents: 1, interior: Junctions::Here }; 100 | let erc20_frame_sm_asset = MultiLocation { 101 | parents: 1, 102 | interior: X3( 103 | Parachain(1000), 104 | PalletInstance(2), 105 | AccountId32 { network: Some(Rococo), id: [0; 32] }, 106 | ), 107 | }; 108 | let erc20_ethereum_sm_asset = MultiLocation { 109 | parents: 1, 110 | interior: X2( 111 | Parachain(2000), 112 | AccountKey20 { network: Some(Ethereum { chain_id: 56 }), key: [0; 20] }, 113 | ), 114 | }; 115 | 116 | new_test_ext().execute_with(|| { 117 | assert_ok!(AssetRegistry::register_reserve_asset( 118 | RuntimeOrigin::root(), 119 | LOCAL_ASSET_ID, 120 | native_frame_based_currency, 121 | )); 122 | }); 123 | new_test_ext().execute_with(|| { 124 | assert_ok!(AssetRegistry::register_reserve_asset( 125 | RuntimeOrigin::root(), 126 | LOCAL_ASSET_ID, 127 | multiasset_pallet_instance, 128 | )); 129 | }); 130 | new_test_ext().execute_with(|| { 131 | assert_ok!(AssetRegistry::register_reserve_asset( 132 | RuntimeOrigin::root(), 133 | LOCAL_ASSET_ID, 134 | relay_native_currency, 135 | )); 136 | }); 137 | new_test_ext().execute_with(|| { 138 | assert_ok!(AssetRegistry::register_reserve_asset( 139 | RuntimeOrigin::root(), 140 | LOCAL_ASSET_ID, 141 | erc20_frame_sm_asset, 142 | )); 143 | }); 144 | new_test_ext().execute_with(|| { 145 | assert_ok!(AssetRegistry::register_reserve_asset( 146 | RuntimeOrigin::root(), 147 | LOCAL_ASSET_ID, 148 | erc20_ethereum_sm_asset, 149 | )); 150 | }); 151 | } 152 | 153 | #[test] 154 | fn invalid_locations_fail() { 155 | let governance_location = MultiLocation { 156 | parents: 1, 157 | interior: X2( 158 | Parachain(1000), 159 | Plurality { id: BodyId::Executive, part: BodyPart::Voice }, 160 | ), 161 | }; 162 | let invalid_general_index = 163 | MultiLocation { parents: 1, interior: X2(Parachain(1000), GeneralIndex(1u128)) }; 164 | 165 | new_test_ext().execute_with(|| { 166 | assert_noop!( 167 | AssetRegistry::register_reserve_asset( 168 | RuntimeOrigin::root(), 169 | LOCAL_ASSET_ID, 170 | governance_location, 171 | ), 172 | Error::::WrongMultiLocation 173 | ); 174 | 175 | assert_noop!( 176 | AssetRegistry::register_reserve_asset( 177 | RuntimeOrigin::root(), 178 | LOCAL_ASSET_ID, 179 | invalid_general_index, 180 | ), 181 | Error::::WrongMultiLocation 182 | ); 183 | }) 184 | } 185 | } 186 | 187 | mod unregister_reserve_asset { 188 | use super::*; 189 | 190 | #[test] 191 | fn unregister_reserve_asset_works() { 192 | new_test_ext().execute_with(|| { 193 | assert_ok!(AssetRegistry::register_reserve_asset( 194 | RuntimeOrigin::root(), 195 | LOCAL_ASSET_ID, 196 | STATEMINE_ASSET_MULTI_LOCATION, 197 | )); 198 | 199 | assert_ok!(AssetRegistry::unregister_reserve_asset( 200 | RuntimeOrigin::root(), 201 | LOCAL_ASSET_ID 202 | )); 203 | 204 | assert!(AssetIdMultiLocation::::get(LOCAL_ASSET_ID).is_none()); 205 | assert!(AssetMultiLocationId::::get(STATEMINE_ASSET_MULTI_LOCATION).is_none()); 206 | }); 207 | } 208 | 209 | #[test] 210 | fn cannot_register_unregistered_asset() { 211 | new_test_ext().execute_with(|| { 212 | assert_noop!( 213 | AssetRegistry::unregister_reserve_asset(RuntimeOrigin::root(), LOCAL_ASSET_ID), 214 | Error::::AssetIsNotRegistered 215 | ); 216 | }); 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /pallets/asset-registry/src/weights.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! Autogenerated weights for `pallet_asset_registry` 19 | //! 20 | //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev 21 | //! DATE: 2023-05-18, STEPS: `20`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]` 22 | //! WORST CASE MAP SIZE: `1000000` 23 | //! HOSTNAME: `vale`, CPU: `11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz` 24 | //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 25 | 26 | // Executed Command: 27 | // ./target/release/trappist-collator 28 | // benchmark 29 | // pallet 30 | // --chain 31 | // dev 32 | // --pallet 33 | // pallet_asset_registry 34 | // --execution=wasm 35 | // --wasm-execution=compiled 36 | // --extrinsic 37 | // * 38 | // --steps 39 | // 20 40 | // --repeat 41 | // 10 42 | // --output 43 | // pallets/asset-registry/src/weights.rs 44 | 45 | #![cfg_attr(rustfmt, rustfmt_skip)] 46 | #![allow(unused_parens)] 47 | #![allow(unused_imports)] 48 | 49 | use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; 50 | use sp_std::marker::PhantomData; 51 | 52 | pub trait WeightInfo { 53 | fn register_reserve_asset() -> Weight; 54 | fn unregister_reserve_asset() -> Weight; 55 | } 56 | 57 | /// Weight functions for `pallet_asset_registry`. 58 | pub struct SubstrateWeight(PhantomData); 59 | impl WeightInfo for SubstrateWeight { 60 | /// Storage: Assets Asset (r:1 w:0) 61 | /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) 62 | /// Storage: AssetRegistry AssetIdMultiLocation (r:1 w:1) 63 | /// Proof: AssetRegistry AssetIdMultiLocation (max_values: None, max_size: Some(622), added: 3097, mode: MaxEncodedLen) 64 | /// Storage: AssetRegistry AssetMultiLocationId (r:0 w:1) 65 | /// Proof: AssetRegistry AssetMultiLocationId (max_values: None, max_size: Some(622), added: 3097, mode: MaxEncodedLen) 66 | fn register_reserve_asset() -> Weight { 67 | // Proof Size summary in bytes: 68 | // Measured: `123` 69 | // Estimated: `7762` 70 | // Minimum execution time: 21_998_000 picoseconds. 71 | Weight::from_parts(22_970_000, 0) 72 | .saturating_add(Weight::from_parts(0, 7762)) 73 | .saturating_add(T::DbWeight::get().reads(2)) 74 | .saturating_add(T::DbWeight::get().writes(2)) 75 | } 76 | /// Storage: AssetRegistry AssetIdMultiLocation (r:1 w:1) 77 | /// Proof: AssetRegistry AssetIdMultiLocation (max_values: None, max_size: Some(622), added: 3097, mode: MaxEncodedLen) 78 | /// Storage: AssetRegistry AssetMultiLocationId (r:0 w:1) 79 | /// Proof: AssetRegistry AssetMultiLocationId (max_values: None, max_size: Some(622), added: 3097, mode: MaxEncodedLen) 80 | fn unregister_reserve_asset() -> Weight { 81 | // Proof Size summary in bytes: 82 | // Measured: `107` 83 | // Estimated: `4087` 84 | // Minimum execution time: 17_862_000 picoseconds. 85 | Weight::from_parts(18_454_000, 0) 86 | .saturating_add(Weight::from_parts(0, 4087)) 87 | .saturating_add(T::DbWeight::get().reads(1)) 88 | .saturating_add(T::DbWeight::get().writes(2)) 89 | } 90 | } 91 | 92 | impl WeightInfo for () { 93 | /// Storage: Assets Asset (r:1 w:0) 94 | /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) 95 | /// Storage: AssetRegistry AssetIdMultiLocation (r:1 w:1) 96 | /// Proof: AssetRegistry AssetIdMultiLocation (max_values: None, max_size: Some(622), added: 3097, mode: MaxEncodedLen) 97 | /// Storage: AssetRegistry AssetMultiLocationId (r:0 w:1) 98 | /// Proof: AssetRegistry AssetMultiLocationId (max_values: None, max_size: Some(622), added: 3097, mode: MaxEncodedLen) 99 | fn register_reserve_asset() -> Weight { 100 | // Proof Size summary in bytes: 101 | // Measured: `123` 102 | // Estimated: `7762` 103 | // Minimum execution time: 21_998_000 picoseconds. 104 | Weight::from_parts(22_970_000, 0) 105 | .saturating_add(Weight::from_parts(0, 7762)) 106 | .saturating_add(RocksDbWeight::get().reads(2)) 107 | .saturating_add(RocksDbWeight::get().writes(2)) 108 | } 109 | /// Storage: AssetRegistry AssetIdMultiLocation (r:1 w:1) 110 | /// Proof: AssetRegistry AssetIdMultiLocation (max_values: None, max_size: Some(622), added: 3097, mode: MaxEncodedLen) 111 | /// Storage: AssetRegistry AssetMultiLocationId (r:0 w:1) 112 | /// Proof: AssetRegistry AssetMultiLocationId (max_values: None, max_size: Some(622), added: 3097, mode: MaxEncodedLen) 113 | fn unregister_reserve_asset() -> Weight { 114 | // Proof Size summary in bytes: 115 | // Measured: `107` 116 | // Estimated: `4087` 117 | // Minimum execution time: 17_862_000 picoseconds. 118 | Weight::from_parts(18_454_000, 0) 119 | .saturating_add(Weight::from_parts(0, 4087)) 120 | .saturating_add(RocksDbWeight::get().reads(1)) 121 | .saturating_add(RocksDbWeight::get().writes(2)) 122 | } 123 | } -------------------------------------------------------------------------------- /pallets/benchmarks/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "trappist-runtime-benchmarks" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [package.metadata.docs.rs] 7 | targets = ["x86_64-unknown-linux-gnu"] 8 | 9 | [dependencies] 10 | parity-scale-codec = { workspace = true, features = ["derive"] } 11 | scale-info = { workspace = true } 12 | sp-runtime = { workspace = true } 13 | sp-std = { workspace = true } 14 | frame-benchmarking = { workspace = true, optional = true } 15 | frame-support = { workspace = true } 16 | frame-system = { workspace = true } 17 | 18 | xcm = { workspace = true } 19 | xcm-executor = { workspace = true } 20 | 21 | [dev-dependencies] 22 | sp-core = { workspace = true } 23 | 24 | [features] 25 | default = ["std"] 26 | std = [ 27 | "parity-scale-codec/std", 28 | "frame-benchmarking?/std", 29 | "frame-support/std", 30 | "frame-system/std", 31 | "sp-runtime/std", 32 | "sp-std/std", 33 | "xcm-executor/std", 34 | ] 35 | runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] 36 | -------------------------------------------------------------------------------- /pallets/benchmarks/src/benchmarking.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use frame_benchmarking::benchmarks; 19 | use sp_runtime::SaturatedConversion; 20 | use xcm::prelude::AssetId as XcmAssetId; 21 | 22 | use crate::*; 23 | 24 | benchmarks! { 25 | drop_assets_fungible { 26 | let origin = MultiLocation::default(); 27 | let asset_id = 1; 28 | let location: MultiLocation = Parachain(asset_id).into(); 29 | T::register_asset(asset_id.into(), location); 30 | let asset = MultiAsset { id: XcmAssetId::Concrete(location), fun: Fungibility::Fungible(100) }; 31 | } : { 32 | T::DropAssets::drop_assets( 33 | &origin, 34 | asset.into(), 35 | &XcmContext { 36 | origin: Some(origin), 37 | message_id: [0; 32], 38 | topic: None, 39 | }, 40 | ); 41 | } 42 | 43 | drop_assets_native { 44 | let origin = MultiLocation::default(); 45 | let location = MultiLocation { parents: 0, interior: Here }; 46 | let amount = T::ExistentialDeposit::get().saturated_into(); 47 | let asset = MultiAsset { id: XcmAssetId::Concrete(location), fun: Fungibility::Fungible(amount) }; 48 | } : { 49 | T::DropAssets::drop_assets( 50 | &origin, 51 | asset.into(), 52 | &XcmContext { 53 | origin: Some(origin), 54 | message_id: [0; 32], 55 | topic: None, 56 | }, 57 | ); 58 | } 59 | 60 | drop_assets_default { 61 | let origin = MultiLocation::default(); 62 | let asset = MultiAsset { id: XcmAssetId::Abstract(Default::default()), fun: Fungibility::Fungible(0) }; 63 | } : { 64 | T::DropAssets::drop_assets( 65 | &origin, 66 | asset.into(), 67 | &XcmContext { 68 | origin: Some(origin), 69 | message_id: [0; 32], 70 | topic: None, 71 | }, 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /pallets/benchmarks/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! Pallet for benchmarking. 19 | 20 | #![cfg_attr(not(feature = "std"), no_std)] 21 | 22 | use frame_support::{pallet_prelude::*, traits::tokens::AssetId}; 23 | use parity_scale_codec::Codec; 24 | use sp_runtime::traits::AtLeast32BitUnsigned; 25 | use xcm::prelude::*; 26 | use xcm_executor::traits::DropAssets; 27 | 28 | pub use pallet::*; 29 | pub use weights::*; 30 | 31 | #[cfg(feature = "runtime-benchmarks")] 32 | pub mod benchmarking; 33 | pub mod weights; 34 | 35 | #[frame_support::pallet] 36 | pub mod pallet { 37 | use super::*; 38 | 39 | #[pallet::config] 40 | pub trait Config: frame_system::Config { 41 | /// Identifier for the class of asset. 42 | type AssetId: AssetId + From; 43 | 44 | /// The balance of an account. 45 | type Balance: Parameter + Member + AtLeast32BitUnsigned + Codec + TypeInfo; 46 | 47 | /// The minimum amount required to keep an account open. 48 | #[pallet::constant] 49 | type ExistentialDeposit: Get; 50 | 51 | /// Handler for when some non-empty `Assets` value should be dropped. 52 | type DropAssets: DropAssets; 53 | 54 | /// Handler to register an asset. 55 | fn register_asset(asset_id: Self::AssetId, location: MultiLocation); 56 | } 57 | 58 | #[pallet::pallet] 59 | pub struct Pallet(_); 60 | } 61 | -------------------------------------------------------------------------------- /pallets/benchmarks/src/weights.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use frame_support::weights::Weight; 19 | 20 | pub trait WeightInfo { 21 | fn drop_assets_fungible() -> Weight; 22 | fn drop_assets_native() -> Weight; 23 | fn drop_assets_default() -> Weight; 24 | } 25 | -------------------------------------------------------------------------------- /pallets/withdraw-teleport/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pallet-withdraw-teleport" 3 | version = "0.1.0" 4 | description = "Pallet for allowing to teleport funds by paying with a fee asset on destination." 5 | authors = { workspace = true } 6 | license = { workspace = true } 7 | homepage = { workspace = true } 8 | repository = { workspace = true } 9 | edition = { workspace = true } 10 | 11 | [package.metadata.docs.rs] 12 | targets = ["x86_64-unknown-linux-gnu"] 13 | 14 | [dependencies] 15 | parity-scale-codec = { workspace = true, features = [ "derive" ] } 16 | scale-info = { workspace = true } 17 | sp-runtime = { workspace = true } 18 | sp-std = { workspace = true } 19 | frame-benchmarking = { workspace = true, optional = true } 20 | frame-support = { workspace = true } 21 | frame-system = { workspace = true } 22 | pallet-xcm = { workspace = true } 23 | xcm = { workspace = true } 24 | xcm-executor = { workspace = true } 25 | sp-io = { workspace = true } 26 | log = { workspace = true } 27 | 28 | 29 | [dev-dependencies] 30 | sp-core = { workspace = true } 31 | sp-io = { workspace = true } 32 | sp-runtime = { workspace = true } 33 | pallet-balances = { workspace = true } 34 | xcm-builder = { workspace = true } 35 | polkadot-parachain-primitives = { workspace = true } 36 | polkadot-runtime-parachains = { workspace = true } 37 | 38 | [features] 39 | default = ["std"] 40 | std = [ 41 | "parity-scale-codec/std", 42 | "frame-benchmarking?/std", 43 | "frame-support/std", 44 | "frame-system/std", 45 | "scale-info/std", 46 | "log/std", 47 | "xcm-executor/std", 48 | ] 49 | runtime-benchmarks = [ 50 | "frame-benchmarking/runtime-benchmarks", 51 | "pallet-xcm/runtime-benchmarks", 52 | ] 53 | try-runtime = ["frame-support/try-runtime"] 54 | -------------------------------------------------------------------------------- /pallets/withdraw-teleport/src/benchmarking.rs: -------------------------------------------------------------------------------- 1 | //! Benchmarking setup for pallet-template 2 | #![cfg(feature = "runtime-benchmarks")] 3 | use super::*; 4 | 5 | #[allow(unused)] 6 | use crate::Pallet as WithdrawTeleport; 7 | use frame_benchmarking::{impl_benchmark_test_suite, v2::*}; 8 | use frame_support::traits::Currency; 9 | use frame_system::RawOrigin; 10 | use sp_std::prelude::*; 11 | 12 | #[benchmarks] 13 | mod benchmarks { 14 | use super::*; 15 | 16 | #[benchmark] 17 | fn withdraw_and_teleport() -> Result<(), BenchmarkError> { 18 | let fee_amount = 1_000; 19 | let asset: MultiAsset = (MultiLocation::new(0, Here), fee_amount.clone()).into(); 20 | let recipient = [0u8; 32]; 21 | let reachable_dest: Option = Some(MultiLocation::new(1, Here).into()); 22 | let versioned_dest: VersionedMultiLocation = reachable_dest 23 | .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))? 24 | .into(); 25 | let versioned_beneficiary: VersionedMultiLocation = 26 | AccountId32 { network: None, id: recipient.into() }.into(); 27 | let versioned_assets: VersionedMultiAssets = asset.into(); 28 | let amount: u32 = 1_000; 29 | let caller = whitelisted_caller(); 30 | T::Currency::make_free_balance_be(&caller, 100_000_000u32.into()); 31 | let initial_balance = T::Currency::free_balance(&caller); 32 | 33 | #[extrinsic_call] 34 | withdraw_and_teleport( 35 | RawOrigin::Signed(caller.clone()), 36 | Box::new(versioned_dest), 37 | Box::new(versioned_beneficiary), 38 | amount.into(), 39 | Box::new(versioned_assets), 40 | ); 41 | 42 | let remaining_balance = initial_balance - amount.into() - (fee_amount as u32).into(); 43 | // Send or execution error would derive on balances amounts not being deducted from caller. 44 | assert_eq!(T::Currency::free_balance(&caller), remaining_balance); 45 | Ok(()) 46 | } 47 | 48 | impl_benchmark_test_suite!(WithdrawTeleport, crate::mock::new_test_ext(), crate::mock::Test); 49 | } 50 | -------------------------------------------------------------------------------- /pallets/withdraw-teleport/src/weights.rs: -------------------------------------------------------------------------------- 1 | 2 | //! Autogenerated weights for pallet_withdraw_teleport 3 | //! 4 | //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev 5 | //! DATE: 2023-09-28, STEPS: `20`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]` 6 | //! WORST CASE MAP SIZE: `1000000` 7 | //! HOSTNAME: `Emilianos-MacBook-Pro.local`, CPU: `` 8 | //! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 9 | 10 | // Executed Command: 11 | // ./target/release/trappist-node 12 | // benchmark 13 | // pallet 14 | // --chain=dev 15 | // --steps=20 16 | // --repeat=10 17 | // --pallet=pallet_withdraw_teleport 18 | // --extrinsic=* 19 | // --wasm-execution=compiled 20 | // --template=./templates/frame-weight-template.hbs 21 | // --output=./pallets/withdraw-teleport/src/weights.rs 22 | 23 | #![cfg_attr(rustfmt, rustfmt_skip)] 24 | #![allow(unused_parens)] 25 | #![allow(unused_imports)] 26 | #![allow(missing_docs)] 27 | 28 | use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; 29 | use core::marker::PhantomData; 30 | 31 | /// Weight functions needed for pallet_withdraw_teleport. 32 | pub trait WeightInfo { 33 | fn withdraw_and_teleport() -> Weight; 34 | } 35 | 36 | /// Weights for pallet_withdraw_teleport using the Substrate node and recommended hardware. 37 | pub struct SubstrateWeight(PhantomData); 38 | impl WeightInfo for SubstrateWeight { 39 | /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) 40 | /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) 41 | /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) 42 | /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) 43 | /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) 44 | /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) 45 | /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) 46 | /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) 47 | /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) 48 | /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) 49 | /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) 50 | /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) 51 | fn withdraw_and_teleport() -> Weight { 52 | // Proof Size summary in bytes: 53 | // Measured: `177` 54 | // Estimated: `3642` 55 | // Minimum execution time: 87_000_000 picoseconds. 56 | Weight::from_parts(88_000_000, 3642) 57 | .saturating_add(T::DbWeight::get().reads(6_u64)) 58 | .saturating_add(T::DbWeight::get().writes(2_u64)) 59 | } 60 | } 61 | 62 | // For backwards compatibility and tests 63 | impl WeightInfo for () { 64 | /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) 65 | /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) 66 | /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) 67 | /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) 68 | /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) 69 | /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) 70 | /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) 71 | /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) 72 | /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) 73 | /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) 74 | /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) 75 | /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) 76 | fn withdraw_and_teleport() -> Weight { 77 | // Proof Size summary in bytes: 78 | // Measured: `177` 79 | // Estimated: `3642` 80 | // Minimum execution time: 87_000_000 picoseconds. 81 | Weight::from_parts(88_000_000, 3642) 82 | .saturating_add(RocksDbWeight::get().reads(6_u64)) 83 | .saturating_add(RocksDbWeight::get().writes(2_u64)) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /primitives/xcm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "xcm-primitives" 3 | version = "0.0.1" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | sp-std = { workspace = true } 8 | frame-support = { workspace = true } 9 | sp-runtime = { workspace = true } 10 | 11 | 12 | xcm = { workspace = true } 13 | xcm-executor = { workspace = true } 14 | 15 | [features] 16 | default = [ "std" ] 17 | std = [ 18 | "sp-std/std", 19 | "frame-support/std", 20 | "sp-runtime/std", 21 | "xcm/std", 22 | "xcm-executor/std" 23 | ] 24 | -------------------------------------------------------------------------------- /primitives/xcm/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #![cfg_attr(not(feature = "std"), no_std)] 19 | 20 | use frame_support::{ 21 | sp_runtime::SaturatedConversion, 22 | traits::{fungibles::Inspect, Currency}, 23 | weights::Weight, 24 | }; 25 | use sp_runtime::traits::MaybeEquivalence; 26 | #[cfg(not(test))] 27 | use sp_runtime::DispatchResult; 28 | use sp_std::marker::PhantomData; 29 | use xcm::{ 30 | latest::{ 31 | AssetId::Concrete, Fungibility::Fungible, Junctions::Here, MultiAsset, MultiLocation, 32 | }, 33 | v3::XcmContext, 34 | }; 35 | use xcm_executor::{ 36 | traits::{DropAssets, Error as MatchError, MatchesFungibles}, 37 | Assets, 38 | }; 39 | 40 | pub struct AsAssetMultiLocation( 41 | PhantomData<(AssetId, AssetIdInfoGetter)>, 42 | ); 43 | impl MaybeEquivalence 44 | for AsAssetMultiLocation 45 | where 46 | AssetId: Clone, 47 | AssetIdInfoGetter: AssetMultiLocationGetter, 48 | { 49 | fn convert(asset_multi_location: &MultiLocation) -> Option { 50 | AssetIdInfoGetter::get_asset_id(asset_multi_location) 51 | } 52 | 53 | fn convert_back(asset_id: &AssetId) -> Option { 54 | AssetIdInfoGetter::get_asset_multi_location(asset_id.clone()) 55 | } 56 | } 57 | 58 | pub trait AssetMultiLocationGetter { 59 | fn get_asset_multi_location(asset_id: AssetId) -> Option; 60 | fn get_asset_id(asset_multi_location: &MultiLocation) -> Option; 61 | } 62 | 63 | pub struct ConvertedRegisteredAssetId( 64 | PhantomData<(AssetId, Balance, ConvertAssetId, ConvertBalance)>, 65 | ); 66 | impl< 67 | AssetId: Clone, 68 | Balance: Clone, 69 | ConvertAssetId: MaybeEquivalence, 70 | ConvertBalance: MaybeEquivalence, 71 | > MatchesFungibles 72 | for ConvertedRegisteredAssetId 73 | { 74 | fn matches_fungibles(a: &MultiAsset) -> Result<(AssetId, Balance), MatchError> { 75 | let (amount, id) = match (&a.fun, &a.id) { 76 | (Fungible(ref amount), Concrete(ref id)) => (amount, id), 77 | _ => return Err(MatchError::AssetNotHandled), 78 | }; 79 | let what = ConvertAssetId::convert(id).ok_or(MatchError::AssetNotHandled)?; 80 | let amount = ConvertBalance::convert_back(amount) 81 | .ok_or(MatchError::AmountToBalanceConversionFailed)?; 82 | Ok((what, amount)) 83 | } 84 | } 85 | 86 | pub trait DropAssetsWeigher { 87 | fn fungible() -> Weight; 88 | fn native() -> Weight; 89 | fn default() -> Weight; 90 | } 91 | 92 | pub struct TrappistDropAssets< 93 | AssetId, 94 | AssetIdInfoGetter, 95 | AssetsPallet, 96 | BalancesPallet, 97 | XcmPallet, 98 | AccountId, 99 | Weigher, 100 | >( 101 | PhantomData<( 102 | AssetId, 103 | AssetIdInfoGetter, 104 | AssetsPallet, 105 | BalancesPallet, 106 | XcmPallet, 107 | AccountId, 108 | Weigher, 109 | )>, 110 | ); 111 | 112 | impl 113 | DropAssets 114 | for TrappistDropAssets< 115 | AssetId, 116 | AssetIdInfoGetter, 117 | AssetsPallet, 118 | BalancesPallet, 119 | XcmPallet, 120 | AccountId, 121 | Weigher, 122 | > where 123 | AssetIdInfoGetter: AssetMultiLocationGetter, 124 | AssetsPallet: Inspect, 125 | BalancesPallet: Currency, 126 | XcmPallet: DropAssets, 127 | Weigher: DropAssetsWeigher, 128 | { 129 | // assets are whatever the Holding Register had when XCVM halts 130 | fn drop_assets(origin: &MultiLocation, mut assets: Assets, context: &XcmContext) -> Weight { 131 | const NATIVE_LOCATION: MultiLocation = MultiLocation { parents: 0, interior: Here }; 132 | 133 | let mut weight: Weight = { 134 | assets.non_fungible.clear(); 135 | Weigher::default() 136 | }; 137 | 138 | assets.fungible.retain(|id, &mut amount| { 139 | if let Concrete(location) = id { 140 | match AssetIdInfoGetter::get_asset_id(location) { 141 | Some(asset_id) => { 142 | weight.saturating_accrue(Weigher::fungible()); 143 | 144 | // only trap if amount ≥ min_balance 145 | // do nothing otherwise (asset is lost) 146 | amount.saturated_into::() 147 | >= AssetsPallet::minimum_balance(asset_id) 148 | }, 149 | None => { 150 | weight.saturating_accrue(Weigher::native()); 151 | 152 | // only trap if native token and amount ≥ min_balance 153 | // do nothing otherwise (asset is lost) 154 | *location == NATIVE_LOCATION 155 | && amount.saturated_into::() 156 | >= BalancesPallet::minimum_balance() 157 | }, 158 | } 159 | } else { 160 | weight.saturating_accrue(Weigher::default()); 161 | false 162 | } 163 | }); 164 | 165 | // we have filtered out non-compliant assets 166 | // insert valid assets into the asset trap implemented by XcmPallet 167 | weight.saturating_add(XcmPallet::drop_assets(origin, assets, context)) 168 | } 169 | } 170 | 171 | /// Pause and resume execution of XCM 172 | #[cfg(not(test))] 173 | pub trait PauseXcmExecution { 174 | fn suspend_xcm_execution() -> DispatchResult; 175 | fn resume_xcm_execution() -> DispatchResult; 176 | } 177 | #[cfg(not(test))] 178 | impl PauseXcmExecution for () { 179 | fn suspend_xcm_execution() -> DispatchResult { 180 | Ok(()) 181 | } 182 | fn resume_xcm_execution() -> DispatchResult { 183 | Ok(()) 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /runtime/stout/build.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use substrate_wasm_builder::WasmBuilder; 19 | 20 | fn main() { 21 | WasmBuilder::new() 22 | .with_current_project() 23 | .export_heap_base() 24 | .import_memory() 25 | .build() 26 | } 27 | -------------------------------------------------------------------------------- /runtime/stout/src/constants.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | pub mod currency { 19 | use parachains_common::kusama as constants; 20 | use polkadot_core_primitives::Balance; 21 | 22 | /// The existential deposit. Set to 1/10 of its parent Relay Chain. 23 | pub const EXISTENTIAL_DEPOSIT: Balance = constants::currency::EXISTENTIAL_DEPOSIT / 10; 24 | 25 | pub const UNITS: Balance = constants::currency::UNITS; 26 | pub const CENTS: Balance = constants::currency::CENTS; 27 | pub const GRAND: Balance = constants::currency::GRAND; 28 | pub const MILLICENTS: Balance = constants::currency::MILLICENTS; 29 | 30 | pub const fn deposit(items: u32, bytes: u32) -> Balance { 31 | // map to 1/10 of what the kusama relay chain charges (v9020) 32 | constants::currency::deposit(items, bytes) / 10 33 | } 34 | } 35 | 36 | /// Fee-related. 37 | pub mod fee { 38 | use super::currency::CENTS; 39 | use frame_support::weights::{ 40 | constants::{ExtrinsicBaseWeight, WEIGHT_REF_TIME_PER_SECOND}, 41 | WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, 42 | }; 43 | use polkadot_core_primitives::Balance; 44 | use smallvec::smallvec; 45 | pub use sp_runtime::Perbill; 46 | 47 | /// The block saturation level. Fees will be updates based on this value. 48 | pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); 49 | 50 | /// Handles converting a weight scalar to a fee value, based on the scale and granularity of the 51 | /// node's balance type. 52 | /// 53 | /// This should typically create a mapping between the following ranges: 54 | /// - [0, MAXIMUM_BLOCK_WEIGHT] 55 | /// - [Balance::min, Balance::max] 56 | /// 57 | /// Yet, it can be used for any other sort of change to weight-fee. Some examples being: 58 | /// - Setting it to `0` will essentially disable the weight fee. 59 | /// - Setting it to `1` will cause the literal `#[weight = x]` values to be charged. 60 | pub struct WeightToFee; 61 | impl WeightToFeePolynomial for WeightToFee { 62 | type Balance = Balance; 63 | fn polynomial() -> WeightToFeeCoefficients { 64 | // in Kusama, extrinsic stout weight (smallest non-zero weight) is mapped to 1/10 CENT: 65 | // in Statemine, we map to 1/10 of that, or 1/100 CENT 66 | let p = super::currency::CENTS; 67 | let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time()); 68 | smallvec![WeightToFeeCoefficient { 69 | degree: 1, 70 | negative: false, 71 | coeff_frac: Perbill::from_rational(p % q, q), 72 | coeff_integer: p / q, 73 | }] 74 | } 75 | } 76 | 77 | pub fn base_tx_fee() -> Balance { 78 | CENTS / 10 79 | } 80 | 81 | pub fn default_fee_per_second() -> u128 { 82 | let base_weight = Balance::from(ExtrinsicBaseWeight::get().ref_time()); 83 | let base_tx_per_second = (WEIGHT_REF_TIME_PER_SECOND as u128) / base_weight; 84 | base_tx_per_second * base_tx_fee() 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /runtime/stout/src/contracts.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use crate::{ 19 | constants::currency::deposit, Balance, Balances, RandomnessCollectiveFlip, Runtime, 20 | RuntimeCall, RuntimeEvent, RuntimeHoldReason, Timestamp, 21 | }; 22 | use frame_support::{ 23 | parameter_types, 24 | traits::{ConstU32, Nothing}, 25 | }; 26 | use pallet_contracts::{ 27 | weights::SubstrateWeight, Config, DebugInfo, DefaultAddressGenerator, Frame, Schedule, 28 | }; 29 | use sp_core::ConstBool; 30 | use sp_runtime::Perbill; 31 | 32 | // Prints debug output of the `contracts` pallet to stdout if the node is 33 | // started with `-lruntime::contracts=debug`. 34 | pub const CONTRACTS_DEBUG_OUTPUT: DebugInfo = DebugInfo::UnsafeDebug; 35 | 36 | parameter_types! { 37 | pub const DepositPerItem: Balance = deposit(1, 0); 38 | pub const DepositPerByte: Balance = deposit(0, 1); 39 | pub MySchedule: Schedule = Default::default(); 40 | pub const DefaultDepositLimit: Balance = deposit(1024, 1024 * 1024); 41 | pub CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(30); 42 | } 43 | 44 | impl Config for Runtime { 45 | type Time = Timestamp; 46 | type Randomness = RandomnessCollectiveFlip; 47 | type Currency = Balances; 48 | type RuntimeEvent = RuntimeEvent; 49 | type RuntimeCall = RuntimeCall; 50 | /// The safest default is to allow no calls at all. 51 | /// 52 | /// Runtimes should whitelist dispatchables that are allowed to be called from contracts 53 | /// and make sure they are stable. Dispatchables exposed to contracts are not allowed to 54 | /// change because that would break already deployed contracts. The `Call` structure itself 55 | /// is not allowed to change the indices of existing pallets, too. 56 | type CallFilter = Nothing; 57 | type WeightPrice = pallet_transaction_payment::Pallet; 58 | type WeightInfo = SubstrateWeight; 59 | type ChainExtension = (); 60 | type Schedule = MySchedule; 61 | type CallStack = [Frame; 5]; 62 | type DepositPerByte = DepositPerByte; 63 | type DefaultDepositLimit = DefaultDepositLimit; 64 | type DepositPerItem = DepositPerItem; 65 | type AddressGenerator = DefaultAddressGenerator; 66 | type MaxCodeLen = ConstU32<{ 123 * 1024 }>; 67 | type MaxStorageKeyLen = ConstU32<128>; 68 | type UnsafeUnstableInterface = ConstBool; 69 | type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>; 70 | #[cfg(not(feature = "runtime-benchmarks"))] 71 | type Migrations = (); 72 | #[cfg(feature = "runtime-benchmarks")] 73 | type Migrations = pallet_contracts::migration::codegen::BenchMigrations; 74 | type MaxDelegateDependencies = ConstU32<32>; 75 | type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; 76 | type Debug = (); 77 | type Environment = (); 78 | type RuntimeHoldReason = RuntimeHoldReason; 79 | type Xcm = pallet_xcm::Pallet; 80 | } 81 | -------------------------------------------------------------------------------- /runtime/trappist/build.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use substrate_wasm_builder::WasmBuilder; 19 | 20 | fn main() { 21 | WasmBuilder::new() 22 | .with_current_project() 23 | .export_heap_base() 24 | .import_memory() 25 | .build() 26 | } 27 | -------------------------------------------------------------------------------- /runtime/trappist/src/constants.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | pub mod currency { 19 | use parachains_common::kusama as constants; 20 | use polkadot_core_primitives::Balance; 21 | 22 | /// The existential deposit. Set to 1/10 of its parent Relay Chain. 23 | pub const EXISTENTIAL_DEPOSIT: Balance = constants::currency::EXISTENTIAL_DEPOSIT / 10; 24 | 25 | pub const UNITS: Balance = constants::currency::UNITS; 26 | pub const CENTS: Balance = constants::currency::CENTS; 27 | pub const GRAND: Balance = constants::currency::GRAND; 28 | pub const MILLICENTS: Balance = constants::currency::MILLICENTS; 29 | 30 | pub const fn deposit(items: u32, bytes: u32) -> Balance { 31 | // map to 1/100 of what the kusama relay chain charges (v9020) 32 | constants::currency::deposit(items, bytes) / 100 33 | } 34 | } 35 | 36 | /// Fee-related. 37 | pub mod fee { 38 | use frame_support::weights::{ 39 | constants::{ExtrinsicBaseWeight, WEIGHT_REF_TIME_PER_SECOND}, 40 | FeePolynomial, Weight, WeightToFeeCoefficient, WeightToFeeCoefficients, 41 | WeightToFeePolynomial, 42 | }; 43 | use polkadot_core_primitives::Balance; 44 | use smallvec::smallvec; 45 | 46 | pub use sp_runtime::Perbill; 47 | 48 | use super::currency::CENTS; 49 | 50 | /// The block saturation level. Fees will be updates based on this value. 51 | pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); 52 | 53 | /// Handles converting a weight scalar to a fee value, based on the scale and granularity of the 54 | /// node's balance type. 55 | /// 56 | /// This should typically create a mapping between the following ranges: 57 | /// - [0, MAXIMUM_BLOCK_WEIGHT] 58 | /// - [Balance::min, Balance::max] 59 | /// 60 | /// Yet, it can be used for any other sort of change to weight-fee. Some examples being: 61 | /// - Setting it to `0` will essentially disable the weight fee. 62 | /// - Setting it to `1` will cause the literal `#[weight = x]` values to be charged. 63 | pub struct WeightToFee; 64 | impl frame_support::weights::WeightToFee for WeightToFee { 65 | type Balance = Balance; 66 | 67 | fn weight_to_fee(weight: &Weight) -> Self::Balance { 68 | let ref_time: FeePolynomial = RefTimeToFee::polynomial().into(); 69 | let proof_size: FeePolynomial = ProofSizeToFee::polynomial().into(); 70 | 71 | // Take the maximum instead of the sum to charge by the more scarce resource. 72 | ref_time.eval(weight.ref_time()).max(proof_size.eval(weight.proof_size())) 73 | } 74 | } 75 | 76 | /// Maps the Ref time component of `Weight` to a fee. 77 | pub struct RefTimeToFee; 78 | impl WeightToFeePolynomial for RefTimeToFee { 79 | type Balance = Balance; 80 | fn polynomial() -> WeightToFeeCoefficients { 81 | // in Kusama, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT: 82 | // in Statemine, we map to 1/10 of that, or 1/100 CENT 83 | let p = CENTS; 84 | let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time()); 85 | smallvec![WeightToFeeCoefficient { 86 | degree: 1, 87 | negative: false, 88 | coeff_frac: Perbill::from_rational(p % q, q), 89 | coeff_integer: p / q, 90 | }] 91 | } 92 | } 93 | 94 | /// Maps the proof size component of `Weight` to a fee. 95 | pub struct ProofSizeToFee; 96 | impl WeightToFeePolynomial for ProofSizeToFee { 97 | type Balance = Balance; 98 | fn polynomial() -> WeightToFeeCoefficients { 99 | // Map 10kb proof to 1 CENT. 100 | let p = CENTS; 101 | let q = 10_000; 102 | 103 | smallvec![WeightToFeeCoefficient { 104 | degree: 1, 105 | negative: false, 106 | coeff_frac: Perbill::from_rational(p % q, q), 107 | coeff_integer: p / q, 108 | }] 109 | } 110 | } 111 | 112 | pub fn base_tx_fee() -> Balance { 113 | CENTS / 10 114 | } 115 | 116 | pub fn default_fee_per_second() -> u128 { 117 | let base_weight = Balance::from(ExtrinsicBaseWeight::get().ref_time()); 118 | let base_tx_per_second = (WEIGHT_REF_TIME_PER_SECOND as u128) / base_weight; 119 | base_tx_per_second * base_tx_fee() 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /runtime/trappist/src/contracts.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use crate::{ 19 | constants::currency::deposit, weights, Balance, Balances, RandomnessCollectiveFlip, Runtime, 20 | RuntimeCall, RuntimeEvent, RuntimeHoldReason, Timestamp, 21 | }; 22 | use frame_support::{ 23 | parameter_types, 24 | traits::{ConstBool, ConstU32, Nothing}, 25 | }; 26 | use pallet_contracts::{Config, DebugInfo, DefaultAddressGenerator, Frame, Schedule}; 27 | use sp_runtime::Perbill; 28 | 29 | // Prints debug output of the `contracts` pallet to stdout if the node is 30 | // started with `-lruntime::contracts=debug`. 31 | pub const CONTRACTS_DEBUG_OUTPUT: DebugInfo = DebugInfo::UnsafeDebug; 32 | 33 | parameter_types! { 34 | pub const DepositPerItem: Balance = deposit(1, 0); 35 | pub const DepositPerByte: Balance = deposit(0, 1); 36 | pub MySchedule: Schedule = Default::default(); 37 | pub const DefaultDepositLimit: Balance = deposit(1024, 1024 * 1024); 38 | pub CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(30); 39 | } 40 | 41 | impl Config for Runtime { 42 | type Time = Timestamp; 43 | type Randomness = RandomnessCollectiveFlip; 44 | type Currency = Balances; 45 | type RuntimeEvent = RuntimeEvent; 46 | type RuntimeCall = RuntimeCall; 47 | /// The safest default is to allow no calls at all. 48 | /// 49 | /// Runtimes should whitelist dispatchables that are allowed to be called from contracts 50 | /// and make sure they are stable. Dispatchables exposed to contracts are not allowed to 51 | /// change because that would break already deployed contracts. The `Call` structure itself 52 | /// is not allowed to change the indices of existing pallets, too. 53 | type CallFilter = Nothing; 54 | type WeightPrice = pallet_transaction_payment::Pallet; 55 | type WeightInfo = weights::pallet_contracts::WeightInfo; 56 | type ChainExtension = (); 57 | type Schedule = MySchedule; 58 | type CallStack = [Frame; 5]; 59 | type DepositPerByte = DepositPerByte; 60 | type DefaultDepositLimit = DefaultDepositLimit; 61 | type DepositPerItem = DepositPerItem; 62 | type AddressGenerator = DefaultAddressGenerator; 63 | type MaxCodeLen = ConstU32<{ 123 * 1024 }>; 64 | type MaxStorageKeyLen = ConstU32<128>; 65 | type UnsafeUnstableInterface = ConstBool; 66 | type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>; 67 | #[cfg(not(feature = "runtime-benchmarks"))] 68 | type Migrations = ( 69 | pallet_contracts::migration::v13::Migration, 70 | pallet_contracts::migration::v14::Migration, 71 | pallet_contracts::migration::v15::Migration, 72 | ); 73 | #[cfg(feature = "runtime-benchmarks")] 74 | type Migrations = pallet_contracts::migration::codegen::BenchMigrations; 75 | type MaxDelegateDependencies = ConstU32<32>; 76 | type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; 77 | type Debug = (); 78 | type Environment = (); 79 | type RuntimeHoldReason = RuntimeHoldReason; 80 | type Xcm = pallet_xcm::Pallet; 81 | } 82 | -------------------------------------------------------------------------------- /runtime/trappist/src/weights/block_weights.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev 19 | //! DATE: 2024-02-15 (Y/M/D) 20 | //! HOSTNAME: `runner-bn-ce5rx-project-647-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` 21 | //! 22 | //! SHORT-NAME: `block`, LONG-NAME: `BlockExecution`, RUNTIME: `Trappist Development` 23 | //! WARMUPS: `10`, REPEAT: `100` 24 | //! WEIGHT-PATH: `./runtime/trappist/src/weights/` 25 | //! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` 26 | 27 | // Executed Command: 28 | // ./target/production/trappist-node 29 | // benchmark 30 | // overhead 31 | // --chain=trappist-dev 32 | // --wasm-execution=compiled 33 | // --weight-path=./runtime/trappist/src/weights/ 34 | // --warmup=10 35 | // --repeat=100 36 | // --header=./templates/file_header.txt 37 | 38 | use sp_core::parameter_types; 39 | use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight}; 40 | 41 | parameter_types! { 42 | /// Time to execute an empty block. 43 | /// Calculated by multiplying the *Average* with `1.0` and adding `0`. 44 | /// 45 | /// Stats nanoseconds: 46 | /// Min, Max: 379_384, 498_695 47 | /// Average: 390_088 48 | /// Median: 388_174 49 | /// Std-Dev: 12292.78 50 | /// 51 | /// Percentiles nanoseconds: 52 | /// 99th: 405_012 53 | /// 95th: 402_611 54 | /// 75th: 391_388 55 | pub const BlockExecutionWeight: Weight = 56 | Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(390_088), 0); 57 | } 58 | 59 | #[cfg(test)] 60 | mod test_weights { 61 | use sp_weights::constants; 62 | 63 | /// Checks that the weight exists and is sane. 64 | // NOTE: If this test fails but you are sure that the generated values are fine, 65 | // you can delete it. 66 | #[test] 67 | fn sane() { 68 | let w = super::BlockExecutionWeight::get(); 69 | 70 | // At least 100 µs. 71 | assert!( 72 | w.ref_time() >= 100u64 * constants::WEIGHT_REF_TIME_PER_MICROS, 73 | "Weight should be at least 100 µs." 74 | ); 75 | // At most 50 ms. 76 | assert!( 77 | w.ref_time() <= 50u64 * constants::WEIGHT_REF_TIME_PER_MILLIS, 78 | "Weight should be at most 50 ms." 79 | ); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /runtime/trappist/src/weights/extrinsic_weights.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev 19 | //! DATE: 2024-02-15 (Y/M/D) 20 | //! HOSTNAME: `runner-bn-ce5rx-project-647-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` 21 | //! 22 | //! SHORT-NAME: `extrinsic`, LONG-NAME: `ExtrinsicBase`, RUNTIME: `Trappist Development` 23 | //! WARMUPS: `10`, REPEAT: `100` 24 | //! WEIGHT-PATH: `./runtime/trappist/src/weights/` 25 | //! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` 26 | 27 | // Executed Command: 28 | // ./target/production/trappist-node 29 | // benchmark 30 | // overhead 31 | // --chain=trappist-dev 32 | // --wasm-execution=compiled 33 | // --weight-path=./runtime/trappist/src/weights/ 34 | // --warmup=10 35 | // --repeat=100 36 | // --header=./templates/file_header.txt 37 | 38 | use sp_core::parameter_types; 39 | use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight}; 40 | 41 | parameter_types! { 42 | /// Time to execute a NO-OP extrinsic, for example `System::remark`. 43 | /// Calculated by multiplying the *Average* with `1.0` and adding `0`. 44 | /// 45 | /// Stats nanoseconds: 46 | /// Min, Max: 110_153, 111_678 47 | /// Average: 110_609 48 | /// Median: 110_575 49 | /// Std-Dev: 239.85 50 | /// 51 | /// Percentiles nanoseconds: 52 | /// 99th: 111_174 53 | /// 95th: 110_945 54 | /// 75th: 110_788 55 | pub const ExtrinsicBaseWeight: Weight = 56 | Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(110_609), 0); 57 | } 58 | 59 | #[cfg(test)] 60 | mod test_weights { 61 | use sp_weights::constants; 62 | 63 | /// Checks that the weight exists and is sane. 64 | // NOTE: If this test fails but you are sure that the generated values are fine, 65 | // you can delete it. 66 | #[test] 67 | fn sane() { 68 | let w = super::ExtrinsicBaseWeight::get(); 69 | 70 | // At least 10 µs. 71 | assert!( 72 | w.ref_time() >= 10u64 * constants::WEIGHT_REF_TIME_PER_MICROS, 73 | "Weight should be at least 10 µs." 74 | ); 75 | // At most 1 ms. 76 | assert!( 77 | w.ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, 78 | "Weight should be at most 1 ms." 79 | ); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /runtime/trappist/src/weights/mod.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use ::trappist_runtime_benchmarks::WeightInfo; 19 | use frame_support::weights::Weight; 20 | use xcm_primitives::DropAssetsWeigher; 21 | 22 | use crate::Runtime; 23 | 24 | pub mod block_weights; 25 | pub mod cumulus_pallet_xcmp_queue; 26 | pub mod extrinsic_weights; 27 | pub mod frame_system; 28 | pub mod pallet_asset_registry; 29 | pub mod pallet_assets; 30 | pub mod pallet_balances; 31 | pub mod pallet_collator_selection; 32 | pub mod pallet_collective; 33 | pub mod pallet_contracts; 34 | pub mod pallet_democracy; 35 | pub mod pallet_identity; 36 | pub mod pallet_multisig; 37 | pub mod pallet_preimage; 38 | pub mod pallet_safe_mode; 39 | pub mod pallet_scheduler; 40 | pub mod pallet_session; 41 | pub mod pallet_timestamp; 42 | pub mod pallet_treasury; 43 | pub mod pallet_tx_pause; 44 | pub mod pallet_uniques; 45 | pub mod pallet_utility; 46 | pub mod pallet_withdraw_teleport; 47 | pub mod trappist_runtime_benchmarks; 48 | pub mod xcm; 49 | 50 | pub struct TrappistDropAssetsWeigher(); 51 | impl DropAssetsWeigher for TrappistDropAssetsWeigher { 52 | fn fungible() -> Weight { 53 | trappist_runtime_benchmarks::WeightInfo::::drop_assets_fungible() 54 | } 55 | 56 | fn native() -> Weight { 57 | trappist_runtime_benchmarks::WeightInfo::::drop_assets_native() 58 | } 59 | 60 | fn default() -> Weight { 61 | trappist_runtime_benchmarks::WeightInfo::::drop_assets_default() 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /runtime/trappist/src/weights/pallet_asset_registry.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! Autogenerated weights for `pallet_asset_registry` 19 | //! 20 | //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev 21 | //! DATE: 2024-02-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` 22 | //! WORST CASE MAP SIZE: `1000000` 23 | //! HOSTNAME: `runner-bn-ce5rx-project-647-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` 24 | //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("trappist-dev")`, DB CACHE: 1024 25 | 26 | // Executed Command: 27 | // ./target/production/trappist-node 28 | // benchmark 29 | // pallet 30 | // --chain=trappist-dev 31 | // --steps=50 32 | // --repeat=20 33 | // --no-storage-info 34 | // --no-median-slopes 35 | // --no-min-squares 36 | // --pallet=pallet_asset_registry 37 | // --extrinsic=* 38 | // --wasm-execution=compiled 39 | // --header=./templates/file_header.txt 40 | // --output=./runtime/trappist/src/weights/ 41 | 42 | #![cfg_attr(rustfmt, rustfmt_skip)] 43 | #![allow(unused_parens)] 44 | #![allow(unused_imports)] 45 | #![allow(missing_docs)] 46 | 47 | use frame_support::{traits::Get, weights::Weight}; 48 | use core::marker::PhantomData; 49 | 50 | /// Weight functions for `pallet_asset_registry`. 51 | pub struct WeightInfo(PhantomData); 52 | impl pallet_asset_registry::WeightInfo for WeightInfo { 53 | /// Storage: `Assets::Asset` (r:1 w:0) 54 | /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) 55 | /// Storage: `AssetRegistry::AssetIdMultiLocation` (r:1 w:1) 56 | /// Proof: `AssetRegistry::AssetIdMultiLocation` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) 57 | /// Storage: `AssetRegistry::AssetMultiLocationId` (r:0 w:1) 58 | /// Proof: `AssetRegistry::AssetMultiLocationId` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) 59 | fn register_reserve_asset() -> Weight { 60 | // Proof Size summary in bytes: 61 | // Measured: `123` 62 | // Estimated: `4087` 63 | // Minimum execution time: 15_977_000 picoseconds. 64 | Weight::from_parts(16_506_000, 0) 65 | .saturating_add(Weight::from_parts(0, 4087)) 66 | .saturating_add(T::DbWeight::get().reads(2)) 67 | .saturating_add(T::DbWeight::get().writes(2)) 68 | } 69 | /// Storage: `AssetRegistry::AssetIdMultiLocation` (r:1 w:1) 70 | /// Proof: `AssetRegistry::AssetIdMultiLocation` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) 71 | /// Storage: `AssetRegistry::AssetMultiLocationId` (r:0 w:1) 72 | /// Proof: `AssetRegistry::AssetMultiLocationId` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) 73 | fn unregister_reserve_asset() -> Weight { 74 | // Proof Size summary in bytes: 75 | // Measured: `107` 76 | // Estimated: `4087` 77 | // Minimum execution time: 12_833_000 picoseconds. 78 | Weight::from_parts(13_330_000, 0) 79 | .saturating_add(Weight::from_parts(0, 4087)) 80 | .saturating_add(T::DbWeight::get().reads(1)) 81 | .saturating_add(T::DbWeight::get().writes(2)) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /runtime/trappist/src/weights/pallet_session.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! Autogenerated weights for `pallet_session` 19 | //! 20 | //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev 21 | //! DATE: 2024-02-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` 22 | //! WORST CASE MAP SIZE: `1000000` 23 | //! HOSTNAME: `runner-bn-ce5rx-project-647-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` 24 | //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("trappist-dev")`, DB CACHE: 1024 25 | 26 | // Executed Command: 27 | // ./target/production/trappist-node 28 | // benchmark 29 | // pallet 30 | // --chain=trappist-dev 31 | // --steps=50 32 | // --repeat=20 33 | // --no-storage-info 34 | // --no-median-slopes 35 | // --no-min-squares 36 | // --pallet=pallet_session 37 | // --extrinsic=* 38 | // --wasm-execution=compiled 39 | // --header=./templates/file_header.txt 40 | // --output=./runtime/trappist/src/weights/ 41 | 42 | #![cfg_attr(rustfmt, rustfmt_skip)] 43 | #![allow(unused_parens)] 44 | #![allow(unused_imports)] 45 | #![allow(missing_docs)] 46 | 47 | use frame_support::{traits::Get, weights::Weight}; 48 | use core::marker::PhantomData; 49 | 50 | /// Weight functions for `pallet_session`. 51 | pub struct WeightInfo(PhantomData); 52 | impl pallet_session::WeightInfo for WeightInfo { 53 | /// Storage: `Session::NextKeys` (r:1 w:1) 54 | /// Proof: `Session::NextKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) 55 | /// Storage: `Session::KeyOwner` (r:1 w:1) 56 | /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) 57 | fn set_keys() -> Weight { 58 | // Proof Size summary in bytes: 59 | // Measured: `298` 60 | // Estimated: `3763` 61 | // Minimum execution time: 15_814_000 picoseconds. 62 | Weight::from_parts(16_197_000, 0) 63 | .saturating_add(Weight::from_parts(0, 3763)) 64 | .saturating_add(T::DbWeight::get().reads(2)) 65 | .saturating_add(T::DbWeight::get().writes(2)) 66 | } 67 | /// Storage: `Session::NextKeys` (r:1 w:1) 68 | /// Proof: `Session::NextKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) 69 | /// Storage: `Session::KeyOwner` (r:0 w:1) 70 | /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) 71 | fn purge_keys() -> Weight { 72 | // Proof Size summary in bytes: 73 | // Measured: `280` 74 | // Estimated: `3745` 75 | // Minimum execution time: 11_054_000 picoseconds. 76 | Weight::from_parts(11_534_000, 0) 77 | .saturating_add(Weight::from_parts(0, 3745)) 78 | .saturating_add(T::DbWeight::get().reads(1)) 79 | .saturating_add(T::DbWeight::get().writes(2)) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /runtime/trappist/src/weights/pallet_timestamp.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! Autogenerated weights for `pallet_timestamp` 19 | //! 20 | //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev 21 | //! DATE: 2024-02-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` 22 | //! WORST CASE MAP SIZE: `1000000` 23 | //! HOSTNAME: `runner-bn-ce5rx-project-647-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` 24 | //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("trappist-dev")`, DB CACHE: 1024 25 | 26 | // Executed Command: 27 | // ./target/production/trappist-node 28 | // benchmark 29 | // pallet 30 | // --chain=trappist-dev 31 | // --steps=50 32 | // --repeat=20 33 | // --no-storage-info 34 | // --no-median-slopes 35 | // --no-min-squares 36 | // --pallet=pallet_timestamp 37 | // --extrinsic=* 38 | // --wasm-execution=compiled 39 | // --header=./templates/file_header.txt 40 | // --output=./runtime/trappist/src/weights/ 41 | 42 | #![cfg_attr(rustfmt, rustfmt_skip)] 43 | #![allow(unused_parens)] 44 | #![allow(unused_imports)] 45 | #![allow(missing_docs)] 46 | 47 | use frame_support::{traits::Get, weights::Weight}; 48 | use core::marker::PhantomData; 49 | 50 | /// Weight functions for `pallet_timestamp`. 51 | pub struct WeightInfo(PhantomData); 52 | impl pallet_timestamp::WeightInfo for WeightInfo { 53 | /// Storage: `Timestamp::Now` (r:1 w:1) 54 | /// Proof: `Timestamp::Now` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) 55 | /// Storage: `Aura::CurrentSlot` (r:1 w:0) 56 | /// Proof: `Aura::CurrentSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) 57 | fn set() -> Weight { 58 | // Proof Size summary in bytes: 59 | // Measured: `190` 60 | // Estimated: `1493` 61 | // Minimum execution time: 7_367_000 picoseconds. 62 | Weight::from_parts(7_723_000, 0) 63 | .saturating_add(Weight::from_parts(0, 1493)) 64 | .saturating_add(T::DbWeight::get().reads(2)) 65 | .saturating_add(T::DbWeight::get().writes(1)) 66 | } 67 | fn on_finalize() -> Weight { 68 | // Proof Size summary in bytes: 69 | // Measured: `128` 70 | // Estimated: `0` 71 | // Minimum execution time: 4_234_000 picoseconds. 72 | Weight::from_parts(4_531_000, 0) 73 | .saturating_add(Weight::from_parts(0, 0)) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /runtime/trappist/src/weights/pallet_tx_pause.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! Autogenerated weights for `pallet_tx_pause` 19 | //! 20 | //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev 21 | //! DATE: 2024-02-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` 22 | //! WORST CASE MAP SIZE: `1000000` 23 | //! HOSTNAME: `runner-bn-ce5rx-project-647-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` 24 | //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("trappist-dev")`, DB CACHE: 1024 25 | 26 | // Executed Command: 27 | // ./target/production/trappist-node 28 | // benchmark 29 | // pallet 30 | // --chain=trappist-dev 31 | // --steps=50 32 | // --repeat=20 33 | // --no-storage-info 34 | // --no-median-slopes 35 | // --no-min-squares 36 | // --pallet=pallet_tx_pause 37 | // --extrinsic=* 38 | // --wasm-execution=compiled 39 | // --header=./templates/file_header.txt 40 | // --output=./runtime/trappist/src/weights/ 41 | 42 | #![cfg_attr(rustfmt, rustfmt_skip)] 43 | #![allow(unused_parens)] 44 | #![allow(unused_imports)] 45 | #![allow(missing_docs)] 46 | 47 | use frame_support::{traits::Get, weights::Weight}; 48 | use core::marker::PhantomData; 49 | 50 | /// Weight functions for `pallet_tx_pause`. 51 | pub struct WeightInfo(PhantomData); 52 | impl pallet_tx_pause::WeightInfo for WeightInfo { 53 | /// Storage: `TxPause::PausedCalls` (r:1 w:1) 54 | /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) 55 | fn pause() -> Weight { 56 | // Proof Size summary in bytes: 57 | // Measured: `4` 58 | // Estimated: `3997` 59 | // Minimum execution time: 12_239_000 picoseconds. 60 | Weight::from_parts(12_706_000, 0) 61 | .saturating_add(Weight::from_parts(0, 3997)) 62 | .saturating_add(T::DbWeight::get().reads(1)) 63 | .saturating_add(T::DbWeight::get().writes(1)) 64 | } 65 | /// Storage: `TxPause::PausedCalls` (r:1 w:1) 66 | /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) 67 | fn unpause() -> Weight { 68 | // Proof Size summary in bytes: 69 | // Measured: `566` 70 | // Estimated: `3997` 71 | // Minimum execution time: 18_008_000 picoseconds. 72 | Weight::from_parts(18_561_000, 0) 73 | .saturating_add(Weight::from_parts(0, 3997)) 74 | .saturating_add(T::DbWeight::get().reads(1)) 75 | .saturating_add(T::DbWeight::get().writes(1)) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /runtime/trappist/src/weights/pallet_utility.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! Autogenerated weights for `pallet_utility` 19 | //! 20 | //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev 21 | //! DATE: 2024-02-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` 22 | //! WORST CASE MAP SIZE: `1000000` 23 | //! HOSTNAME: `runner-bn-ce5rx-project-647-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` 24 | //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("trappist-dev")`, DB CACHE: 1024 25 | 26 | // Executed Command: 27 | // ./target/production/trappist-node 28 | // benchmark 29 | // pallet 30 | // --chain=trappist-dev 31 | // --steps=50 32 | // --repeat=20 33 | // --no-storage-info 34 | // --no-median-slopes 35 | // --no-min-squares 36 | // --pallet=pallet_utility 37 | // --extrinsic=* 38 | // --wasm-execution=compiled 39 | // --header=./templates/file_header.txt 40 | // --output=./runtime/trappist/src/weights/ 41 | 42 | #![cfg_attr(rustfmt, rustfmt_skip)] 43 | #![allow(unused_parens)] 44 | #![allow(unused_imports)] 45 | #![allow(missing_docs)] 46 | 47 | use frame_support::{traits::Get, weights::Weight}; 48 | use core::marker::PhantomData; 49 | 50 | /// Weight functions for `pallet_utility`. 51 | pub struct WeightInfo(PhantomData); 52 | impl pallet_utility::WeightInfo for WeightInfo { 53 | /// The range of component `c` is `[0, 1000]`. 54 | fn batch(c: u32, ) -> Weight { 55 | // Proof Size summary in bytes: 56 | // Measured: `0` 57 | // Estimated: `0` 58 | // Minimum execution time: 4_465_000 picoseconds. 59 | Weight::from_parts(6_596_364, 0) 60 | .saturating_add(Weight::from_parts(0, 0)) 61 | // Standard Error: 3_845 62 | .saturating_add(Weight::from_parts(3_648_493, 0).saturating_mul(c.into())) 63 | } 64 | fn as_derivative() -> Weight { 65 | // Proof Size summary in bytes: 66 | // Measured: `0` 67 | // Estimated: `0` 68 | // Minimum execution time: 4_302_000 picoseconds. 69 | Weight::from_parts(4_529_000, 0) 70 | .saturating_add(Weight::from_parts(0, 0)) 71 | } 72 | /// The range of component `c` is `[0, 1000]`. 73 | fn batch_all(c: u32, ) -> Weight { 74 | // Proof Size summary in bytes: 75 | // Measured: `0` 76 | // Estimated: `0` 77 | // Minimum execution time: 4_262_000 picoseconds. 78 | Weight::from_parts(11_425_884, 0) 79 | .saturating_add(Weight::from_parts(0, 0)) 80 | // Standard Error: 3_500 81 | .saturating_add(Weight::from_parts(3_887_921, 0).saturating_mul(c.into())) 82 | } 83 | fn dispatch_as() -> Weight { 84 | // Proof Size summary in bytes: 85 | // Measured: `0` 86 | // Estimated: `0` 87 | // Minimum execution time: 6_425_000 picoseconds. 88 | Weight::from_parts(6_820_000, 0) 89 | .saturating_add(Weight::from_parts(0, 0)) 90 | } 91 | /// The range of component `c` is `[0, 1000]`. 92 | fn force_batch(c: u32, ) -> Weight { 93 | // Proof Size summary in bytes: 94 | // Measured: `0` 95 | // Estimated: `0` 96 | // Minimum execution time: 4_372_000 picoseconds. 97 | Weight::from_parts(14_534_844, 0) 98 | .saturating_add(Weight::from_parts(0, 0)) 99 | // Standard Error: 3_592 100 | .saturating_add(Weight::from_parts(3_622_262, 0).saturating_mul(c.into())) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /runtime/trappist/src/weights/pallet_withdraw_teleport.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! Autogenerated weights for `pallet_withdraw_teleport` 19 | //! 20 | //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev 21 | //! DATE: 2024-02-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` 22 | //! WORST CASE MAP SIZE: `1000000` 23 | //! HOSTNAME: `runner-bn-ce5rx-project-647-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` 24 | //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("trappist-dev")`, DB CACHE: 1024 25 | 26 | // Executed Command: 27 | // ./target/production/trappist-node 28 | // benchmark 29 | // pallet 30 | // --chain=trappist-dev 31 | // --steps=50 32 | // --repeat=20 33 | // --no-storage-info 34 | // --no-median-slopes 35 | // --no-min-squares 36 | // --pallet=pallet_withdraw_teleport 37 | // --extrinsic=* 38 | // --wasm-execution=compiled 39 | // --header=./templates/file_header.txt 40 | // --output=./runtime/trappist/src/weights/ 41 | 42 | #![cfg_attr(rustfmt, rustfmt_skip)] 43 | #![allow(unused_parens)] 44 | #![allow(unused_imports)] 45 | #![allow(missing_docs)] 46 | 47 | use frame_support::{traits::Get, weights::Weight}; 48 | use core::marker::PhantomData; 49 | 50 | /// Weight functions for `pallet_withdraw_teleport`. 51 | pub struct WeightInfo(PhantomData); 52 | impl pallet_withdraw_teleport::WeightInfo for WeightInfo { 53 | /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) 54 | /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) 55 | /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) 56 | /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) 57 | /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) 58 | /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) 59 | /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) 60 | /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) 61 | /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) 62 | /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) 63 | /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) 64 | /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) 65 | fn withdraw_and_teleport() -> Weight { 66 | // Proof Size summary in bytes: 67 | // Measured: `143` 68 | // Estimated: `3608` 69 | // Minimum execution time: 73_799_000 picoseconds. 70 | Weight::from_parts(75_761_000, 0) 71 | .saturating_add(Weight::from_parts(0, 3608)) 72 | .saturating_add(T::DbWeight::get().reads(6)) 73 | .saturating_add(T::DbWeight::get().writes(2)) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /runtime/trappist/src/weights/trappist_runtime_benchmarks.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! Autogenerated weights for `trappist_runtime_benchmarks` 19 | //! 20 | //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev 21 | //! DATE: 2024-02-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` 22 | //! WORST CASE MAP SIZE: `1000000` 23 | //! HOSTNAME: `runner-bn-ce5rx-project-647-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` 24 | //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("trappist-dev")`, DB CACHE: 1024 25 | 26 | // Executed Command: 27 | // ./target/production/trappist-node 28 | // benchmark 29 | // pallet 30 | // --chain=trappist-dev 31 | // --steps=50 32 | // --repeat=20 33 | // --no-storage-info 34 | // --no-median-slopes 35 | // --no-min-squares 36 | // --pallet=trappist_runtime_benchmarks 37 | // --extrinsic=* 38 | // --wasm-execution=compiled 39 | // --header=./templates/file_header.txt 40 | // --output=./runtime/trappist/src/weights/ 41 | 42 | #![cfg_attr(rustfmt, rustfmt_skip)] 43 | #![allow(unused_parens)] 44 | #![allow(unused_imports)] 45 | #![allow(missing_docs)] 46 | 47 | use frame_support::{traits::Get, weights::Weight}; 48 | use core::marker::PhantomData; 49 | 50 | /// Weight functions for `trappist_runtime_benchmarks`. 51 | pub struct WeightInfo(PhantomData); 52 | impl trappist_runtime_benchmarks::WeightInfo for WeightInfo { 53 | /// Storage: `AssetRegistry::AssetMultiLocationId` (r:1 w:0) 54 | /// Proof: `AssetRegistry::AssetMultiLocationId` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) 55 | /// Storage: `Assets::Asset` (r:1 w:0) 56 | /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) 57 | fn drop_assets_fungible() -> Weight { 58 | // Proof Size summary in bytes: 59 | // Measured: `131` 60 | // Estimated: `4087` 61 | // Minimum execution time: 8_160_000 picoseconds. 62 | Weight::from_parts(8_405_000, 0) 63 | .saturating_add(Weight::from_parts(0, 4087)) 64 | .saturating_add(T::DbWeight::get().reads(2)) 65 | } 66 | /// Storage: `AssetRegistry::AssetMultiLocationId` (r:1 w:0) 67 | /// Proof: `AssetRegistry::AssetMultiLocationId` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) 68 | fn drop_assets_native() -> Weight { 69 | // Proof Size summary in bytes: 70 | // Measured: `42` 71 | // Estimated: `4087` 72 | // Minimum execution time: 4_275_000 picoseconds. 73 | Weight::from_parts(4_453_000, 0) 74 | .saturating_add(Weight::from_parts(0, 4087)) 75 | .saturating_add(T::DbWeight::get().reads(1)) 76 | } 77 | fn drop_assets_default() -> Weight { 78 | // Proof Size summary in bytes: 79 | // Measured: `0` 80 | // Estimated: `0` 81 | // Minimum execution time: 865_000 picoseconds. 82 | Weight::from_parts(925_000, 0) 83 | .saturating_add(Weight::from_parts(0, 0)) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "stable" 3 | components = [ "rustfmt" ] 4 | targets = [ "wasm32-unknown-unknown" ] 5 | profile = "minimal" 6 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | # Basic 2 | hard_tabs = true 3 | max_width = 100 4 | use_small_heuristics = "Max" 5 | # Imports 6 | reorder_imports = true 7 | # Consistency 8 | newline_style = "Unix" 9 | # Misc 10 | chain_width = 80 11 | match_arm_leading_pipes = "Preserve" 12 | match_block_trailing_comma = true 13 | use_field_init_shorthand = true 14 | -------------------------------------------------------------------------------- /scripts/docker_run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # This script is meant to be run on Unix/Linux based systems 3 | set -e 4 | 5 | echo "*** Start Trappist node ***" 6 | 7 | cd $(dirname ${BASH_SOURCE[0]})/.. 8 | 9 | docker-compose down --remove-orphans 10 | docker-compose run --rm --service-ports dev $@ 11 | -------------------------------------------------------------------------------- /scripts/hrmp_helper.sh: -------------------------------------------------------------------------------- 1 | # Helper script to open HRMP channels between Trappist, Stout and Asset Hub. 2 | # This script is meant to be run after the relay chain and parachains are spawned. 3 | 4 | # Change for your bin path 5 | POLKADOT_BIN=~/projects/trappist/bin/polkadot 6 | POLKADOT_PARACHAIN_BIN=~/projects/trappist/bin/polkadot-parachain 7 | 8 | function ensure_binaries() { 9 | echo "*** Checking for required binaries" 10 | if [[ ! -f "$POLKADOT_BIN" ]]; then 11 | echo " Required polkadot binary '$POLKADOT_BIN' does not exist!" 12 | echo " You need to build it and copy to this location!" 13 | exit 1 14 | fi 15 | if [[ ! -f "$POLKADOT_PARACHAIN_BIN" ]]; then 16 | echo " Required polkadot-parachain binary '$POLKADOT_PARACHAIN_BIN' does not exist!" 17 | echo " You need to build it and copy to this location!" 18 | exit 1 19 | fi 20 | echo "*** All required binaries are present" 21 | } 22 | 23 | function ensure_polkadot_js_api() { 24 | echo "*** Checking for required polkadot-js-api" 25 | if ! which polkadot-js-api &>/dev/null; then 26 | echo '' 27 | echo 'Required command `polkadot-js-api` not in PATH, please, install, e.g.:' 28 | echo "npm install -g @polkadot/api-cli" 29 | echo " or" 30 | echo "yarn global add @polkadot/api-cli" 31 | echo '' 32 | exit 1 33 | fi 34 | } 35 | 36 | function open_hrmp_channels() { 37 | local relay_url=$1 38 | local relay_chain_seed=$2 39 | local sender_para_id=$3 40 | local recipient_para_id=$4 41 | local max_capacity=$5 42 | local max_message_size=$6 43 | echo " calling open_hrmp_channels:" 44 | echo " relay_url: ${relay_url}" 45 | echo " relay_chain_seed: ${relay_chain_seed}" 46 | echo " sender_para_id: ${sender_para_id}" 47 | echo " recipient_para_id: ${recipient_para_id}" 48 | echo " max_capacity: ${max_capacity}" 49 | echo " max_message_size: ${max_message_size}" 50 | echo " params:" 51 | echo "--------------------------------------------------" 52 | polkadot-js-api \ 53 | --ws "${relay_url?}" \ 54 | --seed "${relay_chain_seed?}" \ 55 | --sudo \ 56 | tx.hrmp.forceOpenHrmpChannel \ 57 | ${sender_para_id} \ 58 | ${recipient_para_id} \ 59 | ${max_capacity} \ 60 | ${max_message_size} 61 | } 62 | 63 | # Check for binaries 64 | ensure_binaries 65 | 66 | # Check for polkadot-js-api cli 67 | ensure_polkadot_js_api 68 | 69 | # HRMP: Trappist - Stout 70 | open_hrmp_channels \ 71 | "ws://127.0.0.1:9900" \ 72 | "//Alice" \ 73 | 1836 3000 4 524288 74 | 75 | # HRMP: Stout - Trappist 76 | open_hrmp_channels \ 77 | "ws://127.0.0.1:9900" \ 78 | "//Alice" \ 79 | 3000 1836 4 524288 80 | 81 | # HRMP: Trappist - Asset Hub 82 | open_hrmp_channels \ 83 | "ws://127.0.0.1:9900" \ 84 | "//Alice" \ 85 | 1836 1000 4 524288 86 | 87 | # HRMP: Asset Hub - Trappist 88 | open_hrmp_channels \ 89 | "ws://127.0.0.1:9900" \ 90 | "//Alice" \ 91 | 1000 1836 4 524288 92 | 93 | # HRMP: Stout - Asset Hub 94 | open_hrmp_channels \ 95 | "ws://127.0.0.1:9900" \ 96 | "//Alice" \ 97 | 3000 1000 4 524288 98 | 99 | # HRMP: Asset Hub - Stout 100 | open_hrmp_channels \ 101 | "ws://127.0.0.1:9900" \ 102 | "//Alice" \ 103 | 1000 3000 4 524288 104 | -------------------------------------------------------------------------------- /scripts/init.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # This script is meant to be run on Unix/Linux based systems 3 | set -e 4 | 5 | echo "*** Initializing WASM build environment" 6 | 7 | if [ -z $CI_PROJECT_NAME ] ; then 8 | rustup update nightly 9 | rustup update stable 10 | fi 11 | 12 | rustup target add wasm32-unknown-unknown --toolchain nightly 13 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | let 2 | mozillaOverlay = 3 | import (builtins.fetchGit { 4 | url = "https://github.com/mozilla/nixpkgs-mozilla.git"; 5 | rev = "57c8084c7ef41366993909c20491e359bbb90f54"; 6 | }); 7 | pinned = builtins.fetchGit { 8 | # Descriptive name to make the store path easier to identify 9 | url = "https://github.com/nixos/nixpkgs/"; 10 | # Commit hash for nixos-unstable as of 2020-04-26 11 | # `git ls-remote https://github.com/nixos/nixpkgs nixos-unstable` 12 | ref = "refs/heads/nixos-unstable"; 13 | rev = "1fe6ed37fd9beb92afe90671c0c2a662a03463dd"; 14 | }; 15 | nixpkgs = import pinned { overlays = [ mozillaOverlay ]; }; 16 | toolchain = with nixpkgs; (rustChannelOf { date = "2021-09-14"; channel = "nightly"; }); 17 | rust-wasm = toolchain.rust.override { 18 | targets = [ "wasm32-unknown-unknown" ]; 19 | }; 20 | in 21 | with nixpkgs; pkgs.mkShell { 22 | buildInputs = [ 23 | clang 24 | pkg-config 25 | rust-wasm 26 | ] ++ stdenv.lib.optionals stdenv.isDarwin [ 27 | darwin.apple_sdk.frameworks.Security 28 | ]; 29 | 30 | LIBCLANG_PATH = "${llvmPackages.libclang}/lib"; 31 | PROTOC = "${protobuf}/bin/protoc"; 32 | RUST_SRC_PATH = "${toolchain.rust-src}/lib/rustlib/src/rust/library/"; 33 | ROCKSDB_LIB_DIR = "${rocksdb}/lib"; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /templates/file_header.txt: -------------------------------------------------------------------------------- 1 | // This file is part of Trappist. 2 | 3 | // Copyright (C) Parity Technologies (UK) Ltd. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | -------------------------------------------------------------------------------- /templates/frame-weight-template.hbs: -------------------------------------------------------------------------------- 1 | {{header}} 2 | //! Autogenerated weights for {{pallet}} 3 | //! 4 | //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION {{version}} 5 | //! DATE: {{date}}, STEPS: `{{cmd.steps}}`, REPEAT: `{{cmd.repeat}}`, LOW RANGE: `{{cmd.lowest_range_values}}`, HIGH RANGE: `{{cmd.highest_range_values}}` 6 | //! WORST CASE MAP SIZE: `{{cmd.worst_case_map_values}}` 7 | //! HOSTNAME: `{{hostname}}`, CPU: `{{cpuname}}` 8 | //! EXECUTION: {{cmd.execution}}, WASM-EXECUTION: {{cmd.wasm_execution}}, CHAIN: {{cmd.chain}}, DB CACHE: {{cmd.db_cache}} 9 | 10 | // Executed Command: 11 | {{#each args as |arg|}} 12 | // {{arg}} 13 | {{/each}} 14 | 15 | #![cfg_attr(rustfmt, rustfmt_skip)] 16 | #![allow(unused_parens)] 17 | #![allow(unused_imports)] 18 | #![allow(missing_docs)] 19 | 20 | use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; 21 | use core::marker::PhantomData; 22 | 23 | /// Weight functions needed for {{pallet}}. 24 | pub trait WeightInfo { 25 | {{#each benchmarks as |benchmark|}} 26 | fn {{benchmark.name~}} 27 | ( 28 | {{~#each benchmark.components as |c| ~}} 29 | {{c.name}}: u32, {{/each~}} 30 | ) -> Weight; 31 | {{/each}} 32 | } 33 | 34 | /// Weights for {{pallet}} using the Substrate node and recommended hardware. 35 | pub struct SubstrateWeight(PhantomData); 36 | {{#if (eq pallet "frame_system")}} 37 | impl WeightInfo for SubstrateWeight { 38 | {{else}} 39 | impl WeightInfo for SubstrateWeight { 40 | {{/if}} 41 | {{#each benchmarks as |benchmark|}} 42 | {{#each benchmark.comments as |comment|}} 43 | /// {{comment}} 44 | {{/each}} 45 | {{#each benchmark.component_ranges as |range|}} 46 | /// The range of component `{{range.name}}` is `[{{range.min}}, {{range.max}}]`. 47 | {{/each}} 48 | fn {{benchmark.name~}} 49 | ( 50 | {{~#each benchmark.components as |c| ~}} 51 | {{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}} 52 | ) -> Weight { 53 | // Proof Size summary in bytes: 54 | // Measured: `{{benchmark.base_recorded_proof_size}}{{#each benchmark.component_recorded_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` 55 | // Estimated: `{{benchmark.base_calculated_proof_size}}{{#each benchmark.component_calculated_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` 56 | // Minimum execution time: {{underscore benchmark.min_execution_time}}_000 picoseconds. 57 | Weight::from_parts({{underscore benchmark.base_weight}}, {{benchmark.base_calculated_proof_size}}) 58 | {{#each benchmark.component_weight as |cw|}} 59 | // Standard Error: {{underscore cw.error}} 60 | .saturating_add(Weight::from_parts({{underscore cw.slope}}, 0).saturating_mul({{cw.name}}.into())) 61 | {{/each}} 62 | {{#if (ne benchmark.base_reads "0")}} 63 | .saturating_add(T::DbWeight::get().reads({{benchmark.base_reads}}_u64)) 64 | {{/if}} 65 | {{#each benchmark.component_reads as |cr|}} 66 | .saturating_add(T::DbWeight::get().reads(({{cr.slope}}_u64).saturating_mul({{cr.name}}.into()))) 67 | {{/each}} 68 | {{#if (ne benchmark.base_writes "0")}} 69 | .saturating_add(T::DbWeight::get().writes({{benchmark.base_writes}}_u64)) 70 | {{/if}} 71 | {{#each benchmark.component_writes as |cw|}} 72 | .saturating_add(T::DbWeight::get().writes(({{cw.slope}}_u64).saturating_mul({{cw.name}}.into()))) 73 | {{/each}} 74 | {{#each benchmark.component_calculated_proof_size as |cp|}} 75 | .saturating_add(Weight::from_parts(0, {{cp.slope}}).saturating_mul({{cp.name}}.into())) 76 | {{/each}} 77 | } 78 | {{/each}} 79 | } 80 | 81 | // For backwards compatibility and tests 82 | impl WeightInfo for () { 83 | {{#each benchmarks as |benchmark|}} 84 | {{#each benchmark.comments as |comment|}} 85 | /// {{comment}} 86 | {{/each}} 87 | {{#each benchmark.component_ranges as |range|}} 88 | /// The range of component `{{range.name}}` is `[{{range.min}}, {{range.max}}]`. 89 | {{/each}} 90 | fn {{benchmark.name~}} 91 | ( 92 | {{~#each benchmark.components as |c| ~}} 93 | {{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}} 94 | ) -> Weight { 95 | // Proof Size summary in bytes: 96 | // Measured: `{{benchmark.base_recorded_proof_size}}{{#each benchmark.component_recorded_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` 97 | // Estimated: `{{benchmark.base_calculated_proof_size}}{{#each benchmark.component_calculated_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` 98 | // Minimum execution time: {{underscore benchmark.min_execution_time}}_000 picoseconds. 99 | Weight::from_parts({{underscore benchmark.base_weight}}, {{benchmark.base_calculated_proof_size}}) 100 | {{#each benchmark.component_weight as |cw|}} 101 | // Standard Error: {{underscore cw.error}} 102 | .saturating_add(Weight::from_parts({{underscore cw.slope}}, 0).saturating_mul({{cw.name}}.into())) 103 | {{/each}} 104 | {{#if (ne benchmark.base_reads "0")}} 105 | .saturating_add(RocksDbWeight::get().reads({{benchmark.base_reads}}_u64)) 106 | {{/if}} 107 | {{#each benchmark.component_reads as |cr|}} 108 | .saturating_add(RocksDbWeight::get().reads(({{cr.slope}}_u64).saturating_mul({{cr.name}}.into()))) 109 | {{/each}} 110 | {{#if (ne benchmark.base_writes "0")}} 111 | .saturating_add(RocksDbWeight::get().writes({{benchmark.base_writes}}_u64)) 112 | {{/if}} 113 | {{#each benchmark.component_writes as |cw|}} 114 | .saturating_add(RocksDbWeight::get().writes(({{cw.slope}}_u64).saturating_mul({{cw.name}}.into()))) 115 | {{/each}} 116 | {{#each benchmark.component_calculated_proof_size as |cp|}} 117 | .saturating_add(Weight::from_parts(0, {{cp.slope}}).saturating_mul({{cp.name}}.into())) 118 | {{/each}} 119 | } 120 | {{/each}} 121 | } 122 | -------------------------------------------------------------------------------- /templates/xcm-bench-template.hbs: -------------------------------------------------------------------------------- 1 | {{header}} 2 | //! Autogenerated weights for `{{pallet}}` 3 | //! 4 | //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION {{version}} 5 | //! DATE: {{date}}, STEPS: `{{cmd.steps}}`, REPEAT: `{{cmd.repeat}}`, LOW RANGE: `{{cmd.lowest_range_values}}`, HIGH RANGE: `{{cmd.highest_range_values}}` 6 | //! WORST CASE MAP SIZE: `{{cmd.worst_case_map_values}}` 7 | //! HOSTNAME: `{{hostname}}`, CPU: `{{cpuname}}` 8 | //! EXECUTION: {{cmd.execution}}, WASM-EXECUTION: {{cmd.wasm_execution}}, CHAIN: {{cmd.chain}}, DB CACHE: {{cmd.db_cache}} 9 | 10 | // Executed Command: 11 | {{#each args as |arg|}} 12 | // {{arg}} 13 | {{/each}} 14 | 15 | #![cfg_attr(rustfmt, rustfmt_skip)] 16 | #![allow(unused_parens)] 17 | #![allow(unused_imports)] 18 | #![allow(missing_docs)] 19 | 20 | use frame_support::{traits::Get, weights::Weight}; 21 | use core::marker::PhantomData; 22 | 23 | /// Weight functions for `{{pallet}}`. 24 | pub struct WeightInfo(PhantomData); 25 | impl WeightInfo { 26 | {{#each benchmarks as |benchmark|}} 27 | {{#each benchmark.comments as |comment|}} 28 | /// {{comment}} 29 | {{/each}} 30 | {{#each benchmark.component_ranges as |range|}} 31 | /// The range of component `{{range.name}}` is `[{{range.min}}, {{range.max}}]`. 32 | {{/each}} 33 | pub(crate) fn {{benchmark.name~}} 34 | ( 35 | {{~#each benchmark.components as |c| ~}} 36 | {{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}} 37 | ) -> Weight { 38 | // Proof Size summary in bytes: 39 | // Measured: `{{benchmark.base_recorded_proof_size}}{{#each benchmark.component_recorded_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` 40 | // Estimated: `{{benchmark.base_calculated_proof_size}}{{#each benchmark.component_calculated_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` 41 | // Minimum execution time: {{underscore benchmark.min_execution_time}}_000 picoseconds. 42 | Weight::from_parts({{underscore benchmark.base_weight}}, {{benchmark.base_calculated_proof_size}}) 43 | {{#each benchmark.component_weight as |cw|}} 44 | // Standard Error: {{underscore cw.error}} 45 | .saturating_add(Weight::from_parts({{underscore cw.slope}}, 0).saturating_mul({{cw.name}}.into())) 46 | {{/each}} 47 | {{#if (ne benchmark.base_reads "0")}} 48 | .saturating_add(T::DbWeight::get().reads({{benchmark.base_reads}})) 49 | {{/if}} 50 | {{#each benchmark.component_reads as |cr|}} 51 | .saturating_add(T::DbWeight::get().reads(({{cr.slope}}_u64).saturating_mul({{cr.name}}.into()))) 52 | {{/each}} 53 | {{#if (ne benchmark.base_writes "0")}} 54 | .saturating_add(T::DbWeight::get().writes({{benchmark.base_writes}})) 55 | {{/if}} 56 | {{#each benchmark.component_writes as |cw|}} 57 | .saturating_add(T::DbWeight::get().writes(({{cw.slope}}_u64).saturating_mul({{cw.name}}.into()))) 58 | {{/each}} 59 | {{#each benchmark.component_calculated_proof_size as |cp|}} 60 | .saturating_add(Weight::from_parts(0, {{cp.slope}}).saturating_mul({{cp.name}}.into())) 61 | {{/each}} 62 | } 63 | {{/each}} 64 | } 65 | -------------------------------------------------------------------------------- /xcm-simulator/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "xcm-simulator-trappist" 3 | version = "0.1.0" 4 | authors = ["Parity Technologies "] 5 | description = "Examples of xcm-simulator usage." 6 | edition = "2021" 7 | 8 | [dependencies] 9 | codec = { package = "parity-scale-codec", version = "3.0.0" } 10 | scale-info = { version = "2.1.2", features = ["derive"] } 11 | thousands = "0.2.0" 12 | tracing = { version = "0.1.37" } 13 | tracing-subscriber = { version = "0.3.16", features = ["env-filter", "tracing-log"] } 14 | 15 | frame-system = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 16 | frame-support = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 17 | pallet-assets = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 18 | pallet-asset-registry = { version = "0.0.1", path = "../pallets/asset-registry" } 19 | pallet-balances = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 20 | pallet-sudo = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 21 | sp-std = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 22 | sp-core = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 23 | sp-runtime = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 24 | sp-io = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 25 | 26 | xcm = { package = "staging-xcm", git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 27 | xcm-simulator = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 28 | xcm-executor = { package = "staging-xcm-executor", git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 29 | xcm-builder = { package = "staging-xcm-builder", git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 30 | pallet-xcm = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 31 | 32 | # Polkadot 33 | polkadot-core-primitives = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 34 | polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 35 | polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 36 | polkadot-parachain-primitives = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 37 | 38 | # Cumulus 39 | cumulus-pallet-xcm = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 40 | cumulus-primitives-utility = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 41 | pallet-collator-selection = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 42 | parachains-common = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 43 | 44 | # Runtimes 45 | rococo-runtime = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 46 | rococo-runtime-constants = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 47 | asset-hub-kusama-runtime = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } 48 | stout-runtime = { path = "../runtime/stout" } 49 | trappist-runtime = { path = "../runtime/trappist" } 50 | 51 | # Trappist XCM Primitives 52 | xcm-primitives = { path = "../primitives/xcm", default-features = false } 53 | -------------------------------------------------------------------------------- /xcm-simulator/src/parachains/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Parity Technologies (UK) Ltd. 2 | // This file is part of Polkadot. 3 | 4 | // Polkadot is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | 9 | // Polkadot is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | 14 | // You should have received a copy of the GNU General Public License 15 | // along with Polkadot. If not, see . 16 | 17 | use polkadot_core_primitives::BlockNumber as RelayBlockNumber; 18 | use polkadot_parachain::primitives::{ 19 | DmpMessageHandler, Id as ParaId, XcmpMessageFormat, XcmpMessageHandler, 20 | }; 21 | use sp_runtime::traits::Hash; 22 | use xcm::{latest::prelude::*, VersionedXcm}; 23 | 24 | pub(crate) mod asset_reserve; 25 | pub(crate) mod stout; 26 | pub(crate) mod template; 27 | pub(crate) mod trappist; 28 | 29 | #[frame_support::pallet] 30 | pub mod mock_msg_queue { 31 | use super::*; 32 | use frame_support::pallet_prelude::*; 33 | 34 | #[pallet::config] 35 | pub trait Config: frame_system::Config { 36 | type RuntimeEvent: From> + IsType<::RuntimeEvent>; 37 | type XcmExecutor: ExecuteXcm; 38 | } 39 | 40 | #[pallet::call] 41 | impl Pallet {} 42 | 43 | #[pallet::pallet] 44 | #[pallet::generate_store(pub(super) trait Store)] 45 | #[pallet::without_storage_info] 46 | pub struct Pallet(_); 47 | 48 | #[pallet::storage] 49 | #[pallet::getter(fn parachain_id)] 50 | pub(crate) type ParachainId = StorageValue<_, ParaId, ValueQuery>; 51 | 52 | #[pallet::storage] 53 | #[pallet::getter(fn received_dmp)] 54 | /// A queue of received DMP messages 55 | pub(crate) type ReceivedDmp = StorageValue<_, Vec>, ValueQuery>; 56 | 57 | impl Get for Pallet { 58 | fn get() -> ParaId { 59 | Self::parachain_id() 60 | } 61 | } 62 | 63 | pub type MessageId = [u8; 32]; 64 | 65 | #[pallet::event] 66 | #[pallet::generate_deposit(pub(super) fn deposit_event)] 67 | pub enum Event { 68 | // XCMP 69 | /// Some XCM was executed OK. 70 | Success(Option), 71 | /// Some XCM failed. 72 | Fail(Option, XcmError), 73 | /// Bad XCM version used. 74 | BadVersion(Option), 75 | /// Bad XCM format used. 76 | BadFormat(Option), 77 | 78 | // DMP 79 | /// Downward message is invalid XCM. 80 | InvalidFormat(MessageId), 81 | /// Downward message is unsupported version of XCM. 82 | UnsupportedVersion(MessageId), 83 | /// Downward message executed with the given outcome. 84 | ExecutedDownward(MessageId, Outcome), 85 | } 86 | 87 | impl Pallet { 88 | pub fn set_para_id(para_id: ParaId) { 89 | ParachainId::::put(para_id); 90 | } 91 | 92 | fn handle_xcmp_message( 93 | sender: ParaId, 94 | _sent_at: RelayBlockNumber, 95 | xcm: VersionedXcm, 96 | max_weight: Weight, 97 | ) -> Result { 98 | let hash = Encode::using_encoded(&xcm, T::Hashing::hash); 99 | let (result, event) = match Xcm::::try_from(xcm) { 100 | Ok(xcm) => { 101 | let location = (1, Parachain(sender.into())); 102 | match T::XcmExecutor::execute_xcm(location, xcm, max_weight.ref_time()) { 103 | Outcome::Error(e) => (Err(e.clone()), Event::Fail(Some(hash), e)), 104 | Outcome::Complete(w) => 105 | (Ok(Weight::from_ref_time(w)), Event::Success(Some(hash))), 106 | // As far as the caller is concerned, this was dispatched without error, so 107 | // we just report the weight used. 108 | Outcome::Incomplete(w, e) => 109 | (Ok(Weight::from_ref_time(w)), Event::Fail(Some(hash), e)), 110 | } 111 | }, 112 | Err(()) => (Err(XcmError::UnhandledXcmVersion), Event::BadVersion(Some(hash))), 113 | }; 114 | Self::deposit_event(event); 115 | result 116 | } 117 | } 118 | 119 | impl XcmpMessageHandler for Pallet { 120 | fn handle_xcmp_messages<'a, I: Iterator>( 121 | iter: I, 122 | max_weight: Weight, 123 | ) -> Weight { 124 | for (sender, sent_at, data) in iter { 125 | let mut data_ref = data; 126 | let _ = XcmpMessageFormat::decode(&mut data_ref) 127 | .expect("Simulator encodes with versioned xcm format; qed"); 128 | 129 | let mut remaining_fragments = &data_ref[..]; 130 | while !remaining_fragments.is_empty() { 131 | if let Ok(xcm) = 132 | VersionedXcm::::decode(&mut remaining_fragments) 133 | { 134 | let _ = Self::handle_xcmp_message(sender, sent_at, xcm, max_weight); 135 | } else { 136 | debug_assert!(false, "Invalid incoming XCMP message data"); 137 | } 138 | } 139 | } 140 | max_weight 141 | } 142 | } 143 | 144 | impl DmpMessageHandler for Pallet { 145 | fn handle_dmp_messages( 146 | iter: impl Iterator)>, 147 | limit: Weight, 148 | ) -> Weight { 149 | for (_i, (_sent_at, data)) in iter.enumerate() { 150 | let id = sp_io::hashing::blake2_256(&data[..]); 151 | let maybe_msg = VersionedXcm::::decode(&mut &data[..]) 152 | .map(Xcm::::try_from); 153 | match maybe_msg { 154 | Err(_) => { 155 | Self::deposit_event(Event::InvalidFormat(id)); 156 | }, 157 | Ok(Err(())) => { 158 | Self::deposit_event(Event::UnsupportedVersion(id)); 159 | }, 160 | Ok(Ok(x)) => { 161 | let outcome = 162 | T::XcmExecutor::execute_xcm(Parent, x.clone(), limit.ref_time()); 163 | >::append(x); 164 | Self::deposit_event(Event::ExecutedDownward(id, outcome)); 165 | }, 166 | } 167 | } 168 | limit 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /xcm-simulator/src/parachains/template.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Parity Technologies (UK) Ltd. 2 | // This file is part of Polkadot. 3 | 4 | // Polkadot is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | 9 | // Polkadot is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | 14 | // You should have received a copy of the GNU General Public License 15 | // along with Polkadot. If not, see . 16 | 17 | //! Parachain runtime mock. 18 | 19 | use frame_support::{ 20 | construct_runtime, parameter_types, 21 | traits::{Everything, Nothing}, 22 | }; 23 | use pallet_xcm::XcmPassthrough; 24 | use polkadot_parachain::primitives::Sibling; 25 | use sp_core::H256; 26 | use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32}; 27 | use sp_std::prelude::*; 28 | use asset_hub_kusama::common::BlockNumber; 29 | use xcm::latest::prelude::*; 30 | use xcm_builder::{ 31 | AccountId32Aliases, AllowUnpaidExecutionFrom, CurrencyAdapter as XcmCurrencyAdapter, 32 | EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, IsConcrete, LocationInverter, 33 | NativeAsset, ParentIsPreset, SiblingParachainConvertsVia, SignedAccountId32AsNative, 34 | SignedToAccountId32, SovereignSignedViaLocation, 35 | }; 36 | use xcm_executor::{Config, XcmExecutor}; 37 | 38 | pub type AccountId = AccountId32; 39 | pub type Balance = u128; 40 | 41 | parameter_types! { 42 | pub const BlockHashCount: BlockNumber = 250; 43 | } 44 | 45 | impl frame_system::Config for Runtime { 46 | type BaseCallFilter = Everything; 47 | type BlockWeights = (); 48 | type BlockLength = (); 49 | type RuntimeOrigin = RuntimeOrigin; 50 | type RuntimeCall = RuntimeCall; 51 | type Index = u64; 52 | type BlockNumber = u64; 53 | type Hash = H256; 54 | type Hashing = sp_runtime::traits::BlakeTwo256; 55 | type AccountId = AccountId; 56 | type Lookup = IdentityLookup; 57 | type Header = Header; 58 | type RuntimeEvent = RuntimeEvent; 59 | type BlockHashCount = BlockHashCount; 60 | type DbWeight = (); 61 | type Version = (); 62 | type PalletInfo = PalletInfo; 63 | type AccountData = pallet_balances::AccountData; 64 | type OnNewAccount = (); 65 | type OnKilledAccount = (); 66 | type SystemWeightInfo = (); 67 | type SS58Prefix = (); 68 | type OnSetCode = (); 69 | type MaxConsumers = frame_support::traits::ConstU32<16>; 70 | } 71 | 72 | parameter_types! { 73 | pub ExistentialDeposit: Balance = 1; 74 | pub const MaxLocks: u32 = 50; 75 | pub const MaxReserves: u32 = 50; 76 | } 77 | 78 | impl pallet_balances::Config for Runtime { 79 | type Balance = Balance; 80 | type DustRemoval = (); 81 | type RuntimeEvent = RuntimeEvent; 82 | type ExistentialDeposit = ExistentialDeposit; 83 | type AccountStore = System; 84 | type WeightInfo = (); 85 | type MaxLocks = MaxLocks; 86 | type MaxReserves = MaxReserves; 87 | type ReserveIdentifier = [u8; 8]; 88 | } 89 | 90 | parameter_types! { 91 | pub const KsmLocation: MultiLocation = MultiLocation::parent(); 92 | pub const RelayNetwork: NetworkId = NetworkId::Kusama; 93 | pub Ancestry: MultiLocation = Parachain(MsgQueue::parachain_id().into()).into(); 94 | } 95 | 96 | pub type LocationToAccountId = ( 97 | ParentIsPreset, 98 | SiblingParachainConvertsVia, 99 | AccountId32Aliases, 100 | ); 101 | 102 | pub type XcmOriginToCallOrigin = ( 103 | SovereignSignedViaLocation, 104 | SignedAccountId32AsNative, 105 | XcmPassthrough, 106 | ); 107 | 108 | parameter_types! { 109 | pub const UnitWeightCost: u64 = 1; 110 | pub KsmPerSecond: (AssetId, u128) = (Concrete(Parent.into()), 1); 111 | pub const MaxInstructions: u32 = 100; 112 | } 113 | 114 | pub type LocalAssetTransactor = 115 | XcmCurrencyAdapter, LocationToAccountId, AccountId, ()>; 116 | 117 | pub type XcmRouter = crate::ParachainXcmRouter; 118 | pub type Barrier = AllowUnpaidExecutionFrom; 119 | 120 | pub struct XcmConfig; 121 | impl Config for XcmConfig { 122 | type RuntimeCall = RuntimeCall; 123 | type XcmSender = XcmRouter; 124 | type AssetTransactor = LocalAssetTransactor; 125 | type OriginConverter = XcmOriginToCallOrigin; 126 | type IsReserve = NativeAsset; 127 | type IsTeleporter = (); 128 | type LocationInverter = LocationInverter; 129 | type Barrier = Barrier; 130 | type Weigher = FixedWeightBounds; 131 | type Trader = FixedRateOfFungible; 132 | type ResponseHandler = (); 133 | type AssetTrap = (); 134 | type AssetClaims = (); 135 | type SubscriptionService = (); 136 | } 137 | 138 | impl super::mock_msg_queue::Config for Runtime { 139 | type RuntimeEvent = RuntimeEvent; 140 | type XcmExecutor = XcmExecutor; 141 | } 142 | 143 | pub type LocalOriginToLocation = SignedToAccountId32; 144 | 145 | impl pallet_xcm::Config for Runtime { 146 | type RuntimeEvent = RuntimeEvent; 147 | type SendXcmOrigin = EnsureXcmOrigin; 148 | type XcmRouter = XcmRouter; 149 | type ExecuteXcmOrigin = EnsureXcmOrigin; 150 | type XcmExecuteFilter = Everything; 151 | type XcmExecutor = XcmExecutor; 152 | type XcmTeleportFilter = Nothing; 153 | type XcmReserveTransferFilter = Everything; 154 | type Weigher = FixedWeightBounds; 155 | type LocationInverter = LocationInverter; 156 | type RuntimeOrigin = RuntimeOrigin; 157 | type RuntimeCall = RuntimeCall; 158 | const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; 159 | type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; 160 | } 161 | 162 | type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; 163 | type Block = frame_system::mocking::MockBlock; 164 | 165 | construct_runtime!( 166 | pub enum Runtime where 167 | Block = Block, 168 | NodeBlock = Block, 169 | UncheckedExtrinsic = UncheckedExtrinsic, 170 | { 171 | System: frame_system::{Pallet, Call, Storage, Config, Event}, 172 | Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, 173 | MsgQueue: super::mock_msg_queue::{Pallet, Storage, Event}, 174 | PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin}, 175 | } 176 | ); 177 | -------------------------------------------------------------------------------- /xcm-simulator/src/tests/misc.rs: -------------------------------------------------------------------------------- 1 | use crate::tests::*; 2 | use frame_support::assert_ok; 3 | use xcm_simulator::TestExt; 4 | 5 | #[test] 6 | fn event_collection_works() { 7 | init_tracing(); 8 | 9 | MockNet::reset(); 10 | 11 | const AMOUNT: u128 = trappist::EXISTENTIAL_DEPOSIT * 10; 12 | const MAX_WEIGHT: u128 = 1_000_000_000; 13 | 14 | Trappist::execute_with(|| { 15 | assert_ok!(trappist::PolkadotXcm::execute( 16 | trappist::RuntimeOrigin::signed(ALICE), 17 | Box::new(VersionedXcm::from(Xcm(vec![WithdrawAsset(((0, Here), AMOUNT).into())]))), 18 | MAX_WEIGHT as u64 19 | )); 20 | output_events::(); 21 | assert_eq!(3, trappist::System::events().len()); 22 | }); 23 | 24 | Stout::execute_with(|| { 25 | assert_ok!(stout::PolkadotXcm::execute( 26 | stout::RuntimeOrigin::signed(ALICE), 27 | Box::new(VersionedXcm::from(Xcm(vec![WithdrawAsset(((0, Here), AMOUNT).into())]))), 28 | MAX_WEIGHT as u64 29 | )); 30 | output_events::(); 31 | assert_eq!(1, trappist::System::events().len()); 32 | }); 33 | } 34 | -------------------------------------------------------------------------------- /xcm-simulator/src/tests/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::{relay_chain::mock_paras_sudo_wrapper, *}; 2 | use codec::Encode; 3 | use frame_support::{ 4 | assert_ok, log, 5 | pallet_prelude::{DispatchResult, DispatchResultWithPostInfo}, 6 | traits::PalletInfoAccess, 7 | }; 8 | use std::sync::Once; 9 | use xcm::prelude::*; 10 | 11 | mod misc; 12 | mod xcm_asset_trap; 13 | mod xcm_use_cases; 14 | 15 | static INIT: Once = Once::new(); 16 | fn init_tracing() { 17 | INIT.call_once(|| { 18 | // Add test tracing (from sp_tracing::init_for_tests()) but filtering for xcm logs only 19 | let _ = tracing_subscriber::fmt() 20 | .with_max_level(tracing::Level::TRACE) 21 | .with_env_filter("xcm=trace,system::events=trace") // Comment out this line to see all traces 22 | .with_test_writer() 23 | .init(); 24 | }); 25 | } 26 | 27 | fn assert_balance(actual: u128, expected: u128, fees: u128) { 28 | assert!( 29 | actual >= (expected - fees) && actual <= expected, 30 | "expected: {expected}, actual: {actual} fees: {fees}" 31 | ) 32 | } 33 | 34 | fn create_asset_on_asset_reserve( 35 | id: asset_reserve::AssetId, 36 | admin: asset_reserve::AccountId, 37 | min_balance: asset_reserve::Balance, 38 | ) -> DispatchResult { 39 | asset_reserve::Assets::create( 40 | asset_reserve::RuntimeOrigin::signed(ALICE), 41 | id.into(), 42 | admin.into(), 43 | min_balance, 44 | ) 45 | } 46 | 47 | fn create_derivative_asset_on_trappist( 48 | id: trappist::AssetId, 49 | admin: trappist::AccountId, 50 | min_balance: trappist::Balance, 51 | ) -> DispatchResult { 52 | trappist::Assets::create(trappist::RuntimeOrigin::signed(ALICE), id.into(), admin.into(), min_balance) 53 | } 54 | 55 | fn mint_asset_on_asset_reserve( 56 | asset_id: asset_reserve::AssetId, 57 | origin: asset_reserve::AccountId, 58 | mint_amount: asset_reserve::Balance, 59 | ) -> DispatchResult { 60 | asset_reserve::Assets::mint( 61 | asset_reserve::RuntimeOrigin::signed(origin), 62 | asset_id.into(), 63 | ALICE.into(), 64 | mint_amount, 65 | ) 66 | } 67 | 68 | // Helper for outputting events 69 | fn output_events() { 70 | const TARGET: &str = "system::events"; 71 | let events = frame_system::Pallet::::events(); 72 | log::trace!(target: TARGET, "{} events", events.len()); 73 | for event in events { 74 | log::trace!(target: TARGET, "{:?}", event) 75 | } 76 | } 77 | 78 | fn paras_sudo_wrapper_sudo_queue_downward_xcm(call: RuntimeCall) { 79 | let sudo_queue_downward_xcm = 80 | relay_chain::RuntimeCall::ParasSudoWrapper(mock_paras_sudo_wrapper::Call::< 81 | relay_chain::Runtime, 82 | >::sudo_queue_downward_xcm { 83 | id: ParaId::new(ASSET_RESERVE_PARA_ID), 84 | xcm: Box::new(VersionedXcm::V2(Xcm(vec![Transact { 85 | origin_type: OriginKind::Superuser, 86 | require_weight_at_most: 10000000000u64, 87 | call: call.encode().into(), 88 | }]))), 89 | }); 90 | 91 | assert_ok!(relay_chain::Sudo::sudo( 92 | relay_chain::RuntimeOrigin::signed(ALICE), 93 | Box::new(sudo_queue_downward_xcm), 94 | )); 95 | } 96 | 97 | fn register_reserve_asset_on_trappist( 98 | origin: trappist::AccountId, 99 | trappist_asset_id: trappist::AssetId, 100 | asset_reserve_asset_id: asset_reserve::AssetId, 101 | ) -> DispatchResultWithPostInfo { 102 | trappist::Sudo::sudo( 103 | trappist::RuntimeOrigin::signed(origin), 104 | Box::new(trappist::RuntimeCall::AssetRegistry(pallet_asset_registry::Call::< 105 | trappist::Runtime, 106 | >::register_reserve_asset { 107 | asset_id: trappist_asset_id, 108 | asset_multi_location: ( 109 | Parent, 110 | X3( 111 | Parachain(ASSET_RESERVE_PARA_ID), 112 | PalletInstance(asset_reserve::Assets::index() as u8), 113 | GeneralIndex(asset_reserve_asset_id as u128), 114 | ), 115 | ) 116 | .into(), 117 | })), 118 | ) 119 | } 120 | -------------------------------------------------------------------------------- /zombienet/full_network.toml: -------------------------------------------------------------------------------- 1 | [settings] 2 | timeout = 1000 3 | 4 | [relaychain] 5 | chain = "rococo-local" 6 | default_command = "./bin/polkadot" 7 | 8 | [[relaychain.nodes]] 9 | name = "alice" 10 | validator = true 11 | ws_port = 9900 12 | extra_args = ["-lparachain=debug"] 13 | 14 | [[relaychain.nodes]] 15 | name = "bob" 16 | validator = true 17 | extra_args = ["-lparachain=debug"] 18 | 19 | [[relaychain.nodes]] 20 | name = "charlie" 21 | validator = true 22 | extra_args = ["-lparachain=debug"] 23 | 24 | [[relaychain.nodes]] 25 | name = "dave" 26 | validator = true 27 | extra_args = ["-lparachain=debug"] 28 | 29 | [[parachains]] 30 | id = 1000 31 | add_to_genesis = true 32 | cumulus_based = true 33 | chain = "asset-hub-rococo-local" 34 | 35 | [[parachains.collators]] 36 | name = "asset-hub-collator01" 37 | command = "./bin/polkadot-parachain" 38 | ws_port = 9910 39 | args = ["--log=xcm=trace,pallet-assets=trace"] 40 | 41 | [[parachains.collators]] 42 | name = "asset-hub-collator02" 43 | command = "./bin/polkadot-parachain" 44 | ws_port = 9911 45 | args = ["--log=xcm=trace,pallet-assets=trace"] 46 | 47 | [[parachains]] 48 | id = 1836 49 | add_to_genesis = true 50 | cumulus_based = true 51 | chain = "trappist-local" 52 | 53 | [[parachains.collators]] 54 | name = "trappist-collator01" 55 | command = "./target/release/trappist-node" 56 | ws_port = 9920 57 | args = ["--log=xcm=trace,pallet-assets=trace"] 58 | 59 | [[parachains.collators]] 60 | name = "trappist-collator02" 61 | command = "./target/release/trappist-node" 62 | ws_port = 9921 63 | args = ["--log=xcm=trace,pallet-assets=trace"] 64 | 65 | [[parachains]] 66 | id = 3000 67 | add_to_genesis = true 68 | cumulus_based = true 69 | chain = "stout-local" 70 | 71 | [[parachains.collators]] 72 | name = "stout-collator01" 73 | command = "./target/release/trappist-node" 74 | ws_port = 9930 75 | args = ["--log=xcm=trace,pallet-assets=trace"] 76 | 77 | [[parachains.collators]] 78 | name = "stout-collator02" 79 | command = "./target/release/trappist-node" 80 | ws_port = 9931 81 | args = ["--log=xcm=trace,pallet-assets=trace"] 82 | 83 | [types.Header] 84 | number = "u64" 85 | parent_hash = "Hash" 86 | post_state = "Hash" 87 | 88 | # Currently there is a known issue with opening hrmp channels 89 | # on genesis that stops block production after epoch 1. 90 | # Use hrmp_helper script after network spawn to open channels instead. 91 | 92 | # [[hrmp_channels]] 93 | # sender = 1000 94 | # recipient = 1836 95 | # max_capacity = 8 96 | # max_message_size = 512 97 | 98 | # [[hrmp_channels]] 99 | # sender = 1836 100 | # recipient = 1000 101 | # max_capacity = 8 102 | # max_message_size = 512 103 | 104 | # [[hrmp_channels]] 105 | # sender = 1000 106 | # recipient = 3000 107 | # max_capacity = 8 108 | # max_message_size = 512 109 | 110 | # [[hrmp_channels]] 111 | # sender = 3000 112 | # recipient = 1000 113 | # max_capacity = 8 114 | # max_message_size = 512 115 | 116 | # [[hrmp_channels]] 117 | # sender = 1836 118 | # recipient = 3000 119 | # max_capacity = 8 120 | # max_message_size = 512 121 | 122 | # [[hrmp_channels]] 123 | # sender = 3000 124 | # recipient = 1836 125 | # max_capacity = 8 126 | # max_message_size = 512 127 | -------------------------------------------------------------------------------- /zombienet/stout_rococo.toml: -------------------------------------------------------------------------------- 1 | [settings] 2 | timeout = 1000 3 | 4 | [relaychain] 5 | chain = "rococo-local" 6 | default_command = "./bin/polkadot" 7 | 8 | [[relaychain.nodes]] 9 | name = "alice" 10 | validator = true 11 | ws_port = 9900 12 | extra_args = [ "-lparachain=debug" ] 13 | 14 | [[relaychain.nodes]] 15 | name = "bob" 16 | validator = true 17 | extra_args = [ "-lparachain=debug" ] 18 | 19 | [[relaychain.nodes]] 20 | name = "charlie" 21 | validator = true 22 | extra_args = [ "-lparachain=debug" ] 23 | 24 | [[relaychain.nodes]] 25 | name = "dave" 26 | validator = true 27 | extra_args = [ "-lparachain=debug" ] 28 | 29 | [[parachains]] 30 | id = 1000 31 | add_to_genesis = true 32 | cumulus_based = true 33 | chain = "asset-hub-rococo-local" 34 | 35 | [[parachains.collators]] 36 | name = "asset-hub-rococo-collator01" 37 | command = "./bin/polkadot-parachain" 38 | ws_port = 9910 39 | args = ["--log=xcm=trace,pallet-assets=trace"] 40 | 41 | [[parachains.collators]] 42 | name = "asset-hub-rococo-collator02" 43 | command = "./bin/polkadot-parachain" 44 | ws_port = 9911 45 | args = ["--log=xcm=trace,pallet-assets=trace"] 46 | 47 | [[parachains]] 48 | id = 3000 49 | add_to_genesis = true 50 | cumulus_based = true 51 | chain = "stout-local" 52 | 53 | [[parachains.collators]] 54 | name = "stout-collator01" 55 | command = "./target/release/trappist-node" 56 | ws_port = 9930 57 | args = ["--log=xcm=trace,pallet-assets=trace"] 58 | 59 | [[parachains.collators]] 60 | name = "stout-collator02" 61 | command = "./target/release/trappist-node" 62 | ws_port = 9931 63 | args = ["--log=xcm=trace,pallet-assets=trace"] 64 | 65 | [types.Header] 66 | number = "u64" 67 | parent_hash = "Hash" 68 | post_state = "Hash" 69 | 70 | # Currently there is a known issue with opening hrmp channels 71 | # on genesis that stops block production after epoch 1. 72 | # Use hrmp_helper script after network spawn to open channels instead. 73 | 74 | # [[hrmp_channels]] 75 | # sender = 1000 76 | # recipient = 3000 77 | # max_capacity = 8 78 | # max_message_size = 512 79 | 80 | # [[hrmp_channels]] 81 | # sender = 3000 82 | # recipient = 1000 83 | # max_capacity = 8 84 | # max_message_size = 512 -------------------------------------------------------------------------------- /zombienet/trappist_rococo.toml: -------------------------------------------------------------------------------- 1 | [settings] 2 | timeout = 1000 3 | 4 | [relaychain] 5 | chain = "rococo-local" 6 | default_command = "./bin/polkadot" 7 | 8 | [[relaychain.nodes]] 9 | name = "alice" 10 | validator = true 11 | ws_port = 9900 12 | extra_args = [ "-lparachain=debug" ] 13 | 14 | [[relaychain.nodes]] 15 | name = "bob" 16 | validator = true 17 | extra_args = [ "-lparachain=debug" ] 18 | 19 | [[relaychain.nodes]] 20 | name = "charlie" 21 | validator = true 22 | extra_args = [ "-lparachain=debug" ] 23 | 24 | [[relaychain.nodes]] 25 | name = "dave" 26 | validator = true 27 | extra_args = [ "-lparachain=debug" ] 28 | 29 | [[parachains]] 30 | id = 1000 31 | add_to_genesis = true 32 | cumulus_based = true 33 | chain = "asset-hub-rococo-local" 34 | 35 | [[parachains.collators]] 36 | name = "asset-hub-rococo-collator01" 37 | command = "./bin/polkadot-parachain" 38 | ws_port = 9910 39 | args = ["--log=xcm=trace,pallet-assets=trace"] 40 | 41 | [[parachains.collators]] 42 | name = "asset-hub-rococo-collator02" 43 | command = "./bin/polkadot-parachain" 44 | ws_port = 9911 45 | args = ["--log=xcm=trace,pallet-assets=trace"] 46 | 47 | [[parachains]] 48 | id = 1836 49 | add_to_genesis = true 50 | cumulus_based = true 51 | chain = "trappist-local" 52 | 53 | [[parachains.collators]] 54 | name = "trappist-collator01" 55 | command = "./target/release/trappist-node" 56 | ws_port = 9920 57 | args = ["--log=xcm=trace,pallet-assets=trace"] 58 | 59 | [[parachains.collators]] 60 | name = "trappist-collator02" 61 | command = "./target/release/trappist-node" 62 | ws_port = 9921 63 | args = ["--log=xcm=trace,pallet-assets=trace"] 64 | 65 | [types.Header] 66 | number = "u64" 67 | parent_hash = "Hash" 68 | post_state = "Hash" 69 | 70 | # Currently there is a known issue with opening hrmp channels 71 | # on genesis that stops block production after epoch 1. 72 | # Use hrmp_helper script after network spawn to open channels instead. 73 | 74 | # [[hrmp_channels]] 75 | # sender = 1000 76 | # recipient = 1836 77 | # max_capacity = 8 78 | # max_message_size = 512 79 | 80 | # [[hrmp_channels]] 81 | # sender = 1836 82 | # recipient = 1000 83 | # max_capacity = 8 84 | # max_message_size = 512 -------------------------------------------------------------------------------- /zombienet/trappist_stout.toml: -------------------------------------------------------------------------------- 1 | [settings] 2 | timeout = 1000 3 | 4 | [relaychain] 5 | chain = "rococo-local" 6 | default_command = "./bin/polkadot" 7 | # chain_spec_path = "./bin/rococo-local-plain-custom.json" 8 | 9 | [[relaychain.nodes]] 10 | name = "alice" 11 | validator = true 12 | ws_port = 9900 13 | extra_args = [ "-lparachain=debug" ] 14 | 15 | [[relaychain.nodes]] 16 | name = "bob" 17 | validator = true 18 | extra_args = [ "-lparachain=debug" ] 19 | 20 | [[relaychain.nodes]] 21 | name = "charlie" 22 | validator = true 23 | extra_args = [ "-lparachain=debug" ] 24 | 25 | [[relaychain.nodes]] 26 | name = "dave" 27 | validator = true 28 | extra_args = [ "-lparachain=debug" ] 29 | 30 | [[parachains]] 31 | id = 1836 32 | add_to_genesis = true 33 | cumulus_based = true 34 | chain = "trappist-local" 35 | 36 | [[parachains.collators]] 37 | name = "trappist-collator01" 38 | command = "./target/release/trappist-node" 39 | ws_port = 9920 40 | args = ["--log=xcm=trace,pallet-assets=trace"] 41 | 42 | [[parachains.collators]] 43 | name = "trappist-collator02" 44 | command = "./target/release/trappist-node" 45 | ws_port = 9921 46 | args = ["--log=xcm=trace,pallet-assets=trace"] 47 | 48 | [[parachains]] 49 | id = 3000 50 | add_to_genesis = true 51 | cumulus_based = true 52 | chain = "stout-local" 53 | 54 | [[parachains.collators]] 55 | name = "stout-collator01" 56 | command = "./target/release/trappist-node" 57 | ws_port = 9930 58 | args = ["--log=xcm=trace,pallet-assets=trace"] 59 | 60 | [[parachains.collators]] 61 | name = "stout-collator02" 62 | command = "./target/release/trappist-node" 63 | ws_port = 9931 64 | args = ["--log=xcm=trace,pallet-assets=trace"] 65 | 66 | [types.Header] 67 | number = "u64" 68 | parent_hash = "Hash" 69 | post_state = "Hash" 70 | 71 | # Currently there is a known issue with opening hrmp channels 72 | # on genesis that stops block production after epoch 1. 73 | # Use hrmp_helper script after network spawn to open channels instead. 74 | 75 | # [[hrmp_channels]] 76 | # sender = 1836 77 | # recipient = 3000 78 | # max_capacity = 8 79 | # max_message_size = 512 80 | 81 | # [[hrmp_channels]] 82 | # sender = 3000 83 | # recipient = 1836 84 | # max_capacity = 8 85 | # max_message_size = 512 86 | --------------------------------------------------------------------------------