Skip to content

Commit

Permalink
Contracts expose pallet-xcm (#1248)
Browse files Browse the repository at this point in the history
This PR introduces:
- XCM  host functions `xcm_send`, `xcm_execute`
- An Xcm trait into the config. that proxy these functions to to
`pallet_xcm`, or disable their usage by using `()`.
- A mock_network and xcm_test files to test the newly added xcm-related
functions.

---------

Co-authored-by: Keith Yeung <[email protected]>
Co-authored-by: Sasha Gryaznov <[email protected]>
Co-authored-by: command-bot <>
Co-authored-by: Francisco Aguirre <[email protected]>
Co-authored-by: Alexander Theißen <[email protected]>
  • Loading branch information
5 people authored Nov 14, 2023
1 parent fc12f43 commit f517900
Show file tree
Hide file tree
Showing 23 changed files with 1,797 additions and 15 deletions.
43 changes: 43 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ members = [
"substrate/frame/contracts/fixtures",
"substrate/frame/contracts/primitives",
"substrate/frame/contracts/proc-macro",
"substrate/frame/contracts/mock-network",
"substrate/frame/conviction-voting",
"substrate/frame/core-fellowship",
"substrate/frame/democracy",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,5 @@ impl Config for Runtime {
type RuntimeHoldReason = RuntimeHoldReason;
type Debug = ();
type Environment = ();
type Xcm = pallet_xcm::Pallet<Self>;
}
2 changes: 1 addition & 1 deletion polkadot/xcm/xcm-builder/src/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
use frame_support::pallet_prelude::DispatchError;
use sp_std::boxed::Box;
use xcm::prelude::*;
use xcm_executor::traits::QueryHandler;
pub use xcm_executor::traits::QueryHandler;

/// Umbrella trait for all Controller traits.
pub trait Controller<Origin, RuntimeCall, Timeout>:
Expand Down
2 changes: 1 addition & 1 deletion polkadot/xcm/xcm-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,5 +119,5 @@ pub use pay::{FixedLocation, LocatableAssetId, PayAccountId32OnChainOverXcm, Pay
mod controller;
pub use controller::{
Controller, ExecuteController, ExecuteControllerWeightInfo, QueryController,
QueryControllerWeightInfo, SendController, SendControllerWeightInfo,
QueryControllerWeightInfo, QueryHandler, SendController, SendControllerWeightInfo,
};
1 change: 1 addition & 0 deletions substrate/bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1353,6 +1353,7 @@ impl pallet_contracts::Config for Runtime {
type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
type Debug = ();
type Environment = ();
type Xcm = ();
}

impl pallet_sudo::Config for Runtime {
Expand Down
16 changes: 16 additions & 0 deletions substrate/frame/contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ sp-io = { path = "../../primitives/io", default-features = false}
sp-runtime = { path = "../../primitives/runtime", default-features = false}
sp-std = { path = "../../primitives/std", default-features = false}

xcm = { package = "staging-xcm", path = "../../../polkadot/xcm", default-features = false}
xcm-builder = { package = "staging-xcm-builder", path = "../../../polkadot/xcm/xcm-builder", default-features = false}

[dev-dependencies]
array-bytes = "6.1"
assert_matches = "1"
Expand All @@ -56,13 +59,19 @@ pretty_assertions = "1"
wat = "1"
pallet-contracts-fixtures = { path = "./fixtures" }

# Polkadot Dependencies
xcm-builder = {package = "staging-xcm-builder", path = "../../../polkadot/xcm/xcm-builder"}

# Substrate Dependencies
pallet-balances = { path = "../balances" }
pallet-timestamp = { path = "../timestamp" }
pallet-message-queue = { path = "../message-queue" }
pallet-insecure-randomness-collective-flip = { path = "../insecure-randomness-collective-flip" }
pallet-utility = { path = "../utility" }
pallet-assets = { path = "../assets" }
pallet-proxy = { path = "../proxy" }
sp-keystore = { path = "../../primitives/keystore" }
sp-tracing = { path = "../../primitives/tracing" }

[features]
default = [ "std" ]
Expand Down Expand Up @@ -92,25 +101,32 @@ std = [
"sp-std/std",
"wasm-instrument/std",
"wasmi/std",
"xcm-builder/std",
"xcm/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-assets/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-message-queue/runtime-benchmarks",
"pallet-proxy/runtime-benchmarks",
"pallet-timestamp/runtime-benchmarks",
"pallet-utility/runtime-benchmarks",
"rand",
"rand_pcg",
"sp-runtime/runtime-benchmarks",
"wasm-instrument",
"xcm-builder/runtime-benchmarks",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"pallet-assets/try-runtime",
"pallet-balances/try-runtime",
"pallet-insecure-randomness-collective-flip/try-runtime",
"pallet-message-queue/try-runtime",
"pallet-proxy/try-runtime",
"pallet-timestamp/try-runtime",
"pallet-utility/try-runtime",
Expand Down
52 changes: 52 additions & 0 deletions substrate/frame/contracts/fixtures/data/xcm_execute.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
;; This passes its input to `seal_xcm_execute` and returns the return value to its caller.
(module
(import "seal0" "xcm_execute" (func $xcm_execute (param i32 i32 i32) (result i32)))
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
(import "env" "memory" (memory 1 1))

;; 0x1000 = 4k in little endian
;; Size of input buffer
(data (i32.const 0) "\00\10")

(func $assert (param i32)
(block $ok
(br_if $ok
(get_local 0)
)
(unreachable)
)
)

(func (export "call")
;; Receive the encoded call
(call $seal_input
(i32.const 4) ;; Pointer to the input buffer
(i32.const 0) ;; Pointer to the buffer length (before call) and to the copied data length (after call)
)
;; Input data layout.
;; [0..4) - size of the call
;; [4..) - message

;; Call xcm_execute with provided input.
(call $assert
(i32.eq
(call $xcm_execute
(i32.const 4) ;; Pointer where the message is stored
(i32.load (i32.const 0)) ;; Size of the message
(i32.const 100) ;; Pointer to the where the outcome is stored
)
(i32.const 0)
)
)

(call $seal_return
(i32.const 0) ;; flags
(i32.const 100) ;; Pointer to returned value
(i32.const 10) ;; length of returned value
)
)

(func (export "deploy"))
)

59 changes: 59 additions & 0 deletions substrate/frame/contracts/fixtures/data/xcm_send.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
;; This passes its input to `seal_xcm_send` and returns the return value to its caller.
(module
(import "seal0" "xcm_send" (func $xcm_send (param i32 i32 i32 i32) (result i32)))
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
(import "env" "memory" (memory 1 1))

;; 0x1000 = 4k in little endian
;; size of input buffer
(data (i32.const 0) "\00\10")

(func $assert (param i32)
(block $ok
(br_if $ok
(get_local 0)
)
(unreachable)
)
)

(func (export "call")

;; Receive the encoded call
(call $seal_input
(i32.const 4) ;; Pointer to the input buffer
(i32.const 0) ;; Size of the length buffer
)

;; Input data layout.
;; [0..4) - size of the call
;; [4..7) - dest
;; [7..) - message

;; Call xcm_send with provided input.
(call $assert
(i32.eq
(call $xcm_send
(i32.const 4) ;; Pointer where the dest is stored
(i32.const 7) ;; Pointer where the message is stored
(i32.sub
(i32.load (i32.const 0)) ;; length of the input buffer
(i32.const 3) ;; Size of the XCM dest
)
(i32.const 100) ;; Pointer to the where the message_id is stored
)
(i32.const 0)
)
)

;; Return the the message_id
(call $seal_return
(i32.const 0) ;; flags
(i32.const 100) ;; Pointer to returned value
(i32.const 32) ;; length of returned value
)
)

(func (export "deploy"))
)
2 changes: 2 additions & 0 deletions substrate/frame/contracts/fixtures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ fn fixtures_root_dir() -> PathBuf {
// When `CARGO_MANIFEST_DIR` is not set, Rust resolves relative paths from the root folder
(Err(_), _) => "substrate/frame/contracts/fixtures/data".into(),
(Ok(path), Ok(s)) if s == "pallet-contracts" => PathBuf::from(path).join("fixtures/data"),
(Ok(path), Ok(s)) if s == "pallet-contracts-mock-network" =>
PathBuf::from(path).parent().unwrap().join("fixtures/data"),
(Ok(_), pkg_name) => panic!("Failed to resolve fixture dir for tests from {pkg_name:?}."),
}
}
Expand Down
91 changes: 91 additions & 0 deletions substrate/frame/contracts/mock-network/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
[package]
name = "pallet-contracts-mock-network"
version = "1.0.0"
authors.workspace = true
edition.workspace = true
license.workspace = true
homepage = "https://substrate.io"
repository.workspace = true
description = "A mock network for testing pallet-contracts"

[dependencies]
codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = [ "derive", "max-encoded-len"] }

frame-support = { path = "../../support", default-features = false}
frame-system = { path = "../../system", default-features = false}
pallet-assets = { path = "../../assets" }
pallet-balances = { path = "../../balances" }
pallet-contracts = { path = ".." }
pallet-contracts-primitives = { path = "../primitives", default-features = false}
pallet-contracts-proc-macro = { path = "../proc-macro" }
pallet-insecure-randomness-collective-flip = { path = "../../insecure-randomness-collective-flip" }
pallet-message-queue = { path = "../../message-queue" }
pallet-proxy = { path = "../../proxy" }
pallet-timestamp = { path = "../../timestamp" }
pallet-utility = { path = "../../utility" }
pallet-xcm = { path = "../../../../polkadot/xcm/pallet-xcm", default-features = false}
polkadot-parachain-primitives = { path = "../../../../polkadot/parachain" }
polkadot-primitives = { path = "../../../../polkadot/primitives" }
polkadot-runtime-parachains = {path = "../../../../polkadot/runtime/parachains"}
scale-info = { version = "2.10.0", default-features = false, features = ["derive"] }
sp-api = { path = "../../../primitives/api", default-features = false}
sp-core = { path = "../../../primitives/core", default-features = false}
sp-io = { path = "../../../primitives/io", default-features = false}
sp-keystore = { path = "../../../primitives/keystore" }
sp-runtime = { path = "../../../primitives/runtime", default-features = false}
sp-std = { path = "../../../primitives/std", default-features = false}
sp-tracing = { path = "../../../primitives/tracing" }
xcm = { package = "staging-xcm", path = "../../../../polkadot/xcm", default-features = false}
xcm-builder = {package = "staging-xcm-builder", path = "../../../../polkadot/xcm/xcm-builder"}
xcm-executor = { package = "staging-xcm-executor", path = "../../../../polkadot/xcm/xcm-executor", default-features = false}
xcm-simulator = {path = "../../../../polkadot/xcm/xcm-simulator"}

[dev-dependencies]
assert_matches = "1"
pretty_assertions = "1"
pallet-contracts-fixtures = { path = "../fixtures" }

[features]
default = [ "std" ]
std = [
"codec/std",
"frame-support/std",
"frame-system/std",
"pallet-balances/std",
"pallet-contracts-primitives/std",
"pallet-contracts-proc-macro/full",
"pallet-contracts/std",
"pallet-insecure-randomness-collective-flip/std",
"pallet-proxy/std",
"pallet-timestamp/std",
"pallet-utility/std",
"pallet-xcm/std",
"scale-info/std",
"sp-api/std",
"sp-core/std",
"sp-io/std",
"sp-keystore/std",
"sp-runtime/std",
"sp-std/std",
"xcm-executor/std",
"xcm/std",
]

runtime-benchmarks = [
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-assets/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-contracts/runtime-benchmarks",
"pallet-message-queue/runtime-benchmarks",
"pallet-proxy/runtime-benchmarks",
"pallet-timestamp/runtime-benchmarks",
"pallet-utility/runtime-benchmarks",
"pallet-xcm/runtime-benchmarks",
"polkadot-parachain-primitives/runtime-benchmarks",
"polkadot-primitives/runtime-benchmarks",
"polkadot-runtime-parachains/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"xcm-builder/runtime-benchmarks",
"xcm-executor/runtime-benchmarks",
]
Loading

0 comments on commit f517900

Please sign in to comment.