diff --git a/operator/Cargo.lock b/operator/Cargo.lock index ece4aa3c..11d0ea0b 100644 --- a/operator/Cargo.lock +++ b/operator/Cargo.lock @@ -916,7 +916,7 @@ dependencies = [ [[package]] name = "binary-merkle-tree" version = "16.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "hash-db", "log", @@ -1158,7 +1158,7 @@ dependencies = [ [[package]] name = "bp-header-chain" version = "0.19.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bp-runtime", "finality-grandpa", @@ -1175,7 +1175,7 @@ dependencies = [ [[package]] name = "bp-messages" version = "0.19.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bp-header-chain", "bp-runtime", @@ -1191,7 +1191,7 @@ dependencies = [ [[package]] name = "bp-parachains" version = "0.19.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bp-header-chain", "bp-polkadot-core", @@ -1208,7 +1208,7 @@ dependencies = [ [[package]] name = "bp-polkadot-core" version = "0.19.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bp-messages", "bp-runtime", @@ -1225,7 +1225,7 @@ dependencies = [ [[package]] name = "bp-relayers" version = "0.19.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bp-header-chain", "bp-messages", @@ -1243,7 +1243,7 @@ dependencies = [ [[package]] name = "bp-runtime" version = "0.19.1" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-support", "frame-system", @@ -1263,6 +1263,23 @@ dependencies = [ "trie-db", ] +[[package]] +name = "bridge-hub-common" +version = "0.12.0" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" +dependencies = [ + "cumulus-primitives-core", + "frame-support", + "pallet-message-queue", + "parity-scale-codec", + "scale-info", + "snowbridge-core 0.12.1", + "sp-core", + "sp-runtime", + "sp-std", + "staging-xcm", +] + [[package]] name = "bridge-hub-common" version = "0.13.1" @@ -1272,7 +1289,7 @@ dependencies = [ "pallet-message-queue", "parity-scale-codec", "scale-info", - "snowbridge-core", + "snowbridge-core 0.2.0", "sp-core", "sp-runtime", "sp-std", @@ -2013,7 +2030,7 @@ dependencies = [ [[package]] name = "cumulus-client-parachain-inherent" version = "0.15.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2035,7 +2052,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-core" version = "0.17.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", "polkadot-core-primitives", @@ -2051,7 +2068,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-parachain-inherent" version = "0.17.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2065,7 +2082,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-proof-size-hostfunction" version = "0.11.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "sp-externalities", "sp-runtime-interface", @@ -2075,7 +2092,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-interface" version = "0.21.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2094,7 +2111,7 @@ dependencies = [ [[package]] name = "cumulus-test-relay-sproof-builder" version = "0.17.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "cumulus-primitives-core", "parity-scale-codec", @@ -2376,7 +2393,7 @@ dependencies = [ name = "datahaven-runtime" version = "0.1.0" dependencies = [ - "bridge-hub-common", + "bridge-hub-common 0.13.1", "datahaven-runtime-common", "dhp-bridge", "fp-account", @@ -2423,7 +2440,8 @@ dependencies = [ "polkadot-runtime-common", "scale-info", "serde_json", - "snowbridge-beacon-primitives", + "snowbridge-beacon-primitives 0.2.0", + "snowbridge-core 0.2.0", "snowbridge-inbound-queue-primitives", "snowbridge-merkle-tree", "snowbridge-outbound-queue-primitives", @@ -2431,6 +2449,9 @@ dependencies = [ "snowbridge-pallet-ethereum-client", "snowbridge-pallet-inbound-queue-v2", "snowbridge-pallet-outbound-queue-v2", + "snowbridge-pallet-system", + "snowbridge-pallet-system-v2", + "snowbridge-system-v2-runtime-api", "snowbridge-verification-primitives", "sp-api", "sp-block-builder", @@ -2607,7 +2628,7 @@ dependencies = [ "frame-system", "pallet-validator-set", "parity-scale-codec", - "snowbridge-core", + "snowbridge-core 0.2.0", "snowbridge-inbound-queue-primitives", "sp-std", ] @@ -3555,7 +3576,7 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fork-tree" version = "13.0.1" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", ] @@ -3683,7 +3704,7 @@ checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" [[package]] name = "frame-benchmarking" version = "39.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-support", "frame-support-procedural", @@ -3707,7 +3728,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "46.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "Inflector", "array-bytes", @@ -3769,7 +3790,7 @@ dependencies = [ [[package]] name = "frame-election-provider-solution-type" version = "14.0.1" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", @@ -3780,7 +3801,7 @@ dependencies = [ [[package]] name = "frame-election-provider-support" version = "39.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-election-provider-solution-type", "frame-support", @@ -3796,7 +3817,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "39.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "aquamarine", "frame-support", @@ -3849,7 +3870,7 @@ dependencies = [ [[package]] name = "frame-metadata-hash-extension" version = "0.7.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "array-bytes", "const-hex", @@ -3865,7 +3886,7 @@ dependencies = [ [[package]] name = "frame-support" version = "39.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "aquamarine", "array-bytes", @@ -3908,7 +3929,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "31.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "Inflector", "cfg-expr", @@ -3928,7 +3949,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "13.0.1" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate 3.3.0", @@ -3940,7 +3961,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "12.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "proc-macro2", "quote", @@ -3950,7 +3971,7 @@ dependencies = [ [[package]] name = "frame-system" version = "39.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "cfg-if", "docify", @@ -3970,7 +3991,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "39.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-benchmarking", "frame-support", @@ -3984,7 +4005,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "35.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "docify", "parity-scale-codec", @@ -3994,7 +4015,7 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.45.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-support", "parity-scale-codec", @@ -6578,7 +6599,7 @@ dependencies = [ [[package]] name = "mmr-rpc" version = "39.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "jsonrpsee 0.24.9", "parity-scale-codec", @@ -7223,7 +7244,7 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "pallet-asset-conversion" version = "21.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-benchmarking", "frame-support", @@ -7241,7 +7262,7 @@ dependencies = [ [[package]] name = "pallet-asset-rate" version = "18.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-benchmarking", "frame-support", @@ -7255,7 +7276,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" version = "39.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-support", "frame-system", @@ -7270,7 +7291,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "39.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-support", "frame-system", @@ -7283,7 +7304,7 @@ dependencies = [ [[package]] name = "pallet-babe" version = "39.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-benchmarking", "frame-support", @@ -7306,7 +7327,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "40.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "docify", "frame-benchmarking", @@ -7321,7 +7342,7 @@ dependencies = [ [[package]] name = "pallet-beefy" version = "40.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-support", "frame-system", @@ -7340,7 +7361,7 @@ dependencies = [ [[package]] name = "pallet-beefy-mmr" version = "40.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "array-bytes", "binary-merkle-tree", @@ -7365,7 +7386,7 @@ dependencies = [ [[package]] name = "pallet-broker" version = "0.18.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bitvec", "frame-benchmarking", @@ -7383,7 +7404,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-phase" version = "38.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7405,7 +7426,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-support-benchmarking" version = "38.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7475,7 +7496,7 @@ dependencies = [ [[package]] name = "pallet-fast-unstake" version = "38.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "docify", "frame-benchmarking", @@ -7493,7 +7514,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "39.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-benchmarking", "frame-support", @@ -7515,7 +7536,7 @@ dependencies = [ [[package]] name = "pallet-identity" version = "39.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "enumflags2", "frame-benchmarking", @@ -7531,7 +7552,7 @@ dependencies = [ [[package]] name = "pallet-im-online" version = "38.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-benchmarking", "frame-support", @@ -7550,7 +7571,7 @@ dependencies = [ [[package]] name = "pallet-message-queue" version = "42.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "environmental", "frame-benchmarking", @@ -7569,7 +7590,7 @@ dependencies = [ [[package]] name = "pallet-mmr" version = "39.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-benchmarking", "frame-support", @@ -7586,7 +7607,7 @@ dependencies = [ [[package]] name = "pallet-multisig" version = "39.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "log", "parity-scale-codec", @@ -7597,7 +7618,7 @@ dependencies = [ [[package]] name = "pallet-offences" version = "38.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-support", "frame-system", @@ -7613,7 +7634,7 @@ dependencies = [ [[package]] name = "pallet-parameters" version = "0.10.1" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "docify", "frame-benchmarking", @@ -7630,7 +7651,7 @@ dependencies = [ [[package]] name = "pallet-preimage" version = "39.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-benchmarking", "frame-support", @@ -7646,7 +7667,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" version = "40.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "docify", "frame-benchmarking", @@ -7663,7 +7684,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "39.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-support", "frame-system", @@ -7684,7 +7705,7 @@ dependencies = [ [[package]] name = "pallet-staking" version = "39.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7706,7 +7727,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-fn" version = "22.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "log", "sp-arithmetic", @@ -7715,7 +7736,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "39.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "docify", "frame-benchmarking", @@ -7730,7 +7751,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "38.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "docify", "frame-benchmarking", @@ -7749,7 +7770,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "39.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-benchmarking", "frame-support", @@ -7765,7 +7786,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "42.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "jsonrpsee 0.24.9", "pallet-transaction-payment-rpc-runtime-api", @@ -7781,7 +7802,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "39.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -7793,7 +7814,7 @@ dependencies = [ [[package]] name = "pallet-treasury" version = "38.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "docify", "frame-benchmarking", @@ -7812,7 +7833,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "39.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-benchmarking", "frame-support", @@ -7844,7 +7865,7 @@ dependencies = [ [[package]] name = "pallet-vesting" version = "39.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-benchmarking", "frame-support", @@ -7858,7 +7879,7 @@ dependencies = [ [[package]] name = "pallet-xcm" version = "18.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bounded-collections", "frame-benchmarking", @@ -8198,7 +8219,7 @@ dependencies = [ [[package]] name = "polkadot-core-primitives" version = "16.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", "scale-info", @@ -8209,7 +8230,7 @@ dependencies = [ [[package]] name = "polkadot-node-metrics" version = "21.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bs58", "futures", @@ -8228,7 +8249,7 @@ dependencies = [ [[package]] name = "polkadot-node-network-protocol" version = "21.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-channel 1.9.0", "async-trait", @@ -8253,7 +8274,7 @@ dependencies = [ [[package]] name = "polkadot-node-primitives" version = "17.0.1" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bitvec", "bounded-vec", @@ -8279,7 +8300,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-types" version = "21.0.1" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "bitvec", @@ -8308,7 +8329,7 @@ dependencies = [ [[package]] name = "polkadot-overseer" version = "21.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "futures", @@ -8330,7 +8351,7 @@ dependencies = [ [[package]] name = "polkadot-parachain-primitives" version = "15.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bounded-collections", "derive_more 0.99.20", @@ -8346,7 +8367,7 @@ dependencies = [ [[package]] name = "polkadot-primitives" version = "17.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bitvec", "hex-literal 0.4.1", @@ -8374,7 +8395,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" version = "18.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bitvec", "frame-benchmarking", @@ -8425,7 +8446,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-metrics" version = "18.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bs58", "frame-benchmarking", @@ -8437,7 +8458,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-parachains" version = "18.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bitflags 1.3.2", "bitvec", @@ -8486,7 +8507,7 @@ dependencies = [ [[package]] name = "polkadot-sdk-frame" version = "0.8.1" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "docify", "frame-benchmarking", @@ -8520,7 +8541,7 @@ dependencies = [ [[package]] name = "polkadot-statement-table" version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", "polkadot-primitives", @@ -9889,7 +9910,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "30.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "log", "sp-core", @@ -9900,7 +9921,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" version = "0.48.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "futures", @@ -9930,7 +9951,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.48.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "futures", "futures-timer", @@ -9952,7 +9973,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.43.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", "sp-api", @@ -9967,7 +9988,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "41.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "array-bytes", "docify", @@ -9994,7 +10015,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "12.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", @@ -10005,7 +10026,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.50.1" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "array-bytes", "chrono", @@ -10047,7 +10068,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "38.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "fnv", "futures", @@ -10074,7 +10095,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.45.1" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "hash-db", "kvdb", @@ -10100,7 +10121,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.47.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "futures", @@ -10153,7 +10174,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.48.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "fork-tree", @@ -10189,7 +10210,7 @@ dependencies = [ [[package]] name = "sc-consensus-beefy" version = "27.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "array-bytes", "async-channel 1.9.0", @@ -10225,7 +10246,7 @@ dependencies = [ [[package]] name = "sc-consensus-beefy-rpc" version = "27.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "futures", "jsonrpsee 0.24.9", @@ -10245,7 +10266,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" version = "0.47.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "fork-tree", "parity-scale-codec", @@ -10258,7 +10279,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "ahash", "array-bytes", @@ -10337,7 +10358,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.47.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "futures", @@ -10360,7 +10381,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.41.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", @@ -10383,7 +10404,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.36.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "polkavm", "sc-allocator", @@ -10396,7 +10417,7 @@ dependencies = [ [[package]] name = "sc-executor-polkavm" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "log", "polkavm", @@ -10407,7 +10428,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.36.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "anyhow", "cfg-if", @@ -10425,7 +10446,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.47.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "console", "futures", @@ -10442,7 +10463,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "34.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "array-bytes", "parking_lot 0.12.3", @@ -10456,7 +10477,7 @@ dependencies = [ [[package]] name = "sc-mixnet" version = "0.18.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "array-bytes", "arrayvec 0.7.6", @@ -10485,7 +10506,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.48.3" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "array-bytes", "async-channel 1.9.0", @@ -10536,7 +10557,7 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.47.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "bitflags 1.3.2", @@ -10554,7 +10575,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.48.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "ahash", "futures", @@ -10573,7 +10594,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.47.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "array-bytes", "async-channel 1.9.0", @@ -10594,7 +10615,7 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.47.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "array-bytes", "async-channel 1.9.0", @@ -10630,7 +10651,7 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.47.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "array-bytes", "futures", @@ -10649,7 +10670,7 @@ dependencies = [ [[package]] name = "sc-network-types" version = "0.15.2" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bs58", "ed25519-dalek", @@ -10666,7 +10687,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "43.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "array-bytes", "bytes", @@ -10703,7 +10724,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.18.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -10712,7 +10733,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "43.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "futures", "jsonrpsee 0.24.9", @@ -10744,7 +10765,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.47.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "jsonrpsee 0.24.9", "parity-scale-codec", @@ -10764,7 +10785,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "20.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "dyn-clone", "forwarded-header-value", @@ -10788,7 +10809,7 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" version = "0.48.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "array-bytes", "futures", @@ -10820,7 +10841,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.49.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "directories", @@ -10884,7 +10905,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.37.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "log", "parity-scale-codec", @@ -10895,7 +10916,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "41.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "derive_more 0.99.20", "futures", @@ -10916,7 +10937,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "chrono", "futures", @@ -10936,7 +10957,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "38.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "chrono", "console", @@ -10964,7 +10985,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", @@ -10975,7 +10996,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "38.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "futures", @@ -11006,7 +11027,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "38.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "futures", @@ -11022,7 +11043,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "18.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-channel 1.9.0", "futures", @@ -11605,7 +11626,7 @@ checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" [[package]] name = "slot-range-helper" version = "16.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "enumn", "parity-scale-codec", @@ -11772,7 +11793,29 @@ dependencies = [ "rlp 0.6.1", "scale-info", "serde", - "snowbridge-ethereum", + "snowbridge-ethereum 0.3.0", + "snowbridge-milagro-bls", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "ssz_rs", + "ssz_rs_derive", +] + +[[package]] +name = "snowbridge-beacon-primitives" +version = "0.12.1" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" +dependencies = [ + "byte-slice-cast", + "frame-support", + "hex", + "parity-scale-codec", + "rlp 0.6.1", + "scale-info", + "serde", + "snowbridge-ethereum 0.11.0", "snowbridge-milagro-bls", "sp-core", "sp-io", @@ -11807,6 +11850,29 @@ dependencies = [ "staging-xcm-executor", ] +[[package]] +name = "snowbridge-core" +version = "0.12.1" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" +dependencies = [ + "ethabi-decode", + "frame-support", + "frame-system", + "hex-literal 0.4.1", + "parity-scale-codec", + "polkadot-parachain-primitives", + "scale-info", + "serde", + "snowbridge-beacon-primitives 0.12.1", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "staging-xcm", + "staging-xcm-builder", +] + [[package]] name = "snowbridge-ethereum" version = "0.3.0" @@ -11828,6 +11894,26 @@ dependencies = [ "sp-std", ] +[[package]] +name = "snowbridge-ethereum" +version = "0.11.0" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" +dependencies = [ + "ethabi-decode", + "ethbloom", + "ethereum-types", + "hex-literal 0.4.1", + "parity-bytes", + "parity-scale-codec", + "rlp 0.6.1", + "scale-info", + "serde", + "serde-big-array", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "snowbridge-inbound-queue-primitives" version = "0.9.0" @@ -11841,8 +11927,8 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "snowbridge-beacon-primitives", - "snowbridge-core", + "snowbridge-beacon-primitives 0.2.0", + "snowbridge-core 0.2.0", "snowbridge-verification-primitives", "sp-core", "sp-io", @@ -11883,6 +11969,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "snowbridge-outbound-queue-merkle-tree" +version = "0.10.0" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" +dependencies = [ + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-runtime", +] + [[package]] name = "snowbridge-outbound-queue-primitives" version = "0.2.0" @@ -11897,7 +11994,7 @@ dependencies = [ "parity-scale-codec", "polkadot-parachain-primitives", "scale-info", - "snowbridge-core", + "snowbridge-core 0.2.0", "snowbridge-verification-primitives", "sp-arithmetic", "sp-core", @@ -11916,7 +12013,7 @@ dependencies = [ "frame-support", "parity-scale-codec", "scale-info", - "snowbridge-core", + "snowbridge-core 0.2.0", "snowbridge-merkle-tree", "snowbridge-outbound-queue-primitives", "sp-api", @@ -11939,9 +12036,9 @@ dependencies = [ "scale-info", "serde", "serde_json", - "snowbridge-beacon-primitives", - "snowbridge-core", - "snowbridge-ethereum", + "snowbridge-beacon-primitives 0.2.0", + "snowbridge-core 0.2.0", + "snowbridge-ethereum 0.3.0", "snowbridge-inbound-queue-primitives", "snowbridge-pallet-ethereum-client-fixtures", "sp-core", @@ -11956,8 +12053,8 @@ name = "snowbridge-pallet-ethereum-client-fixtures" version = "0.9.0" dependencies = [ "hex-literal 0.3.4", - "snowbridge-beacon-primitives", - "snowbridge-core", + "snowbridge-beacon-primitives 0.2.0", + "snowbridge-core 0.2.0", "snowbridge-inbound-queue-primitives", "sp-core", "sp-std", @@ -11979,8 +12076,8 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "snowbridge-beacon-primitives", - "snowbridge-core", + "snowbridge-beacon-primitives 0.2.0", + "snowbridge-core 0.2.0", "snowbridge-inbound-queue-primitives", "snowbridge-pallet-ethereum-client", "snowbridge-pallet-inbound-queue-v2-fixtures", @@ -12001,20 +12098,42 @@ name = "snowbridge-pallet-inbound-queue-v2-fixtures" version = "0.10.0" dependencies = [ "hex-literal 0.3.4", - "snowbridge-beacon-primitives", - "snowbridge-core", + "snowbridge-beacon-primitives 0.2.0", + "snowbridge-core 0.2.0", "snowbridge-inbound-queue-primitives", "sp-core", "sp-std", ] +[[package]] +name = "snowbridge-pallet-outbound-queue" +version = "0.12.1" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" +dependencies = [ + "bridge-hub-common 0.12.0", + "ethabi-decode", + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "serde", + "snowbridge-core 0.12.1", + "snowbridge-outbound-queue-merkle-tree", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "snowbridge-pallet-outbound-queue-v2" version = "0.2.0" dependencies = [ "alloy-core", "bp-relayers", - "bridge-hub-common", + "bridge-hub-common 0.13.1", "ethabi-decode", "frame-benchmarking", "frame-support", @@ -12024,7 +12143,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "snowbridge-core", + "snowbridge-core 0.2.0", "snowbridge-inbound-queue-primitives", "snowbridge-merkle-tree", "snowbridge-outbound-queue-primitives", @@ -12039,6 +12158,71 @@ dependencies = [ "staging-xcm-executor", ] +[[package]] +name = "snowbridge-pallet-system" +version = "0.13.1" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "hex", + "hex-literal 0.3.4", + "log", + "pallet-balances", + "pallet-message-queue", + "parity-scale-codec", + "polkadot-primitives", + "scale-info", + "snowbridge-core 0.2.0", + "snowbridge-outbound-queue-primitives", + "snowbridge-pallet-outbound-queue", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "staging-xcm", + "staging-xcm-executor", +] + +[[package]] +name = "snowbridge-pallet-system-v2" +version = "0.2.0" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "hex-literal 0.3.4", + "log", + "pallet-balances", + "pallet-xcm", + "parity-scale-codec", + "polkadot-primitives", + "scale-info", + "snowbridge-core 0.2.0", + "snowbridge-outbound-queue-primitives", + "snowbridge-pallet-outbound-queue-v2", + "snowbridge-pallet-system", + "snowbridge-test-utils", + "sp-core", + "sp-io", + "sp-keyring", + "sp-runtime", + "sp-std", + "staging-xcm", + "staging-xcm-executor", +] + +[[package]] +name = "snowbridge-system-v2-runtime-api" +version = "0.2.0" +dependencies = [ + "parity-scale-codec", + "snowbridge-core 0.2.0", + "sp-api", + "sp-std", + "staging-xcm", +] + [[package]] name = "snowbridge-test-utils" version = "0.1.0" @@ -12066,7 +12250,7 @@ dependencies = [ "frame-support", "parity-scale-codec", "scale-info", - "snowbridge-beacon-primitives", + "snowbridge-beacon-primitives 0.2.0", "sp-core", "sp-std", ] @@ -12125,7 +12309,7 @@ dependencies = [ [[package]] name = "sp-api" version = "35.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "docify", "hash-db", @@ -12147,7 +12331,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "21.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "Inflector", "blake2 0.10.6", @@ -12161,7 +12345,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "39.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", "scale-info", @@ -12173,7 +12357,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "docify", "integer-sqrt", @@ -12187,7 +12371,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" version = "35.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", "scale-info", @@ -12199,7 +12383,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "35.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "sp-api", "sp-inherents", @@ -12209,7 +12393,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "38.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "futures", "parity-scale-codec", @@ -12228,7 +12412,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.41.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "futures", @@ -12243,7 +12427,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.41.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "parity-scale-codec", @@ -12259,7 +12443,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.41.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "parity-scale-codec", @@ -12277,7 +12461,7 @@ dependencies = [ [[package]] name = "sp-consensus-beefy" version = "23.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", "scale-info", @@ -12297,7 +12481,7 @@ dependencies = [ [[package]] name = "sp-consensus-grandpa" version = "22.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "finality-grandpa", "log", @@ -12314,7 +12498,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.41.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", "scale-info", @@ -12325,7 +12509,7 @@ dependencies = [ [[package]] name = "sp-core" version = "35.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "array-bytes", "bitflags 1.3.2", @@ -12385,7 +12569,7 @@ dependencies = [ [[package]] name = "sp-crypto-hashing" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "blake2b_simd", "byteorder", @@ -12398,7 +12582,7 @@ dependencies = [ [[package]] name = "sp-crypto-hashing-proc-macro" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "quote", "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?branch=stable2412)", @@ -12408,7 +12592,7 @@ dependencies = [ [[package]] name = "sp-database" version = "10.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "kvdb", "parking_lot 0.12.3", @@ -12417,7 +12601,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "proc-macro2", "quote", @@ -12427,7 +12611,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.30.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "environmental", "parity-scale-codec", @@ -12437,7 +12621,7 @@ dependencies = [ [[package]] name = "sp-genesis-builder" version = "0.16.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", "scale-info", @@ -12449,7 +12633,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "35.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -12462,7 +12646,7 @@ dependencies = [ [[package]] name = "sp-io" version = "39.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bytes", "docify", @@ -12488,7 +12672,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "40.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "sp-core", "sp-runtime", @@ -12498,7 +12682,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.41.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", @@ -12509,7 +12693,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "thiserror 1.0.69", "zstd 0.12.4", @@ -12518,7 +12702,7 @@ dependencies = [ [[package]] name = "sp-metadata-ir" version = "0.8.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-metadata 18.0.0", "parity-scale-codec", @@ -12528,7 +12712,7 @@ dependencies = [ [[package]] name = "sp-mixnet" version = "0.13.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", "scale-info", @@ -12539,7 +12723,7 @@ dependencies = [ [[package]] name = "sp-mmr-primitives" version = "35.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "log", "parity-scale-codec", @@ -12556,7 +12740,7 @@ dependencies = [ [[package]] name = "sp-npos-elections" version = "35.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", "scale-info", @@ -12569,7 +12753,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "35.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "sp-api", "sp-core", @@ -12579,7 +12763,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "13.0.1" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "backtrace", "regex", @@ -12588,7 +12772,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "33.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "rustc-hash 1.1.0", "serde", @@ -12598,7 +12782,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "40.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "binary-merkle-tree", "docify", @@ -12627,7 +12811,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "29.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -12646,7 +12830,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "18.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "Inflector", "expander", @@ -12659,7 +12843,7 @@ dependencies = [ [[package]] name = "sp-session" version = "37.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", "scale-info", @@ -12673,7 +12857,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "37.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -12686,7 +12870,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.44.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "hash-db", "log", @@ -12706,7 +12890,7 @@ dependencies = [ [[package]] name = "sp-statement-store" version = "19.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "aes-gcm", "curve25519-dalek", @@ -12730,12 +12914,12 @@ dependencies = [ [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" [[package]] name = "sp-storage" version = "22.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "impl-serde 0.5.0", "parity-scale-codec", @@ -12747,7 +12931,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "35.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "parity-scale-codec", @@ -12759,7 +12943,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "17.0.1" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", "tracing", @@ -12770,7 +12954,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "35.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "sp-api", "sp-runtime", @@ -12779,7 +12963,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "35.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "async-trait", "parity-scale-codec", @@ -12793,7 +12977,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "38.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "ahash", "hash-db", @@ -12815,7 +12999,7 @@ dependencies = [ [[package]] name = "sp-version" version = "38.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "impl-serde 0.5.0", "parity-scale-codec", @@ -12832,7 +13016,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "15.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "parity-scale-codec", "proc-macro-warning 1.84.1", @@ -12844,7 +13028,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "21.0.1" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "anyhow", "impl-trait-for-tuples", @@ -12856,7 +13040,7 @@ dependencies = [ [[package]] name = "sp-weights" version = "31.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "bounded-collections", "parity-scale-codec", @@ -13068,7 +13252,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "staging-xcm" version = "15.0.3" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "array-bytes", "bounded-collections", @@ -13089,7 +13273,7 @@ dependencies = [ [[package]] name = "staging-xcm-builder" version = "18.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-support", "frame-system", @@ -13111,7 +13295,7 @@ dependencies = [ [[package]] name = "staging-xcm-executor" version = "18.0.2" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "environmental", "frame-benchmarking", @@ -13218,7 +13402,7 @@ dependencies = [ [[package]] name = "substrate-bip39" version = "0.6.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "hmac 0.12.1", "pbkdf2", @@ -13230,12 +13414,12 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" [[package]] name = "substrate-frame-rpc-system" version = "42.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "docify", "frame-system-rpc-runtime-api", @@ -13255,7 +13439,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.17.1" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "http-body-util", "hyper 1.6.0", @@ -13269,7 +13453,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "25.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "array-bytes", "build-helper", @@ -13974,7 +14158,7 @@ dependencies = [ [[package]] name = "tracing-gum" version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "coarsetime", "polkadot-primitives", @@ -13985,7 +14169,7 @@ dependencies = [ [[package]] name = "tracing-gum-proc-macro" version = "5.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "expander", "proc-macro-crate 3.3.0", @@ -15310,7 +15494,7 @@ dependencies = [ [[package]] name = "xcm-procedural" version = "11.0.1" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "Inflector", "proc-macro2", @@ -15321,7 +15505,7 @@ dependencies = [ [[package]] name = "xcm-runtime-apis" version = "0.5.2" -source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#823a912ab188db40f9b66ee1f8e011c0238dff55" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=stable2412#02fe4655b2426d9ed0573ba5eadd3c9bb2b2ee63" dependencies = [ "frame-support", "parity-scale-codec", diff --git a/operator/Cargo.toml b/operator/Cargo.toml index d09eb88f..fdefbf8c 100644 --- a/operator/Cargo.toml +++ b/operator/Cargo.toml @@ -11,6 +11,8 @@ members = [ "pallets/ethereum-client", "pallets/inbound-queue-v2", "pallets/outbound-queue-v2", + "pallets/system", + "pallets/system-v2", "pallets/validator-set", "primitives/bridge", "runtime", @@ -18,6 +20,8 @@ members = [ ] resolver = "2" +[workspace.lints] + [workspace.dependencies] # Local datahaven-runtime = { path = "./runtime", default-features = false } @@ -156,18 +160,22 @@ xcm-executor = { git = "https://github.com/paritytech/polkadot-sdk", branch = "s # Snowbridge bp-relayers = { git = "https://github.com/paritytech/polkadot-sdk", branch = "stable2412", default-features = false } bridge-hub-common = { path = "primitives/snowbridge/bridge-hub-common", default-features = false } +snowbridge-merkle-tree = { path = "primitives/snowbridge/merkle-tree", default-features = false } +snowbridge-pallet-system = { path = "pallets/system", default-features = false } snowbridge-beacon-primitives = { path = "primitives/snowbridge/beacon", default-features = false } snowbridge-core = { path = "primitives/snowbridge/core", default-features = false } snowbridge-ethereum = { path = "primitives/snowbridge/ethereum", default-features = false } snowbridge-inbound-queue-primitives = { path = "primitives/snowbridge/inbound-queue", default-features = false } -snowbridge-merkle-tree = { path = "primitives/snowbridge/merkle-tree", default-features = false } snowbridge-outbound-queue-primitives = { path = "primitives/snowbridge/outbound-queue", default-features = false } snowbridge-outbound-queue-v2-runtime-api = { path = "pallets/outbound-queue-v2/runtime-api", default-features = false } snowbridge-pallet-ethereum-client = { path = "pallets/ethereum-client", default-features = false } snowbridge-pallet-ethereum-client-fixtures = { path = "pallets/ethereum-client/fixtures", default-features = false } +snowbridge-pallet-outbound-queue = { git = "https://github.com/paritytech/polkadot-sdk", branch = "stable2412", default-features = false } snowbridge-pallet-inbound-queue-v2 = { path = "pallets/inbound-queue-v2", default-features = false } snowbridge-pallet-inbound-queue-v2-fixtures = { path = "pallets/inbound-queue-v2/fixtures", default-features = false } snowbridge-pallet-outbound-queue-v2 = { path = "pallets/outbound-queue-v2", default-features = false } +snowbridge-pallet-system-v2 = { path = "pallets/system-v2", default-features = false } +snowbridge-system-v2-runtime-api = { path = "pallets/system-v2/runtime-api", default-features = false } snowbridge-test-utils = { path = "primitives/snowbridge/test-utils", default-features = false } snowbridge-verification-primitives = { path = "primitives/snowbridge/verification", default-features = false } diff --git a/operator/pallets/system-v2/Cargo.toml b/operator/pallets/system-v2/Cargo.toml new file mode 100644 index 00000000..2e342327 --- /dev/null +++ b/operator/pallets/system-v2/Cargo.toml @@ -0,0 +1,85 @@ +[package] +name = "snowbridge-pallet-system-v2" +description = "Snowbridge System Pallet V2" +version = "0.2.0" +authors = ["Snowfork "] +edition.workspace = true +repository.workspace = true +license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[package.metadata.polkadot-sdk] +exclude-from-umbrella = true + +[dependencies] +codec = { features = ["derive"], workspace = true } +frame-benchmarking = { optional = true, workspace = true } +frame-support.workspace = true +frame-system.workspace = true +log = { workspace = true } +pallet-xcm.workspace = true +scale-info = { features = ["derive"], workspace = true } +snowbridge-core.workspace = true +snowbridge-outbound-queue-primitives.workspace = true +snowbridge-pallet-system.workspace = true +sp-core.workspace = true +sp-io.workspace = true +sp-runtime.workspace = true +sp-std.workspace = true +xcm-executor.workspace = true +xcm.workspace = true + +[dev-dependencies] +hex-literal = { workspace = true, default-features = true } +pallet-balances = { default-features = true, workspace = true } +polkadot-primitives = { default-features = true, workspace = true } +snowbridge-pallet-outbound-queue-v2 = { default-features = true, workspace = true } +snowbridge-test-utils = { workspace = true } +sp-keyring = { default-features = true, workspace = true } + +[features] +default = ["std"] +std = [ + "codec/std", + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "log/std", + "pallet-xcm/std", + "scale-info/std", + "snowbridge-core/std", + "snowbridge-outbound-queue-primitives/std", + "snowbridge-pallet-system/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "sp-std/std", + "xcm-executor/std", + "xcm/std", +] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-xcm/runtime-benchmarks", + "polkadot-primitives/runtime-benchmarks", + "snowbridge-core/runtime-benchmarks", + "snowbridge-pallet-outbound-queue-v2/runtime-benchmarks", + "snowbridge-pallet-system/runtime-benchmarks", + "snowbridge-test-utils/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "xcm-executor/runtime-benchmarks", +] +try-runtime = [ + "frame-support/try-runtime", + "frame-system/try-runtime", + "pallet-balances/try-runtime", + "pallet-xcm/try-runtime", + "snowbridge-pallet-outbound-queue-v2/try-runtime", + "snowbridge-pallet-system/try-runtime", + "sp-runtime/try-runtime", +] diff --git a/operator/pallets/system-v2/README.md b/operator/pallets/system-v2/README.md new file mode 100644 index 00000000..6456af8b --- /dev/null +++ b/operator/pallets/system-v2/README.md @@ -0,0 +1,4 @@ +# Ethereum System V2 + +This pallet is part of BridgeHub. Certain extrinsics in this pallet (like `register_token` and `add_tip`) will be called +from the System Frontend pallet on AssetHub. diff --git a/operator/pallets/system-v2/runtime-api/Cargo.toml b/operator/pallets/system-v2/runtime-api/Cargo.toml new file mode 100644 index 00000000..e654e7ae --- /dev/null +++ b/operator/pallets/system-v2/runtime-api/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "snowbridge-system-v2-runtime-api" +description = "Snowbridge System Runtime API V2" +version = "0.2.0" +authors = ["Snowfork "] +edition.workspace = true +repository.workspace = true +license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] + +[lints] +workspace = true + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[package.metadata.polkadot-sdk] +exclude-from-umbrella = true + +[dependencies] +codec = { features = [ + "derive", +], workspace = true } +snowbridge-core.workspace = true +sp-api.workspace = true +sp-std.workspace = true +xcm.workspace = true + +[features] +default = ["std"] +std = [ + "codec/std", + "snowbridge-core/std", + "sp-api/std", + "sp-std/std", + "xcm/std", +] diff --git a/operator/pallets/system-v2/runtime-api/README.md b/operator/pallets/system-v2/runtime-api/README.md new file mode 100644 index 00000000..8b2adffe --- /dev/null +++ b/operator/pallets/system-v2/runtime-api/README.md @@ -0,0 +1,4 @@ +# Ethereum System Runtime API V2 + +Provides an API for looking up an agent ID on Ethereum. An agent ID is a unique mapping to an Agent contract on Ethereum +which acts as the sovereign account for the Location. diff --git a/operator/pallets/system-v2/runtime-api/src/lib.rs b/operator/pallets/system-v2/runtime-api/src/lib.rs new file mode 100644 index 00000000..80d5ff55 --- /dev/null +++ b/operator/pallets/system-v2/runtime-api/src/lib.rs @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +#![cfg_attr(not(feature = "std"), no_std)] + +use snowbridge_core::AgentId; +use xcm::VersionedLocation; + +sp_api::decl_runtime_apis! { + pub trait ControlV2Api + { + /// Provides the Agent ID on Ethereum for the specified location. + fn agent_id(location: VersionedLocation) -> Option; + } +} diff --git a/operator/pallets/system-v2/src/api.rs b/operator/pallets/system-v2/src/api.rs new file mode 100644 index 00000000..963ab7b6 --- /dev/null +++ b/operator/pallets/system-v2/src/api.rs @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +//! Helpers for implementing runtime api + +use crate::Config; +use sp_core::H256; +use xcm::{prelude::*, VersionedLocation}; + +pub fn agent_id(location: VersionedLocation) -> Option +where + Runtime: Config, +{ + let location: Location = location.try_into().ok()?; + crate::Pallet::::location_to_message_origin(location).ok() +} diff --git a/operator/pallets/system-v2/src/benchmarking.rs b/operator/pallets/system-v2/src/benchmarking.rs new file mode 100644 index 00000000..01c13b9a --- /dev/null +++ b/operator/pallets/system-v2/src/benchmarking.rs @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +//! Benchmarking setup for pallet-template +use super::*; + +#[allow(unused)] +use crate::Pallet as SnowbridgeControl; +use frame_benchmarking::v2::*; +use xcm::prelude::*; + +#[benchmarks] +mod benchmarks { + use super::*; + + #[benchmark] + fn register_token() -> Result<(), BenchmarkError> { + let origin_location = Location::new(1, [Parachain(1000), PalletInstance(36)]); + let origin = ::Helper::make_xcm_origin(origin_location.clone()); + let creator = Box::new(VersionedLocation::from(origin_location.clone())); + let relay_token_asset_id: Location = Location::parent(); + let asset = Box::new(VersionedLocation::from(relay_token_asset_id)); + let asset_metadata = AssetMetadata { + name: "wnd".as_bytes().to_vec().try_into().unwrap(), + symbol: "wnd".as_bytes().to_vec().try_into().unwrap(), + decimals: 12, + }; + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, creator, asset, asset_metadata); + + Ok(()) + } + + impl_benchmark_test_suite!( + SnowbridgeControl, + crate::mock::new_test_ext(true), + crate::mock::Test + ); +} diff --git a/operator/pallets/system-v2/src/lib.rs b/operator/pallets/system-v2/src/lib.rs new file mode 100644 index 00000000..22a0f015 --- /dev/null +++ b/operator/pallets/system-v2/src/lib.rs @@ -0,0 +1,278 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +//! Governance API for controlling the Ethereum side of the bridge +//! +//! # Extrinsics +//! +//! ## Governance +//! +//! * [`Call::upgrade`]: Upgrade the Gateway contract on Ethereum. +//! * [`Call::set_operating_mode`]: Set the operating mode of the Gateway contract +//! +//! ## Polkadot-native tokens on Ethereum +//! +//! Tokens deposited on AssetHub pallet can be bridged to Ethereum as wrapped ERC20 tokens. As a +//! prerequisite, the token should be registered first. +//! +//! * [`Call::register_token`]: Register a token location as a wrapped ERC20 contract on Ethereum. +#![cfg_attr(not(feature = "std"), no_std)] +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod tests; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +pub mod api; +pub mod weights; +pub use weights::*; + +use frame_support::{pallet_prelude::*, traits::EnsureOrigin}; +use frame_system::pallet_prelude::*; +use snowbridge_core::{AgentIdOf as LocationHashOf, AssetMetadata, TokenId, TokenIdOf}; +use snowbridge_outbound_queue_primitives::{ + v2::{Command, Initializer, Message, SendMessage}, + OperatingMode, SendError, +}; +use snowbridge_pallet_system::{ForeignToNativeId, NativeToForeignId}; +use sp_core::{H160, H256}; +use sp_io::hashing::blake2_256; +use sp_runtime::traits::MaybeEquivalence; +use sp_std::prelude::*; +use xcm::prelude::*; +use xcm_executor::traits::ConvertLocation; + +#[cfg(feature = "runtime-benchmarks")] +use frame_support::traits::OriginTrait; + +pub use pallet::*; + +pub type AccountIdOf = ::AccountId; +#[cfg(feature = "runtime-benchmarks")] +pub trait BenchmarkHelper +where + O: OriginTrait, +{ + fn make_xcm_origin(location: Location) -> O; +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config + snowbridge_pallet_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// Send messages to Ethereum + type OutboundQueue: SendMessage; + + /// Origin check for XCM locations that transact with this pallet + type FrontendOrigin: EnsureOrigin; + + /// Origin for governance calls + type GovernanceOrigin: EnsureOrigin; + + type WeightInfo: WeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type Helper: BenchmarkHelper; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// An Upgrade message was sent to the Gateway + Upgrade { + impl_address: H160, + impl_code_hash: H256, + initializer_params_hash: H256, + }, + /// An SetOperatingMode message was sent to the Gateway + SetOperatingMode { mode: OperatingMode }, + /// Register Polkadot-native token as a wrapped ERC20 token on Ethereum + RegisterToken { + /// Location of Polkadot-native token + location: VersionedLocation, + /// ID of Polkadot-native token on Ethereum + foreign_token_id: H256, + }, + } + + #[pallet::error] + pub enum Error { + /// Location could not be reachored + LocationReanchorFailed, + /// A token location could not be converted to a token ID. + LocationConversionFailed, + /// A `VersionedLocation` could not be converted into a `Location`. + UnsupportedLocationVersion, + /// An XCM could not be sent, due to a `SendError`. + Send(SendError), + /// The gateway contract upgrade message could not be sent due to invalid upgrade + /// parameters. + InvalidUpgradeParameters, + } + + #[pallet::call] + impl Pallet { + /// Sends command to the Gateway contract to upgrade itself with a new implementation + /// contract + /// + /// Fee required: No + /// + /// - `origin`: Must be `Root`. + /// - `impl_address`: The address of the implementation contract. + /// - `impl_code_hash`: The codehash of the implementation contract. + /// - `initializer`: Optionally call an initializer on the implementation contract. + #[pallet::call_index(3)] + #[pallet::weight((::WeightInfo::upgrade(), DispatchClass::Operational))] + pub fn upgrade( + origin: OriginFor, + impl_address: H160, + impl_code_hash: H256, + initializer: Initializer, + ) -> DispatchResult { + let origin_location = T::GovernanceOrigin::ensure_origin(origin)?; + let origin = Self::location_to_message_origin(origin_location)?; + + ensure!( + !impl_address.eq(&H160::zero()) && !impl_code_hash.eq(&H256::zero()), + Error::::InvalidUpgradeParameters + ); + + let initializer_params_hash: H256 = blake2_256(initializer.params.as_ref()).into(); + + let command = Command::Upgrade { + impl_address, + impl_code_hash, + initializer, + }; + Self::send(origin, command, 0)?; + + Self::deposit_event(Event::::Upgrade { + impl_address, + impl_code_hash, + initializer_params_hash, + }); + Ok(()) + } + + /// Sends a message to the Gateway contract to change its operating mode + /// + /// Fee required: No + /// + /// - `origin`: Must be `GovernanceOrigin` + #[pallet::call_index(4)] + #[pallet::weight((::WeightInfo::set_operating_mode(), DispatchClass::Operational))] + pub fn set_operating_mode(origin: OriginFor, mode: OperatingMode) -> DispatchResult { + let origin_location = T::GovernanceOrigin::ensure_origin(origin)?; + let origin = Self::location_to_message_origin(origin_location)?; + + let command = Command::SetOperatingMode { mode }; + Self::send(origin, command, 0)?; + + Self::deposit_event(Event::::SetOperatingMode { mode }); + Ok(()) + } + + /// Registers a Polkadot-native token as a wrapped ERC20 token on Ethereum. + /// + /// The system frontend pallet on AH proxies this call to BH. + /// + /// - `sender`: The original sender initiating the call on AH + /// - `asset_id`: Location of the asset (relative to this chain) + /// - `metadata`: Metadata to include in the instantiated ERC20 contract on Ethereum + /// - `fee`: Ether to pay for the execution cost on Ethereum + #[pallet::call_index(0)] + #[pallet::weight(::WeightInfo::register_token())] + pub fn register_token( + origin: OriginFor, + sender: Box, + asset_id: Box, + metadata: AssetMetadata, + ) -> DispatchResult { + T::FrontendOrigin::ensure_origin(origin)?; + + let sender_location: Location = (*sender) + .try_into() + .map_err(|_| Error::::UnsupportedLocationVersion)?; + let asset_location: Location = (*asset_id) + .try_into() + .map_err(|_| Error::::UnsupportedLocationVersion)?; + + let location = Self::reanchor(asset_location)?; + let token_id = TokenIdOf::convert_location(&location) + .ok_or(Error::::LocationConversionFailed)?; + + if !ForeignToNativeId::::contains_key(token_id) { + NativeToForeignId::::insert(location.clone(), token_id); + ForeignToNativeId::::insert(token_id, location.clone()); + } + + let command = Command::RegisterForeignToken { + token_id, + name: metadata.name.into_inner(), + symbol: metadata.symbol.into_inner(), + decimals: metadata.decimals, + }; + + let message_origin = Self::location_to_message_origin(sender_location)?; + Self::send(message_origin, command, 0)?; + + Self::deposit_event(Event::::RegisterToken { + location: location.into(), + foreign_token_id: token_id, + }); + + Ok(()) + } + } + + impl Pallet { + /// Send `command` to the Gateway from a specific origin/agent + fn send(origin: H256, command: Command, fee: u128) -> DispatchResult { + let mut message = Message { + origin, + id: Default::default(), + fee, + commands: BoundedVec::try_from(vec![command]).unwrap(), + }; + let hash = sp_io::hashing::blake2_256(&message.encode()); + message.id = hash.into(); + + let ticket = ::OutboundQueue::validate(&message) + .map_err(|err| Error::::Send(err))?; + + ::OutboundQueue::deliver(ticket) + .map_err(|err| Error::::Send(err))?; + Ok(()) + } + + /// Reanchor the `location` in context of ethereum + pub fn reanchor(location: Location) -> Result> { + location + .reanchored(&T::EthereumLocation::get(), &T::UniversalLocation::get()) + .map_err(|_| Error::::LocationReanchorFailed) + } + + pub fn location_to_message_origin(location: Location) -> Result> { + let reanchored_location = Self::reanchor(location)?; + LocationHashOf::convert_location(&reanchored_location) + .ok_or(Error::::LocationConversionFailed) + } + } + + impl MaybeEquivalence for Pallet { + fn convert(foreign_id: &TokenId) -> Option { + ForeignToNativeId::::get(foreign_id) + } + fn convert_back(location: &Location) -> Option { + NativeToForeignId::::get(location) + } + } +} diff --git a/operator/pallets/system-v2/src/mock.rs b/operator/pallets/system-v2/src/mock.rs new file mode 100644 index 00000000..64c2009f --- /dev/null +++ b/operator/pallets/system-v2/src/mock.rs @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +use frame_support::{ + derive_impl, parameter_types, + traits::{tokens::fungible::Mutate, ConstU128, Contains}, + PalletId, +}; +use sp_core::H256; + +use crate as snowbridge_system_v2; +use frame_system::EnsureRootWithSuccess; +use snowbridge_core::{ + gwei, meth, sibling_sovereign_account, AllowSiblingsOnly, ParaId, PricingParameters, Rewards, +}; + +pub use snowbridge_test_utils::{mock_origin::pallet_xcm_origin, mock_outbound_queue::*}; +use sp_runtime::{ + traits::{AccountIdConversion, BlakeTwo256, IdentityLookup}, + AccountId32, BuildStorage, FixedU128, +}; +use xcm::{opaque::latest::WESTEND_GENESIS_HASH, prelude::*}; + +#[cfg(feature = "runtime-benchmarks")] +use crate::BenchmarkHelper; + +type Block = frame_system::mocking::MockBlock; +type Balance = u128; + +pub type AccountId = AccountId32; + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + XcmOrigin: pallet_xcm_origin::{Pallet, Origin}, + EthereumSystem: snowbridge_pallet_system, + EthereumSystemV2: snowbridge_system_v2, + } +); + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] +impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type RuntimeTask = RuntimeTask; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type RuntimeEvent = RuntimeEvent; + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type Nonce = u64; + type Block = Block; +} + +#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] +impl pallet_balances::Config for Test { + type Balance = Balance; + type ExistentialDeposit = ConstU128<1>; + type AccountStore = System; +} + +impl pallet_xcm_origin::Config for Test { + type RuntimeOrigin = RuntimeOrigin; +} + +parameter_types! { + pub const AnyNetwork: Option = None; + pub const RelayNetwork: Option = Some(NetworkId::ByGenesis(WESTEND_GENESIS_HASH)); + pub const RelayLocation: Location = Location::parent(); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(1013)].into(); + pub EthereumNetwork: NetworkId = Ethereum { chain_id: 11155111 }; + pub EthereumDestination: Location = Location::new(2,[GlobalConsensus(EthereumNetwork::get())]); +} + +parameter_types! { + pub const InitialFunding: u128 = 1_000_000_000_000; + pub BridgeHubParaId: ParaId = ParaId::new(1002); + pub AssetHubParaId: ParaId = ParaId::new(1000); + pub TestParaId: u32 = 2000; + pub RootLocation: Location = Location::parent(); + pub FrontendLocation: Location = Location::new(1, [Parachain(1000), PalletInstance(36)]); +} + +#[cfg(feature = "runtime-benchmarks")] +impl BenchmarkHelper for () { + fn make_xcm_origin(location: Location) -> RuntimeOrigin { + RuntimeOrigin::from(pallet_xcm_origin::Origin(location)) + } +} + +pub struct AllowFromAssetHub; +impl Contains for AllowFromAssetHub { + fn contains(location: &Location) -> bool { + FrontendLocation::get() == *location + } +} + +impl crate::Config for Test { + type RuntimeEvent = RuntimeEvent; + type OutboundQueue = MockOkOutboundQueue; + type FrontendOrigin = pallet_xcm_origin::EnsureXcm; + type GovernanceOrigin = EnsureRootWithSuccess; + type WeightInfo = (); + #[cfg(feature = "runtime-benchmarks")] + type Helper = (); +} + +parameter_types! { + pub TreasuryAccount: AccountId = PalletId(*b"py/trsry").into_account_truncating(); + pub Parameters: PricingParameters = PricingParameters { + exchange_rate: FixedU128::from_rational(1, 400), + fee_per_gas: gwei(20), + rewards: Rewards { local: 10_000_000_000, remote: meth(1) }, + multiplier: FixedU128::from_rational(4, 3) + }; + pub const InboundDeliveryCost: u128 = 1_000_000_000; +} + +#[cfg(feature = "runtime-benchmarks")] +impl snowbridge_pallet_system::BenchmarkHelper for () { + fn make_xcm_origin(location: Location) -> RuntimeOrigin { + RuntimeOrigin::from(pallet_xcm_origin::Origin(location)) + } +} + +impl snowbridge_pallet_system::Config for Test { + type RuntimeEvent = RuntimeEvent; + type OutboundQueue = MockOkOutboundQueueV1; + type SiblingOrigin = pallet_xcm_origin::EnsureXcm; + type AgentIdOf = snowbridge_core::AgentIdOf; + type Token = Balances; + type TreasuryAccount = TreasuryAccount; + type DefaultPricingParameters = Parameters; + type InboundDeliveryCost = InboundDeliveryCost; + type WeightInfo = (); + type UniversalLocation = UniversalLocation; + type EthereumLocation = EthereumDestination; + #[cfg(feature = "runtime-benchmarks")] + type Helper = (); +} + +// Build genesis storage according to the mock runtime. +pub fn new_test_ext(_genesis_build: bool) -> sp_io::TestExternalities { + let storage = frame_system::GenesisConfig::::default() + .build_storage() + .unwrap(); + + let mut ext: sp_io::TestExternalities = storage.into(); + let initial_amount = InitialFunding::get(); + let test_para_id = TestParaId::get(); + let sovereign_account = sibling_sovereign_account::(test_para_id.into()); + ext.execute_with(|| { + System::set_block_number(1); + Balances::mint_into(&AccountId32::from([0; 32]), initial_amount).unwrap(); + Balances::mint_into(&sovereign_account, initial_amount).unwrap(); + }); + ext +} + +// Test helpers + +pub fn make_xcm_origin(location: Location) -> RuntimeOrigin { + pallet_xcm_origin::Origin(location).into() +} diff --git a/operator/pallets/system-v2/src/tests.rs b/operator/pallets/system-v2/src/tests.rs new file mode 100644 index 00000000..d625238d --- /dev/null +++ b/operator/pallets/system-v2/src/tests.rs @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +use crate::{mock::*, DispatchError::BadOrigin, *}; +use frame_support::{assert_noop, assert_ok}; +use sp_keyring::sr25519::Keyring; +use xcm::{latest::WESTEND_GENESIS_HASH, prelude::*}; + +#[test] +fn register_tokens_succeeds() { + new_test_ext(true).execute_with(|| { + let origin = make_xcm_origin(FrontendLocation::get()); + let versioned_location: VersionedLocation = Location::parent().into(); + + assert_ok!(EthereumSystemV2::register_token( + origin, + Box::new(versioned_location.clone()), + Box::new(versioned_location), + Default::default(), + )); + }); +} + +#[test] +fn agent_id_from_location() { + new_test_ext(true).execute_with(|| { + let bob: AccountId = Keyring::Bob.into(); + let origin = Location::new( + 1, + [ + Parachain(1000), + AccountId32 { + network: Some(NetworkId::ByGenesis(WESTEND_GENESIS_HASH)), + id: bob.into(), + }, + ], + ); + let agent_id = EthereumSystemV2::location_to_message_origin(origin.clone()).unwrap(); + let expected_agent_id = + hex_literal::hex!("fa2d646322a1c6db25dd004f44f14f3d39a9556bed9655f372942a84a5b3d93b") + .into(); + assert_eq!(agent_id, expected_agent_id); + }); +} + +#[test] +fn upgrade_as_root() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::root(); + let address: H160 = [1_u8; 20].into(); + let code_hash: H256 = [1_u8; 32].into(); + let initializer = Initializer { + params: [0; 256].into(), + maximum_required_gas: 10000, + }; + let initializer_params_hash: H256 = blake2_256(initializer.params.as_ref()).into(); + assert_ok!(EthereumSystemV2::upgrade( + origin, + address, + code_hash, + initializer + )); + + System::assert_last_event(RuntimeEvent::EthereumSystemV2(crate::Event::Upgrade { + impl_address: address, + impl_code_hash: code_hash, + initializer_params_hash, + })); + }); +} + +#[test] +fn upgrade_as_signed_fails() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::signed(sp_runtime::AccountId32::new([0; 32])); + let address: H160 = Default::default(); + let code_hash: H256 = Default::default(); + let initializer = Initializer { + params: [0; 256].into(), + maximum_required_gas: 10000, + }; + assert_noop!( + EthereumSystemV2::upgrade(origin, address, code_hash, initializer), + BadOrigin + ); + }); +} + +#[test] +fn upgrade_with_params() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::root(); + let address: H160 = [1_u8; 20].into(); + let code_hash: H256 = [1_u8; 32].into(); + let initializer = Initializer { + params: [0; 256].into(), + maximum_required_gas: 10000, + }; + assert_ok!(EthereumSystemV2::upgrade( + origin, + address, + code_hash, + initializer + )); + }); +} + +#[test] +fn set_operating_mode() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::root(); + let mode = OperatingMode::RejectingOutboundMessages; + + assert_ok!(EthereumSystemV2::set_operating_mode(origin, mode)); + + System::assert_last_event(RuntimeEvent::EthereumSystemV2( + crate::Event::SetOperatingMode { mode }, + )); + }); +} + +pub struct RegisterTokenTestCase { + /// Input: Location of Polkadot-native token relative to BH + pub native: Location, +} + +#[test] +fn register_all_tokens_succeeds() { + let test_cases = vec![ + // DOT + RegisterTokenTestCase { + native: Location::parent(), + }, + // GLMR (Some Polkadot parachain currency) + RegisterTokenTestCase { + native: Location::new(1, [Parachain(2004)]), + }, + // USDT + RegisterTokenTestCase { + native: Location::new(1, [Parachain(1000), PalletInstance(50), GeneralIndex(1984)]), + }, + // KSM + RegisterTokenTestCase { + native: Location::new(2, [GlobalConsensus(Kusama)]), + }, + // KAR (Some Kusama parachain currency) + RegisterTokenTestCase { + native: Location::new(2, [GlobalConsensus(Kusama), Parachain(2000)]), + }, + ]; + for tc in test_cases.iter() { + new_test_ext(true).execute_with(|| { + let origin = make_xcm_origin(FrontendLocation::get()); + let versioned_location: VersionedLocation = tc.native.clone().into(); + + assert_ok!(EthereumSystemV2::register_token( + origin, + Box::new(versioned_location.clone()), + Box::new(versioned_location), + Default::default() + )); + + let reanchored_location = EthereumSystemV2::reanchor(tc.native.clone()).unwrap(); + let foreign_token_id = + EthereumSystemV2::location_to_message_origin(tc.native.clone()).unwrap(); + + assert_eq!( + NativeToForeignId::::get(reanchored_location.clone()), + Some(foreign_token_id) + ); + assert_eq!( + ForeignToNativeId::::get(foreign_token_id), + Some(reanchored_location.clone()) + ); + + System::assert_last_event(RuntimeEvent::EthereumSystemV2( + Event::::RegisterToken { + location: reanchored_location.into(), + foreign_token_id, + }, + )); + }); + } +} + +#[test] +fn register_ethereum_native_token_fails() { + new_test_ext(true).execute_with(|| { + let origin = make_xcm_origin(FrontendLocation::get()); + let location = Location::new(2, [GlobalConsensus(Ethereum { chain_id: 11155111 })]); + let versioned_location: Box = Box::new(location.clone().into()); + assert_noop!( + EthereumSystemV2::register_token( + origin, + versioned_location.clone(), + versioned_location.clone(), + Default::default() + ), + Error::::LocationConversionFailed + ); + }); +} diff --git a/operator/pallets/system-v2/src/weights.rs b/operator/pallets/system-v2/src/weights.rs new file mode 100644 index 00000000..9c8a76a5 --- /dev/null +++ b/operator/pallets/system-v2/src/weights.rs @@ -0,0 +1,89 @@ + +//! Autogenerated weights for `snowbridge_system` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-10-09, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `crake.local`, CPU: `` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: `1024` + +// Executed Command: +// target/release/polkadot-parachain +// benchmark +// pallet +// --chain +// bridge-hub-rococo-dev +// --pallet=snowbridge_system +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --template +// ../parachain/templates/module-weight-template.hbs +// --output +// ../parachain/pallets/control/src/weights.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for `snowbridge_system`. +pub trait WeightInfo { + fn register_token() -> Weight; + fn upgrade() -> Weight; + fn set_operating_mode() -> Weight; +} + +// For backwards compatibility and tests. +impl WeightInfo for () { + fn register_token() -> Weight { + // Proof Size summary in bytes: + // Measured: `256` + // Estimated: `6044` + // Minimum execution time: 45_000_000 picoseconds. + Weight::from_parts(45_000_000, 6044) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: EthereumOutboundQueue PalletOperatingMode (r:1 w:0) + /// Proof: EthereumOutboundQueue PalletOperatingMode (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(5), added: 500, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:0 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65585), added: 68060, mode: MaxEncodedLen) + fn upgrade() -> Weight { + // Proof Size summary in bytes: + // Measured: `80` + // Estimated: `3517` + // Minimum execution time: 44_000_000 picoseconds. + Weight::from_parts(44_000_000, 3517) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: EthereumOutboundQueue PalletOperatingMode (r:1 w:0) + /// Proof: EthereumOutboundQueue PalletOperatingMode (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(5), added: 500, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:0 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65585), added: 68060, mode: MaxEncodedLen) + fn set_operating_mode() -> Weight { + // Proof Size summary in bytes: + // Measured: `80` + // Estimated: `3517` + // Minimum execution time: 31_000_000 picoseconds. + Weight::from_parts(31_000_000, 3517) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } +} diff --git a/operator/pallets/system/Cargo.toml b/operator/pallets/system/Cargo.toml new file mode 100644 index 00000000..abefc2e3 --- /dev/null +++ b/operator/pallets/system/Cargo.toml @@ -0,0 +1,80 @@ +[package] +name = "snowbridge-pallet-system" +description = "Snowbridge System Pallet" +version = "0.13.1" +authors = ["Snowfork "] +edition.workspace = true +repository.workspace = true +license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[package.metadata.polkadot-sdk] +exclude-from-umbrella = true + +[dependencies] +codec = { features = ["derive"], workspace = true } +frame-benchmarking = { optional = true, workspace = true } +frame-support.workspace = true +frame-system.workspace = true +log = { workspace = true } +scale-info = { features = ["derive"], workspace = true } +snowbridge-core.workspace = true +snowbridge-outbound-queue-primitives.workspace = true +sp-core.workspace = true +sp-io.workspace = true +sp-runtime.workspace = true +sp-std.workspace = true +xcm-executor.workspace = true +xcm.workspace = true + +[dev-dependencies] +hex = { workspace = true, default-features = true } +hex-literal = { workspace = true, default-features = true } +pallet-balances = { default-features = true, workspace = true } +pallet-message-queue = { default-features = true, workspace = true } +polkadot-primitives = { default-features = true, workspace = true } +snowbridge-pallet-outbound-queue = { default-features = true, workspace = true } + +[features] +default = ["std"] +std = [ + "codec/std", + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "log/std", + "scale-info/std", + "snowbridge-core/std", + "snowbridge-outbound-queue-primitives/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "sp-std/std", + "xcm-executor/std", + "xcm/std", +] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-message-queue/runtime-benchmarks", + "polkadot-primitives/runtime-benchmarks", + "snowbridge-core/runtime-benchmarks", + "snowbridge-pallet-outbound-queue/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "xcm-executor/runtime-benchmarks", +] +try-runtime = [ + "frame-support/try-runtime", + "frame-system/try-runtime", + "pallet-balances/try-runtime", + "pallet-message-queue/try-runtime", + "snowbridge-pallet-outbound-queue/try-runtime", + "sp-runtime/try-runtime", +] + +[lib] +test = false \ No newline at end of file diff --git a/operator/pallets/system/README.md b/operator/pallets/system/README.md new file mode 100644 index 00000000..5ab11d45 --- /dev/null +++ b/operator/pallets/system/README.md @@ -0,0 +1,3 @@ +# Ethereum System + +Contains management functions to manage functions on Ethereum. For example, creating agents and channels. diff --git a/operator/pallets/system/runtime-api/Cargo.toml b/operator/pallets/system/runtime-api/Cargo.toml new file mode 100644 index 00000000..07eb01b5 --- /dev/null +++ b/operator/pallets/system/runtime-api/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "snowbridge-system-runtime-api" +description = "Snowbridge System Runtime API" +version = "0.13.0" +authors = ["Snowfork "] +edition.workspace = true +repository.workspace = true +license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] + +[lints] +workspace = true + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[package.metadata.polkadot-sdk] +exclude-from-umbrella = true + +[dependencies] +codec = { features = [ + "derive", +], workspace = true } +snowbridge-core.workspace = true +sp-api.workspace = true +sp-std.workspace = true +xcm.workspace = true + +[features] +default = ["std"] +std = [ + "codec/std", + "snowbridge-core/std", + "sp-api/std", + "sp-std/std", + "xcm/std", +] diff --git a/operator/pallets/system/runtime-api/README.md b/operator/pallets/system/runtime-api/README.md new file mode 100644 index 00000000..99827c9c --- /dev/null +++ b/operator/pallets/system/runtime-api/README.md @@ -0,0 +1,3 @@ +# Ethereum System Runtime API + +Provides an API for looking up an agent ID on Ethereum. diff --git a/operator/pallets/system/runtime-api/src/lib.rs b/operator/pallets/system/runtime-api/src/lib.rs new file mode 100644 index 00000000..7f119809 --- /dev/null +++ b/operator/pallets/system/runtime-api/src/lib.rs @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +#![cfg_attr(not(feature = "std"), no_std)] + +use snowbridge_core::AgentId; +use xcm::VersionedLocation; + +sp_api::decl_runtime_apis! { + pub trait ControlApi + { + fn agent_id(location: VersionedLocation) -> Option; + } +} diff --git a/operator/pallets/system/src/api.rs b/operator/pallets/system/src/api.rs new file mode 100644 index 00000000..94b77787 --- /dev/null +++ b/operator/pallets/system/src/api.rs @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +//! Helpers for implementing runtime api + +use snowbridge_core::AgentId; +use xcm::{prelude::*, VersionedLocation}; + +use crate::{agent_id_of, Config}; + +pub fn agent_id(location: VersionedLocation) -> Option +where + Runtime: Config, +{ + let location: Location = location.try_into().ok()?; + agent_id_of::(&location).ok() +} diff --git a/operator/pallets/system/src/benchmarking.rs b/operator/pallets/system/src/benchmarking.rs new file mode 100644 index 00000000..2e2f7494 --- /dev/null +++ b/operator/pallets/system/src/benchmarking.rs @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +//! Benchmarking setup for pallet-template +use super::*; + +#[allow(unused)] +use crate::Pallet as SnowbridgeControl; +use frame_benchmarking::v2::*; +use frame_system::RawOrigin; +use snowbridge_core::eth; +use snowbridge_outbound_queue_primitives::OperatingMode; +use sp_runtime::SaturatedConversion; +use xcm::prelude::*; + +#[benchmarks] +mod benchmarks { + use super::*; + + #[benchmark] + fn upgrade() -> Result<(), BenchmarkError> { + let impl_address = H160::repeat_byte(1); + let impl_code_hash = H256::repeat_byte(1); + + // Assume 256 bytes passed to initializer + let params: Vec = (0..256).map(|_| 1u8).collect(); + + #[extrinsic_call] + _( + RawOrigin::Root, + impl_address, + impl_code_hash, + Some(Initializer { + params, + maximum_required_gas: 100000, + }), + ); + + Ok(()) + } + + #[benchmark] + fn set_operating_mode() -> Result<(), BenchmarkError> { + #[extrinsic_call] + _(RawOrigin::Root, OperatingMode::RejectingOutboundMessages); + + Ok(()) + } + + #[benchmark] + fn set_pricing_parameters() -> Result<(), BenchmarkError> { + let params = T::DefaultPricingParameters::get(); + + #[extrinsic_call] + _(RawOrigin::Root, params); + + Ok(()) + } + + #[benchmark] + fn set_token_transfer_fees() -> Result<(), BenchmarkError> { + #[extrinsic_call] + _(RawOrigin::Root, 1, 1, eth(1)); + + Ok(()) + } + + #[benchmark] + fn register_token() -> Result<(), BenchmarkError> { + let caller: T::AccountId = whitelisted_caller(); + + let amount: BalanceOf = (10_000_000_000_000_u128) + .saturated_into::() + .saturated_into(); + + T::Token::mint_into(&caller, amount)?; + + let relay_token_asset_id: Location = Location::parent(); + let asset = Box::new(VersionedLocation::from(relay_token_asset_id)); + let asset_metadata = AssetMetadata { + name: "wnd".as_bytes().to_vec().try_into().unwrap(), + symbol: "wnd".as_bytes().to_vec().try_into().unwrap(), + decimals: 12, + }; + + #[extrinsic_call] + _(RawOrigin::Root, asset, asset_metadata); + + Ok(()) + } + + impl_benchmark_test_suite!( + SnowbridgeControl, + crate::mock::new_test_ext(true), + crate::mock::Test + ); +} diff --git a/operator/pallets/system/src/lib.rs b/operator/pallets/system/src/lib.rs new file mode 100644 index 00000000..20b37a37 --- /dev/null +++ b/operator/pallets/system/src/lib.rs @@ -0,0 +1,566 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +//! Governance API for controlling the Ethereum side of the bridge +//! +//! # Extrinsics +//! +//! ## Governance +//! +//! Only Polkadot governance itself can call these extrinsics. Delivery fees are waived. +//! +//! * [`Call::upgrade`]`: Upgrade the gateway contract +//! * [`Call::set_operating_mode`]: Update the operating mode of the gateway contract +//! +//! ## Polkadot-native tokens on Ethereum +//! +//! Tokens deposited on AssetHub pallet can be bridged to Ethereum as wrapped ERC20 tokens. As a +//! prerequisite, the token should be registered first. +//! +//! * [`Call::register_token`]: Register a token location as a wrapped ERC20 contract on Ethereum. +#![cfg_attr(not(feature = "std"), no_std)] +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod tests; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; +pub mod migration; + +pub mod api; +pub mod weights; +pub use weights::*; + +use frame_support::{ + pallet_prelude::*, + traits::{ + fungible::{Inspect, Mutate}, + tokens::Preservation, + Contains, EnsureOrigin, + }, +}; +use frame_system::pallet_prelude::*; +use snowbridge_core::{ + meth, AgentId, AssetMetadata, Channel, ChannelId, ParaId, + PricingParameters as PricingParametersRecord, TokenId, TokenIdOf, PRIMARY_GOVERNANCE_CHANNEL, + SECONDARY_GOVERNANCE_CHANNEL, +}; +use snowbridge_outbound_queue_primitives::{ + v1::{Command, Initializer, Message, SendMessage}, + OperatingMode, SendError, +}; +use sp_core::{RuntimeDebug, H160, H256}; +use sp_io::hashing::blake2_256; +use sp_runtime::{traits::MaybeEquivalence, DispatchError, SaturatedConversion}; +use sp_std::prelude::*; +use xcm::prelude::*; +use xcm_executor::traits::ConvertLocation; + +#[cfg(feature = "runtime-benchmarks")] +use frame_support::traits::OriginTrait; + +pub use pallet::*; + +pub type BalanceOf = + <::Token as Inspect<::AccountId>>::Balance; +pub type AccountIdOf = ::AccountId; +pub type PricingParametersOf = PricingParametersRecord>; + +/// Hash the location to produce an agent id +pub fn agent_id_of(location: &Location) -> Result { + T::AgentIdOf::convert_location(location).ok_or(Error::::LocationConversionFailed.into()) +} + +#[cfg(feature = "runtime-benchmarks")] +pub trait BenchmarkHelper +where + O: OriginTrait, +{ + fn make_xcm_origin(location: Location) -> O; +} + +/// Whether a fee should be withdrawn to an account for sending an outbound message +#[derive(Clone, PartialEq, RuntimeDebug)] +pub enum PaysFee +where + T: Config, +{ + /// Fully charge includes (local + remote fee) + Yes(AccountIdOf), + /// Partially charge includes local fee only + Partial(AccountIdOf), + /// No charge + No, +} + +#[frame_support::pallet] +pub mod pallet { + use frame_support::dispatch::PostDispatchInfo; + use snowbridge_core::StaticLookup; + use sp_core::U256; + + use super::*; + + #[pallet::pallet] + #[pallet::storage_version(migration::STORAGE_VERSION)] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// Send messages to Ethereum + type OutboundQueue: SendMessage>; + + /// Origin check for XCM locations that can create agents + type SiblingOrigin: EnsureOrigin; + + /// Converts Location to AgentId + type AgentIdOf: ConvertLocation; + + /// Token reserved for control operations + type Token: Mutate; + + /// TreasuryAccount to collect fees + #[pallet::constant] + type TreasuryAccount: Get; + + /// Number of decimal places of local currency + type DefaultPricingParameters: Get>; + + /// Cost of delivering a message from Ethereum + #[pallet::constant] + type InboundDeliveryCost: Get>; + + type WeightInfo: WeightInfo; + + /// This chain's Universal Location. + type UniversalLocation: Get; + + // The bridges configured Ethereum location + type EthereumLocation: Get; + + #[cfg(feature = "runtime-benchmarks")] + type Helper: BenchmarkHelper; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// An Upgrade message was sent to the Gateway + Upgrade { + impl_address: H160, + impl_code_hash: H256, + initializer_params_hash: Option, + }, + /// An CreateAgent message was sent to the Gateway + CreateAgent { + location: Box, + agent_id: AgentId, + }, + /// An CreateChannel message was sent to the Gateway + CreateChannel { + channel_id: ChannelId, + agent_id: AgentId, + }, + /// An UpdateChannel message was sent to the Gateway + UpdateChannel { + channel_id: ChannelId, + mode: OperatingMode, + }, + /// An SetOperatingMode message was sent to the Gateway + SetOperatingMode { + mode: OperatingMode, + }, + /// An TransferNativeFromAgent message was sent to the Gateway + TransferNativeFromAgent { + agent_id: AgentId, + recipient: H160, + amount: u128, + }, + /// A SetTokenTransferFees message was sent to the Gateway + SetTokenTransferFees { + create_asset_xcm: u128, + transfer_asset_xcm: u128, + register_token: U256, + }, + PricingParametersChanged { + params: PricingParametersOf, + }, + /// Register Polkadot-native token as a wrapped ERC20 token on Ethereum + RegisterToken { + /// Location of Polkadot-native token + location: VersionedLocation, + /// ID of Polkadot-native token on Ethereum + foreign_token_id: H256, + }, + } + + #[pallet::error] + pub enum Error { + LocationConversionFailed, + AgentAlreadyCreated, + NoAgent, + ChannelAlreadyCreated, + NoChannel, + UnsupportedLocationVersion, + InvalidLocation, + Send(SendError), + InvalidTokenTransferFees, + InvalidPricingParameters, + InvalidUpgradeParameters, + } + + /// The set of registered agents + #[pallet::storage] + #[pallet::getter(fn agents)] + pub type Agents = StorageMap<_, Twox64Concat, AgentId, (), OptionQuery>; + + /// The set of registered channels + #[pallet::storage] + #[pallet::getter(fn channels)] + pub type Channels = StorageMap<_, Twox64Concat, ChannelId, Channel, OptionQuery>; + + #[pallet::storage] + #[pallet::getter(fn parameters)] + pub type PricingParameters = + StorageValue<_, PricingParametersOf, ValueQuery, T::DefaultPricingParameters>; + + /// Lookup table for foreign token ID to native location relative to ethereum + #[pallet::storage] + pub type ForeignToNativeId = + StorageMap<_, Blake2_128Concat, TokenId, xcm::v5::Location, OptionQuery>; + + /// Lookup table for native location relative to ethereum to foreign token ID + #[pallet::storage] + pub type NativeToForeignId = + StorageMap<_, Blake2_128Concat, xcm::v5::Location, TokenId, OptionQuery>; + + #[pallet::genesis_config] + #[derive(frame_support::DefaultNoBound)] + pub struct GenesisConfig { + // Own parachain id + pub para_id: ParaId, + // AssetHub's parachain id + pub asset_hub_para_id: ParaId, + #[serde(skip)] + pub _config: PhantomData, + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + Pallet::::initialize(self.para_id, self.asset_hub_para_id).expect("infallible; qed"); + } + } + + #[pallet::call] + impl Pallet { + /// Sends command to the Gateway contract to upgrade itself with a new implementation + /// contract + /// + /// Fee required: No + /// + /// - `origin`: Must be `Root`. + /// - `impl_address`: The address of the implementation contract. + /// - `impl_code_hash`: The codehash of the implementation contract. + /// - `initializer`: Optionally call an initializer on the implementation contract. + #[pallet::call_index(0)] + #[pallet::weight((T::WeightInfo::upgrade(), DispatchClass::Operational))] + pub fn upgrade( + origin: OriginFor, + impl_address: H160, + impl_code_hash: H256, + initializer: Option, + ) -> DispatchResult { + ensure_root(origin)?; + + ensure!( + !impl_address.eq(&H160::zero()) && !impl_code_hash.eq(&H256::zero()), + Error::::InvalidUpgradeParameters + ); + + let initializer_params_hash: Option = initializer + .as_ref() + .map(|i| H256::from(blake2_256(i.params.as_ref()))); + let command = Command::Upgrade { + impl_address, + impl_code_hash, + initializer, + }; + Self::send(PRIMARY_GOVERNANCE_CHANNEL, command, PaysFee::::No)?; + + Self::deposit_event(Event::::Upgrade { + impl_address, + impl_code_hash, + initializer_params_hash, + }); + Ok(()) + } + + /// Sends a message to the Gateway contract to change its operating mode + /// + /// Fee required: No + /// + /// - `origin`: Must be `Location` + #[pallet::call_index(1)] + #[pallet::weight((T::WeightInfo::set_operating_mode(), DispatchClass::Operational))] + pub fn set_operating_mode(origin: OriginFor, mode: OperatingMode) -> DispatchResult { + ensure_root(origin)?; + + let command = Command::SetOperatingMode { mode }; + Self::send(PRIMARY_GOVERNANCE_CHANNEL, command, PaysFee::::No)?; + + Self::deposit_event(Event::::SetOperatingMode { mode }); + Ok(()) + } + + /// Set pricing parameters on both sides of the bridge + /// + /// Fee required: No + /// + /// - `origin`: Must be root + #[pallet::call_index(2)] + #[pallet::weight((T::WeightInfo::set_pricing_parameters(), DispatchClass::Operational))] + pub fn set_pricing_parameters( + origin: OriginFor, + params: PricingParametersOf, + ) -> DispatchResult { + ensure_root(origin)?; + params + .validate() + .map_err(|_| Error::::InvalidPricingParameters)?; + PricingParameters::::put(params.clone()); + + let command = Command::SetPricingParameters { + exchange_rate: params.exchange_rate.into(), + delivery_cost: T::InboundDeliveryCost::get().saturated_into::(), + multiplier: params.multiplier.into(), + }; + Self::send(PRIMARY_GOVERNANCE_CHANNEL, command, PaysFee::::No)?; + + Self::deposit_event(Event::PricingParametersChanged { params }); + Ok(()) + } + + /// Sends a message to the Gateway contract to update fee related parameters for + /// token transfers. + /// + /// Privileged. Can only be called by root. + /// + /// Fee required: No + /// + /// - `origin`: Must be root + /// - `create_asset_xcm`: The XCM execution cost for creating a new asset class on AssetHub, + /// in DOT + /// - `transfer_asset_xcm`: The XCM execution cost for performing a reserve transfer on + /// AssetHub, in DOT + /// - `register_token`: The Ether fee for registering a new token, to discourage spamming + #[pallet::call_index(9)] + #[pallet::weight((T::WeightInfo::set_token_transfer_fees(), DispatchClass::Operational))] + pub fn set_token_transfer_fees( + origin: OriginFor, + create_asset_xcm: u128, + transfer_asset_xcm: u128, + register_token: U256, + ) -> DispatchResult { + ensure_root(origin)?; + + // Basic validation of new costs. Particularly for token registration, we want to ensure + // its relatively expensive to discourage spamming. Like at least 100 USD. + ensure!( + create_asset_xcm > 0 && transfer_asset_xcm > 0 && register_token > meth(100), + Error::::InvalidTokenTransferFees + ); + + let command = Command::SetTokenTransferFees { + create_asset_xcm, + transfer_asset_xcm, + register_token, + }; + Self::send(PRIMARY_GOVERNANCE_CHANNEL, command, PaysFee::::No)?; + + Self::deposit_event(Event::::SetTokenTransferFees { + create_asset_xcm, + transfer_asset_xcm, + register_token, + }); + Ok(()) + } + + /// Registers a Polkadot-native token as a wrapped ERC20 token on Ethereum. + /// Privileged. Can only be called by root. + /// + /// Fee required: No + /// + /// - `origin`: Must be root + /// - `location`: Location of the asset (relative to this chain) + /// - `metadata`: Metadata to include in the instantiated ERC20 contract on Ethereum + #[pallet::call_index(10)] + #[pallet::weight(T::WeightInfo::register_token())] + pub fn register_token( + origin: OriginFor, + location: Box, + metadata: AssetMetadata, + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + + let location: Location = (*location) + .try_into() + .map_err(|_| Error::::UnsupportedLocationVersion)?; + + Self::do_register_token(&location, metadata, PaysFee::::No)?; + + Ok(PostDispatchInfo { + actual_weight: Some(T::WeightInfo::register_token()), + pays_fee: Pays::No, + }) + } + } + + impl Pallet { + /// Send `command` to the Gateway on the Channel identified by `channel_id` + fn send(channel_id: ChannelId, command: Command, pays_fee: PaysFee) -> DispatchResult { + let message = Message { + id: None, + channel_id, + command, + }; + let (ticket, fee) = + T::OutboundQueue::validate(&message).map_err(|err| Error::::Send(err))?; + + let payment = match pays_fee { + PaysFee::Yes(account) => Some((account, fee.total())), + PaysFee::Partial(account) => Some((account, fee.local)), + PaysFee::No => None, + }; + + if let Some((payer, fee)) = payment { + T::Token::transfer( + &payer, + &T::TreasuryAccount::get(), + fee, + Preservation::Preserve, + )?; + } + + T::OutboundQueue::deliver(ticket).map_err(|err| Error::::Send(err))?; + Ok(()) + } + + /// Initializes agents and channels. + pub fn initialize(para_id: ParaId, asset_hub_para_id: ParaId) -> Result<(), DispatchError> { + // Asset Hub + let asset_hub_location: Location = + ParentThen(Parachain(asset_hub_para_id.into()).into()).into(); + let asset_hub_agent_id = agent_id_of::(&asset_hub_location)?; + let asset_hub_channel_id: ChannelId = asset_hub_para_id.into(); + Agents::::insert(asset_hub_agent_id, ()); + Channels::::insert( + asset_hub_channel_id, + Channel { + agent_id: asset_hub_agent_id, + para_id: asset_hub_para_id, + }, + ); + + // Governance channels + let bridge_hub_agent_id = agent_id_of::(&Location::here())?; + // Agent for BridgeHub + Agents::::insert(bridge_hub_agent_id, ()); + + // Primary governance channel + Channels::::insert( + PRIMARY_GOVERNANCE_CHANNEL, + Channel { + agent_id: bridge_hub_agent_id, + para_id, + }, + ); + + // Secondary governance channel + Channels::::insert( + SECONDARY_GOVERNANCE_CHANNEL, + Channel { + agent_id: bridge_hub_agent_id, + para_id, + }, + ); + + Ok(()) + } + + /// Checks if the pallet has been initialized. + pub(crate) fn is_initialized() -> bool { + let primary_exists = Channels::::contains_key(PRIMARY_GOVERNANCE_CHANNEL); + let secondary_exists = Channels::::contains_key(SECONDARY_GOVERNANCE_CHANNEL); + primary_exists && secondary_exists + } + + pub(crate) fn do_register_token( + location: &Location, + metadata: AssetMetadata, + pays_fee: PaysFee, + ) -> Result<(), DispatchError> { + let ethereum_location = T::EthereumLocation::get(); + // reanchor to Ethereum context + let location = location + .clone() + .reanchored(ðereum_location, &T::UniversalLocation::get()) + .map_err(|_| Error::::LocationConversionFailed)?; + + let token_id = TokenIdOf::convert_location(&location) + .ok_or(Error::::LocationConversionFailed)?; + + if !ForeignToNativeId::::contains_key(token_id) { + NativeToForeignId::::insert(location.clone(), token_id); + ForeignToNativeId::::insert(token_id, location.clone()); + } + + let command = Command::RegisterForeignToken { + token_id, + name: metadata.name.into_inner(), + symbol: metadata.symbol.into_inner(), + decimals: metadata.decimals, + }; + Self::send(SECONDARY_GOVERNANCE_CHANNEL, command, pays_fee)?; + + Self::deposit_event(Event::::RegisterToken { + location: location.clone().into(), + foreign_token_id: token_id, + }); + + Ok(()) + } + } + + impl StaticLookup for Pallet { + type Source = ChannelId; + type Target = Channel; + fn lookup(channel_id: Self::Source) -> Option { + Channels::::get(channel_id) + } + } + + impl Contains for Pallet { + fn contains(channel_id: &ChannelId) -> bool { + Channels::::get(channel_id).is_some() + } + } + + impl Get> for Pallet { + fn get() -> PricingParametersOf { + PricingParameters::::get() + } + } + + impl MaybeEquivalence for Pallet { + fn convert(foreign_id: &TokenId) -> Option { + ForeignToNativeId::::get(foreign_id) + } + fn convert_back(location: &Location) -> Option { + NativeToForeignId::::get(location) + } + } +} diff --git a/operator/pallets/system/src/migration.rs b/operator/pallets/system/src/migration.rs new file mode 100644 index 00000000..7a6aacd0 --- /dev/null +++ b/operator/pallets/system/src/migration.rs @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +//! Governance API for controlling the Ethereum side of the bridge +use super::*; +use frame_support::{ + migrations::VersionedMigration, + pallet_prelude::*, + traits::{OnRuntimeUpgrade, UncheckedOnRuntimeUpgrade}, + weights::Weight, +}; +use log; +use sp_std::marker::PhantomData; + +#[cfg(feature = "try-runtime")] +use sp_runtime::TryRuntimeError; + +const LOG_TARGET: &str = "ethereum_system::migration"; + +/// The in-code storage version. +pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + +pub mod v0 { + use super::*; + + pub struct InitializeOnUpgrade( + PhantomData<(T, BridgeHubParaId, AssetHubParaId)>, + ); + + impl OnRuntimeUpgrade + for InitializeOnUpgrade + where + T: Config, + BridgeHubParaId: Get, + AssetHubParaId: Get, + { + fn on_runtime_upgrade() -> Weight { + if !Pallet::::is_initialized() { + Pallet::::initialize( + BridgeHubParaId::get().into(), + AssetHubParaId::get().into(), + ) + .expect("infallible; qed"); + log::info!( + target: LOG_TARGET, + "Ethereum system initialized." + ); + T::DbWeight::get().reads_writes(2, 5) + } else { + log::info!( + target: LOG_TARGET, + "Ethereum system already initialized. Skipping." + ); + T::DbWeight::get().reads(2) + } + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, TryRuntimeError> { + if !Pallet::::is_initialized() { + log::info!( + target: LOG_TARGET, + "Agents and channels not initialized. Initialization will run." + ); + } else { + log::info!( + target: LOG_TARGET, + "Agents and channels are initialized. Initialization will not run." + ); + } + Ok(vec![]) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(_: Vec) -> Result<(), TryRuntimeError> { + frame_support::ensure!( + Pallet::::is_initialized(), + "Agents and channels were not initialized." + ); + Ok(()) + } + } +} + +pub mod v1 { + use super::*; + + #[cfg(feature = "try-runtime")] + use sp_core::U256; + + /// Descreases the fee per gas. + pub struct FeePerGasMigration(PhantomData); + + #[cfg(feature = "try-runtime")] + impl FeePerGasMigration + where + T: Config, + { + /// Calculate the fee required to pay for gas on Ethereum. + fn calculate_remote_fee_v1(params: &PricingParametersOf) -> U256 { + use snowbridge_outbound_queue_primitives::v1::{ + AgentExecuteCommand, Command, ConstantGasMeter, GasMeter, + }; + let command = Command::AgentExecute { + agent_id: H256::zero(), + command: AgentExecuteCommand::TransferToken { + token: H160::zero(), + recipient: H160::zero(), + amount: 0, + }, + }; + let gas_used_at_most = ConstantGasMeter::maximum_gas_used_at_most(&command); + params + .fee_per_gas + .saturating_mul(gas_used_at_most.into()) + .saturating_add(params.rewards.remote) + } + + /// Calculate the fee required to pay for gas on Ethereum. + fn calculate_remote_fee_v2(params: &PricingParametersOf) -> U256 { + use snowbridge_outbound_queue_primitives::v2::{Command, ConstantGasMeter, GasMeter}; + let command = Command::UnlockNativeToken { + token: H160::zero(), + recipient: H160::zero(), + amount: 0, + }; + let gas_used_at_most = ConstantGasMeter::maximum_dispatch_gas_used_at_most(&command); + params + .fee_per_gas + .saturating_mul(gas_used_at_most.into()) + .saturating_add(params.rewards.remote) + } + } + + /// The percentage gas increase. We must adjust the fee per gas by this percentage. + const GAS_INCREASE_PERCENTAGE: u64 = 70; + + impl UncheckedOnRuntimeUpgrade for FeePerGasMigration + where + T: Config, + { + fn on_runtime_upgrade() -> Weight { + let mut params = Pallet::::parameters(); + + let old_fee_per_gas = params.fee_per_gas; + + // Fee per gas can be set based on a percentage in order to keep the remote fee the + // same. + params.fee_per_gas = params.fee_per_gas * GAS_INCREASE_PERCENTAGE / 100; + + log::info!( + target: LOG_TARGET, + "Fee per gas migrated from {old_fee_per_gas:?} to {0:?}.", + params.fee_per_gas, + ); + + PricingParameters::::put(params); + T::DbWeight::get().reads_writes(1, 1) + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, TryRuntimeError> { + use codec::Encode; + + let params = Pallet::::parameters(); + let remote_fee_v1 = Self::calculate_remote_fee_v1(¶ms); + let remote_fee_v2 = Self::calculate_remote_fee_v2(¶ms); + + log::info!( + target: LOG_TARGET, + "Pre fee per gas migration: pricing parameters = {params:?}, remote_fee_v1 = {remote_fee_v1:?}, remote_fee_v2 = {remote_fee_v2:?}" + ); + Ok((params, remote_fee_v1, remote_fee_v2).encode()) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(state: Vec) -> Result<(), TryRuntimeError> { + use codec::Decode; + + let (old_params, old_remote_fee_v1, old_remote_fee_v2): ( + PricingParametersOf, + U256, + U256, + ) = Decode::decode(&mut &state[..]).unwrap(); + + let params = Pallet::::parameters(); + ensure!( + old_params.exchange_rate == params.exchange_rate, + "Exchange rate unchanged." + ); + ensure!(old_params.rewards == params.rewards, "Rewards unchanged."); + ensure!( + (old_params.fee_per_gas * GAS_INCREASE_PERCENTAGE / 100) == params.fee_per_gas, + "Fee per gas decreased." + ); + ensure!( + old_params.multiplier == params.multiplier, + "Multiplier unchanged." + ); + + let remote_fee_v1 = Self::calculate_remote_fee_v1(¶ms); + let remote_fee_v2 = Self::calculate_remote_fee_v2(¶ms); + ensure!( + remote_fee_v1 <= old_remote_fee_v1, + "The v1 remote fee can cover the cost of the previous fee." + ); + ensure!( + remote_fee_v2 <= old_remote_fee_v2, + "The v2 remote fee can cover the cost of the previous fee." + ); + + log::info!( + target: LOG_TARGET, + "Post fee per gas migration: pricing parameters = {params:?} remote_fee_v1 = {remote_fee_v1:?} remote_fee_v2 = {remote_fee_v2:?}" + ); + Ok(()) + } + } +} + +/// Run the migration of the gas price and increment the pallet version so it cannot be re-run. +pub type FeePerGasMigrationV0ToV1 = VersionedMigration< + 0, + 1, + v1::FeePerGasMigration, + Pallet, + ::DbWeight, +>; diff --git a/operator/pallets/system/src/mock.rs b/operator/pallets/system/src/mock.rs new file mode 100644 index 00000000..d3572eaf --- /dev/null +++ b/operator/pallets/system/src/mock.rs @@ -0,0 +1,254 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +use crate as snowbridge_system; +use frame_support::{ + derive_impl, parameter_types, + traits::{tokens::fungible::Mutate, ConstU128, ConstU8}, + weights::IdentityFee, + PalletId, +}; +use sp_core::H256; +use xcm_executor::traits::ConvertLocation; + +use snowbridge_core::{ + gwei, meth, sibling_sovereign_account, AgentId, AllowSiblingsOnly, ParaId, PricingParameters, + Rewards, +}; +use snowbridge_outbound_queue_primitives::v1::ConstantGasMeter; +use sp_runtime::{ + traits::{AccountIdConversion, BlakeTwo256, IdentityLookup, Keccak256}, + AccountId32, BuildStorage, FixedU128, +}; +use xcm::prelude::*; + +#[cfg(feature = "runtime-benchmarks")] +use crate::BenchmarkHelper; + +type Block = frame_system::mocking::MockBlock; +type Balance = u128; + +pub type AccountId = AccountId32; + +// A stripped-down version of pallet-xcm that only inserts an XCM origin into the runtime +#[allow(dead_code)] +#[frame_support::pallet] +mod pallet_xcm_origin { + use frame_support::{ + pallet_prelude::*, + traits::{Contains, OriginTrait}, + }; + use xcm::latest::prelude::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeOrigin: From + From<::RuntimeOrigin>; + } + + // Insert this custom Origin into the aggregate RuntimeOrigin + #[pallet::origin] + #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub struct Origin(pub Location); + + impl From for Origin { + fn from(location: Location) -> Origin { + Origin(location) + } + } + + /// `EnsureOrigin` implementation succeeding with a `Location` value to recognize and + /// filter the contained location + pub struct EnsureXcm(PhantomData); + impl, F: Contains> EnsureOrigin for EnsureXcm + where + for<'a> &'a O::PalletsOrigin: TryInto<&'a Origin>, + { + type Success = Location; + + fn try_origin(outer: O) -> Result { + match outer.caller().try_into() { + Ok(Origin(ref location)) if F::contains(location) => return Ok(location.clone()), + _ => (), + } + + Err(outer) + } + + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin() -> Result { + Ok(O::from(Origin(Location::new(1, [Parachain(2000)])))) + } + } +} + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + XcmOrigin: pallet_xcm_origin::{Pallet, Origin}, + OutboundQueue: snowbridge_pallet_outbound_queue::{Pallet, Call, Storage, Event}, + EthereumSystem: snowbridge_system, + MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} + } +); + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] +impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type RuntimeTask = RuntimeTask; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type RuntimeEvent = RuntimeEvent; + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type Nonce = u64; + type Block = Block; +} + +#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] +impl pallet_balances::Config for Test { + type Balance = Balance; + type ExistentialDeposit = ConstU128<1>; + type AccountStore = System; +} + +impl pallet_xcm_origin::Config for Test { + type RuntimeOrigin = RuntimeOrigin; +} + +parameter_types! { + pub const HeapSize: u32 = 32 * 1024; + pub const MaxStale: u32 = 32; + pub static ServiceWeight: Option = Some(Weight::from_parts(100, 100)); +} + +impl pallet_message_queue::Config for Test { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type MessageProcessor = OutboundQueue; + type Size = u32; + type QueueChangeHandler = (); + type HeapSize = HeapSize; + type MaxStale = MaxStale; + type ServiceWeight = ServiceWeight; + type IdleMaxServiceWeight = (); + type QueuePausedQuery = (); +} + +parameter_types! { + pub const MaxMessagePayloadSize: u32 = 1024; + pub const MaxMessagesPerBlock: u32 = 20; + pub const OwnParaId: ParaId = ParaId::new(1013); +} + +impl snowbridge_pallet_outbound_queue::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Hashing = Keccak256; + type MessageQueue = MessageQueue; + type Decimals = ConstU8<10>; + type MaxMessagePayloadSize = MaxMessagePayloadSize; + type MaxMessagesPerBlock = MaxMessagesPerBlock; + type GasMeter = ConstantGasMeter; + type Balance = u128; + type PricingParameters = EthereumSystem; + type Channels = EthereumSystem; + type WeightToFee = IdentityFee; + type WeightInfo = (); +} + +parameter_types! { + pub const SS58Prefix: u8 = 42; + pub const AnyNetwork: Option = None; + pub const RelayNetwork: Option = Some(NetworkId::Polkadot); + pub const RelayLocation: Location = Location::parent(); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(1013)].into(); + pub EthereumNetwork: NetworkId = NetworkId::Ethereum { chain_id: 11155111 }; + pub EthereumDestination: Location = Location::new(2,[GlobalConsensus(EthereumNetwork::get())]); +} + +pub const DOT: u128 = 10_000_000_000; + +parameter_types! { + pub TreasuryAccount: AccountId = PalletId(*b"py/trsry").into_account_truncating(); + pub Fee: u64 = 1000; + pub const InitialFunding: u128 = 1_000_000_000_000; + pub BridgeHubParaId: ParaId = ParaId::new(1002); + pub AssetHubParaId: ParaId = ParaId::new(1000); + pub TestParaId: u32 = 2000; + pub Parameters: PricingParameters = PricingParameters { + exchange_rate: FixedU128::from_rational(1, 400), + fee_per_gas: gwei(20), + rewards: Rewards { local: DOT, remote: meth(1) }, + multiplier: FixedU128::from_rational(4, 3) + }; + pub const InboundDeliveryCost: u128 = 1_000_000_000; +} + +#[cfg(feature = "runtime-benchmarks")] +impl BenchmarkHelper for () { + fn make_xcm_origin(location: Location) -> RuntimeOrigin { + RuntimeOrigin::from(pallet_xcm_origin::Origin(location)) + } +} + +impl crate::Config for Test { + type RuntimeEvent = RuntimeEvent; + type OutboundQueue = OutboundQueue; + type SiblingOrigin = pallet_xcm_origin::EnsureXcm; + type AgentIdOf = snowbridge_core::AgentIdOf; + type TreasuryAccount = TreasuryAccount; + type Token = Balances; + type DefaultPricingParameters = Parameters; + type WeightInfo = (); + type InboundDeliveryCost = InboundDeliveryCost; + type UniversalLocation = UniversalLocation; + type EthereumLocation = EthereumDestination; + #[cfg(feature = "runtime-benchmarks")] + type Helper = (); +} + +// Build genesis storage according to the mock runtime. +pub fn new_test_ext(genesis_build: bool) -> sp_io::TestExternalities { + let mut storage = frame_system::GenesisConfig::::default() + .build_storage() + .unwrap(); + + if genesis_build { + crate::GenesisConfig:: { + para_id: OwnParaId::get(), + asset_hub_para_id: AssetHubParaId::get(), + _config: Default::default(), + } + .assimilate_storage(&mut storage) + .unwrap(); + } + + let mut ext: sp_io::TestExternalities = storage.into(); + let initial_amount = InitialFunding::get(); + let test_para_id = TestParaId::get(); + let sovereign_account = sibling_sovereign_account::(test_para_id.into()); + let treasury_account = TreasuryAccount::get(); + ext.execute_with(|| { + System::set_block_number(1); + Balances::mint_into(&AccountId32::from([0; 32]), initial_amount).unwrap(); + Balances::mint_into(&sovereign_account, initial_amount).unwrap(); + Balances::mint_into(&treasury_account, initial_amount).unwrap(); + }); + ext +} + +// Test helpers + +pub fn make_agent_id(location: Location) -> AgentId { + ::AgentIdOf::convert_location(&location) + .expect("convert location") +} diff --git a/operator/pallets/system/src/tests.rs b/operator/pallets/system/src/tests.rs new file mode 100644 index 00000000..c0ef20a9 --- /dev/null +++ b/operator/pallets/system/src/tests.rs @@ -0,0 +1,330 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +use crate::{mock::*, *}; +use frame_support::{assert_noop, assert_ok}; +use hex_literal::hex; +use snowbridge_core::eth; +use sp_core::H256; +use sp_runtime::{AccountId32, DispatchError::BadOrigin}; + +#[test] +fn test_agent_for_here() { + new_test_ext(true).execute_with(|| { + let origin_location = Location::here(); + let agent_id = make_agent_id(origin_location); + assert_eq!( + agent_id, + hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(), + ) + }); +} + +#[test] +fn upgrade_as_root() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::root(); + let address: H160 = [1_u8; 20].into(); + let code_hash: H256 = [1_u8; 32].into(); + + assert_ok!(EthereumSystem::upgrade(origin, address, code_hash, None)); + + System::assert_last_event(RuntimeEvent::EthereumSystem(crate::Event::Upgrade { + impl_address: address, + impl_code_hash: code_hash, + initializer_params_hash: None, + })); + }); +} + +#[test] +fn upgrade_as_signed_fails() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::signed(AccountId32::new([0; 32])); + let address: H160 = Default::default(); + let code_hash: H256 = Default::default(); + + assert_noop!( + EthereumSystem::upgrade(origin, address, code_hash, None), + BadOrigin + ); + }); +} + +#[test] +fn upgrade_with_params() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::root(); + let address: H160 = [1_u8; 20].into(); + let code_hash: H256 = [1_u8; 32].into(); + let initializer: Option = Some(Initializer { + params: [0; 256].into(), + maximum_required_gas: 10000, + }); + assert_ok!(EthereumSystem::upgrade( + origin, + address, + code_hash, + initializer + )); + }); +} + +#[test] +fn set_operating_mode() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::root(); + let mode = OperatingMode::RejectingOutboundMessages; + + assert_ok!(EthereumSystem::set_operating_mode(origin, mode)); + + System::assert_last_event(RuntimeEvent::EthereumSystem( + crate::Event::SetOperatingMode { mode }, + )); + }); +} + +#[test] +fn set_operating_mode_as_signed_fails() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::signed([14; 32].into()); + let mode = OperatingMode::RejectingOutboundMessages; + + assert_noop!(EthereumSystem::set_operating_mode(origin, mode), BadOrigin); + }); +} + +#[test] +fn set_pricing_parameters() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::root(); + let mut params = Parameters::get(); + params.rewards.local = 7; + + assert_ok!(EthereumSystem::set_pricing_parameters(origin, params)); + + assert_eq!(PricingParameters::::get().rewards.local, 7); + }); +} + +#[test] +fn set_pricing_parameters_as_signed_fails() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::signed([14; 32].into()); + let params = Parameters::get(); + + assert_noop!( + EthereumSystem::set_pricing_parameters(origin, params), + BadOrigin + ); + }); +} + +#[test] +fn set_pricing_parameters_invalid() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::root(); + let mut params = Parameters::get(); + params.rewards.local = 0; + + assert_noop!( + EthereumSystem::set_pricing_parameters(origin.clone(), params), + Error::::InvalidPricingParameters + ); + + let mut params = Parameters::get(); + params.exchange_rate = 0u128.into(); + assert_noop!( + EthereumSystem::set_pricing_parameters(origin.clone(), params), + Error::::InvalidPricingParameters + ); + params = Parameters::get(); + params.fee_per_gas = sp_core::U256::zero(); + assert_noop!( + EthereumSystem::set_pricing_parameters(origin.clone(), params), + Error::::InvalidPricingParameters + ); + params = Parameters::get(); + params.rewards.local = 0; + assert_noop!( + EthereumSystem::set_pricing_parameters(origin.clone(), params), + Error::::InvalidPricingParameters + ); + params = Parameters::get(); + params.rewards.remote = sp_core::U256::zero(); + assert_noop!( + EthereumSystem::set_pricing_parameters(origin, params), + Error::::InvalidPricingParameters + ); + }); +} + +#[test] +fn set_token_transfer_fees() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::root(); + + assert_ok!(EthereumSystem::set_token_transfer_fees( + origin, + 1, + 1, + eth(1) + )); + }); +} + +#[test] +fn set_token_transfer_fees_root_only() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::signed([14; 32].into()); + + assert_noop!( + EthereumSystem::set_token_transfer_fees(origin, 1, 1, 1.into()), + BadOrigin + ); + }); +} + +#[test] +fn set_token_transfer_fees_invalid() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::root(); + + assert_noop!( + EthereumSystem::set_token_transfer_fees(origin, 0, 0, 0.into()), + Error::::InvalidTokenTransferFees + ); + }); +} + +#[test] +fn genesis_build_initializes_correctly() { + new_test_ext(true).execute_with(|| { + assert!(EthereumSystem::is_initialized(), "Ethereum uninitialized."); + }); +} + +#[test] +fn no_genesis_build_is_uninitialized() { + new_test_ext(false).execute_with(|| { + assert!(!EthereumSystem::is_initialized(), "Ethereum initialized."); + }); +} + +#[test] +fn register_token_with_signed_yields_bad_origin() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::signed([14; 32].into()); + let location = Location::new(1, [Parachain(2000)]); + let versioned_location: Box = Box::new(location.clone().into()); + assert_noop!( + EthereumSystem::register_token(origin, versioned_location, Default::default()), + BadOrigin + ); + }); +} + +pub struct RegisterTokenTestCase { + /// Input: Location of Polkadot-native token relative to BH + pub native: Location, + /// Output: Reanchored, canonicalized location + pub reanchored: Location, + /// Output: Stable hash of reanchored location + pub foreign: TokenId, +} + +#[test] +fn register_all_tokens_succeeds() { + let test_cases = vec![ + // DOT + RegisterTokenTestCase { + native: Location::parent(), + reanchored: Location::new(1, GlobalConsensus(Polkadot)), + foreign: hex!("4e241583d94b5d48a27a22064cd49b2ed6f5231d2d950e432f9b7c2e0ade52b2") + .into(), + }, + // GLMR (Some Polkadot parachain currency) + RegisterTokenTestCase { + native: Location::new(1, [Parachain(2004)]), + reanchored: Location::new(1, [GlobalConsensus(Polkadot), Parachain(2004)]), + foreign: hex!("34c08fc90409b6924f0e8eabb7c2aaa0c749e23e31adad9f6d217b577737fafb") + .into(), + }, + // USDT + RegisterTokenTestCase { + native: Location::new(1, [Parachain(1000), PalletInstance(50), GeneralIndex(1984)]), + reanchored: Location::new( + 1, + [ + GlobalConsensus(Polkadot), + Parachain(1000), + PalletInstance(50), + GeneralIndex(1984), + ], + ), + foreign: hex!("14b0579be12d7d7f9971f1d4b41f0e88384b9b74799b0150d4aa6cd01afb4444") + .into(), + }, + // KSM + RegisterTokenTestCase { + native: Location::new(2, [GlobalConsensus(Kusama)]), + reanchored: Location::new(1, [GlobalConsensus(Kusama)]), + foreign: hex!("03b6054d0c576dd8391e34e1609cf398f68050c23009d19ce93c000922bcd852") + .into(), + }, + // KAR (Some Kusama parachain currency) + RegisterTokenTestCase { + native: Location::new(2, [GlobalConsensus(Kusama), Parachain(2000)]), + reanchored: Location::new(1, [GlobalConsensus(Kusama), Parachain(2000)]), + foreign: hex!("d3e39ad6ea4cee68c9741181e94098823b2ea34a467577d0875c036f0fce5be0") + .into(), + }, + ]; + for tc in test_cases.iter() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::root(); + let versioned_location: VersionedLocation = tc.native.clone().into(); + + assert_ok!(EthereumSystem::register_token( + origin, + Box::new(versioned_location), + Default::default() + )); + + assert_eq!( + NativeToForeignId::::get(tc.reanchored.clone()), + Some(tc.foreign) + ); + assert_eq!( + ForeignToNativeId::::get(tc.foreign), + Some(tc.reanchored.clone()) + ); + + System::assert_last_event(RuntimeEvent::EthereumSystem(Event::::RegisterToken { + location: tc.reanchored.clone().into(), + foreign_token_id: tc.foreign, + })); + }); + } +} + +#[test] +fn register_ethereum_native_token_fails() { + new_test_ext(true).execute_with(|| { + let origin = RuntimeOrigin::root(); + let location = Location::new( + 2, + [ + GlobalConsensus(Ethereum { chain_id: 11155111 }), + AccountKey20 { + network: None, + key: hex!("87d1f7fdfEe7f651FaBc8bFCB6E086C278b77A7d"), + }, + ], + ); + let versioned_location: Box = Box::new(location.clone().into()); + assert_noop!( + EthereumSystem::register_token(origin, versioned_location, Default::default()), + Error::::LocationConversionFailed + ); + }); +} diff --git a/operator/pallets/system/src/weights.rs b/operator/pallets/system/src/weights.rs new file mode 100644 index 00000000..7b251377 --- /dev/null +++ b/operator/pallets/system/src/weights.rs @@ -0,0 +1,131 @@ + +//! Autogenerated weights for `snowbridge_system` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-10-09, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `crake.local`, CPU: `` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: `1024` + +// Executed Command: +// target/release/polkadot-parachain +// benchmark +// pallet +// --chain +// bridge-hub-rococo-dev +// --pallet=snowbridge_system +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --template +// ../parachain/templates/module-weight-template.hbs +// --output +// ../parachain/pallets/control/src/weights.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for `snowbridge_system`. +pub trait WeightInfo { + fn upgrade() -> Weight; + fn set_operating_mode() -> Weight; + fn set_token_transfer_fees() -> Weight; + fn set_pricing_parameters() -> Weight; + fn register_token() -> Weight; +} + +// For backwards compatibility and tests. +impl WeightInfo for () { + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: EthereumOutboundQueue PalletOperatingMode (r:1 w:0) + /// Proof: EthereumOutboundQueue PalletOperatingMode (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(5), added: 500, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:0 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65585), added: 68060, mode: MaxEncodedLen) + fn upgrade() -> Weight { + // Proof Size summary in bytes: + // Measured: `80` + // Estimated: `3517` + // Minimum execution time: 44_000_000 picoseconds. + Weight::from_parts(44_000_000, 3517) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: EthereumOutboundQueue PalletOperatingMode (r:1 w:0) + /// Proof: EthereumOutboundQueue PalletOperatingMode (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(5), added: 500, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:0 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65585), added: 68060, mode: MaxEncodedLen) + fn set_operating_mode() -> Weight { + // Proof Size summary in bytes: + // Measured: `80` + // Estimated: `3517` + // Minimum execution time: 31_000_000 picoseconds. + Weight::from_parts(31_000_000, 3517) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: EthereumOutboundQueue PalletOperatingMode (r:1 w:0) + /// Proof: EthereumOutboundQueue PalletOperatingMode (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(5), added: 500, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:0 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65585), added: 68060, mode: MaxEncodedLen) + fn set_token_transfer_fees() -> Weight { + // Proof Size summary in bytes: + // Measured: `80` + // Estimated: `3517` + // Minimum execution time: 31_000_000 picoseconds. + Weight::from_parts(42_000_000, 3517) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: EthereumOutboundQueue PalletOperatingMode (r:1 w:0) + /// Proof: EthereumOutboundQueue PalletOperatingMode (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(5), added: 500, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:0 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65585), added: 68060, mode: MaxEncodedLen) + fn set_pricing_parameters() -> Weight { + // Proof Size summary in bytes: + // Measured: `80` + // Estimated: `3517` + // Minimum execution time: 31_000_000 picoseconds. + Weight::from_parts(42_000_000, 3517) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + + fn register_token() -> Weight { + // Proof Size summary in bytes: + // Measured: `256` + // Estimated: `6044` + // Minimum execution time: 45_000_000 picoseconds. + Weight::from_parts(45_000_000, 6044) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } +} diff --git a/operator/primitives/snowbridge/outbound-queue/src/lib.rs b/operator/primitives/snowbridge/outbound-queue/src/lib.rs index be0c0542..4e39021f 100644 --- a/operator/primitives/snowbridge/outbound-queue/src/lib.rs +++ b/operator/primitives/snowbridge/outbound-queue/src/lib.rs @@ -4,6 +4,7 @@ //! # Outbound //! //! Common traits and types +pub mod v1; pub mod v2; use codec::{Decode, DecodeWithMemTracking, Encode}; diff --git a/operator/primitives/snowbridge/outbound-queue/src/v1/message.rs b/operator/primitives/snowbridge/outbound-queue/src/v1/message.rs new file mode 100644 index 00000000..e218e4b0 --- /dev/null +++ b/operator/primitives/snowbridge/outbound-queue/src/v1/message.rs @@ -0,0 +1,408 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +//! # Outbound V1 primitives + +use crate::{OperatingMode, SendError, SendMessageFeeProvider}; +use codec::{Decode, DecodeWithMemTracking, Encode}; +use ethabi::Token; +use scale_info::TypeInfo; +use snowbridge_core::{pricing::UD60x18, ChannelId}; +use sp_arithmetic::traits::{BaseArithmetic, Unsigned}; +use sp_core::{RuntimeDebug, H160, H256, U256}; +use sp_std::{borrow::ToOwned, vec, vec::Vec}; + +/// Enqueued outbound messages need to be versioned to prevent data corruption +/// or loss after forkless runtime upgrades +#[derive(Encode, Decode, TypeInfo, Clone, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub enum VersionedQueuedMessage { + V1(QueuedMessage), +} + +impl TryFrom for QueuedMessage { + type Error = (); + fn try_from(x: VersionedQueuedMessage) -> Result { + use VersionedQueuedMessage::*; + match x { + V1(x) => Ok(x), + } + } +} + +impl> From for VersionedQueuedMessage { + fn from(x: T) -> Self { + VersionedQueuedMessage::V1(x.into()) + } +} + +/// A message which can be accepted by implementations of `/[`SendMessage`\]` +#[derive(Encode, Decode, TypeInfo, Clone, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub struct Message { + /// ID for this message. One will be automatically generated if not provided. + /// + /// When this message is created from an XCM message, the ID should be extracted + /// from the `SetTopic` instruction. + /// + /// The ID plays no role in bridge consensus, and is purely meant for message tracing. + pub id: Option, + /// The message channel ID + pub channel_id: ChannelId, + /// The stable ID for a receiving gateway contract + pub command: Command, +} + +/// A command which is executable by the Gateway contract on Ethereum +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub enum Command { + /// Execute a sub-command within an agent for a consensus system in Polkadot + /// DEPRECATED in favour of `UnlockNativeToken`. We still have to keep it around in + /// case buffered and uncommitted messages are using this variant. + AgentExecute { + /// The ID of the agent + agent_id: H256, + /// The sub-command to be executed + command: AgentExecuteCommand, + }, + /// Upgrade the Gateway contract + Upgrade { + /// Address of the new implementation contract + impl_address: H160, + /// Codehash of the implementation contract + impl_code_hash: H256, + /// Optionally invoke an initializer in the implementation contract + initializer: Option, + }, + /// Set the global operating mode of the Gateway contract + SetOperatingMode { + /// The new operating mode + mode: OperatingMode, + }, + /// Set token fees of the Gateway contract + SetTokenTransferFees { + /// The fee(DOT) for the cost of creating asset on AssetHub + create_asset_xcm: u128, + /// The fee(DOT) for the cost of sending asset on AssetHub + transfer_asset_xcm: u128, + /// The fee(Ether) for register token to discourage spamming + register_token: U256, + }, + /// Set pricing parameters + SetPricingParameters { + // ETH/DOT exchange rate + exchange_rate: UD60x18, + // Cost of delivering a message from Ethereum to BridgeHub, in ROC/KSM/DOT + delivery_cost: u128, + // Fee multiplier + multiplier: UD60x18, + }, + /// Transfer ERC20 tokens + UnlockNativeToken { + /// ID of the agent + agent_id: H256, + /// Address of the ERC20 token + token: H160, + /// The recipient of the tokens + recipient: H160, + /// The amount of tokens to transfer + amount: u128, + }, + /// Register foreign token from Polkadot + RegisterForeignToken { + /// ID for the token + token_id: H256, + /// Name of the token + name: Vec, + /// Short symbol for the token + symbol: Vec, + /// Number of decimal places + decimals: u8, + }, + /// Mint foreign token from Polkadot + MintForeignToken { + /// ID for the token + token_id: H256, + /// The recipient of the newly minted tokens + recipient: H160, + /// The amount of tokens to mint + amount: u128, + }, +} + +impl Command { + /// Compute the enum variant index + pub fn index(&self) -> u8 { + match self { + Command::AgentExecute { .. } => 0, + Command::Upgrade { .. } => 1, + Command::SetOperatingMode { .. } => 5, + Command::SetTokenTransferFees { .. } => 7, + Command::SetPricingParameters { .. } => 8, + Command::UnlockNativeToken { .. } => 9, + Command::RegisterForeignToken { .. } => 10, + Command::MintForeignToken { .. } => 11, + } + } + + /// ABI-encode the Command. + pub fn abi_encode(&self) -> Vec { + match self { + Command::AgentExecute { agent_id, command } => ethabi::encode(&[Token::Tuple(vec![ + Token::FixedBytes(agent_id.as_bytes().to_owned()), + Token::Bytes(command.abi_encode()), + ])]), + Command::Upgrade { + impl_address, + impl_code_hash, + initializer, + .. + } => ethabi::encode(&[Token::Tuple(vec![ + Token::Address(*impl_address), + Token::FixedBytes(impl_code_hash.as_bytes().to_owned()), + initializer + .clone() + .map_or(Token::Bytes(vec![]), |i| Token::Bytes(i.params)), + ])]), + Command::SetOperatingMode { mode } => { + ethabi::encode(&[Token::Tuple(vec![Token::Uint(U256::from((*mode) as u64))])]) + } + Command::SetTokenTransferFees { + create_asset_xcm, + transfer_asset_xcm, + register_token, + } => ethabi::encode(&[Token::Tuple(vec![ + Token::Uint(U256::from(*create_asset_xcm)), + Token::Uint(U256::from(*transfer_asset_xcm)), + Token::Uint(*register_token), + ])]), + Command::SetPricingParameters { + exchange_rate, + delivery_cost, + multiplier, + } => ethabi::encode(&[Token::Tuple(vec![ + Token::Uint(exchange_rate.clone().into_inner()), + Token::Uint(U256::from(*delivery_cost)), + Token::Uint(multiplier.clone().into_inner()), + ])]), + Command::UnlockNativeToken { + agent_id, + token, + recipient, + amount, + } => ethabi::encode(&[Token::Tuple(vec![ + Token::FixedBytes(agent_id.as_bytes().to_owned()), + Token::Address(*token), + Token::Address(*recipient), + Token::Uint(U256::from(*amount)), + ])]), + Command::RegisterForeignToken { + token_id, + name, + symbol, + decimals, + } => ethabi::encode(&[Token::Tuple(vec![ + Token::FixedBytes(token_id.as_bytes().to_owned()), + Token::String(name.to_owned()), + Token::String(symbol.to_owned()), + Token::Uint(U256::from(*decimals)), + ])]), + Command::MintForeignToken { + token_id, + recipient, + amount, + } => ethabi::encode(&[Token::Tuple(vec![ + Token::FixedBytes(token_id.as_bytes().to_owned()), + Token::Address(*recipient), + Token::Uint(U256::from(*amount)), + ])]), + } + } +} + +/// Representation of a call to the initializer of an implementation contract. +/// The initializer has the following ABI signature: `initialize(bytes)`. +#[derive(Clone, Encode, Decode, DecodeWithMemTracking, PartialEq, RuntimeDebug, TypeInfo)] +pub struct Initializer { + /// ABI-encoded params of type `bytes` to pass to the initializer + pub params: Vec, + /// The initializer is allowed to consume this much gas at most. + pub maximum_required_gas: u64, +} + +/// A Sub-command executable within an agent +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub enum AgentExecuteCommand { + /// Transfer ERC20 tokens + TransferToken { + /// Address of the ERC20 token + token: H160, + /// The recipient of the tokens + recipient: H160, + /// The amount of tokens to transfer + amount: u128, + }, +} + +impl AgentExecuteCommand { + fn index(&self) -> u8 { + match self { + AgentExecuteCommand::TransferToken { .. } => 0, + } + } + + /// ABI-encode the sub-command + pub fn abi_encode(&self) -> Vec { + match self { + AgentExecuteCommand::TransferToken { + token, + recipient, + amount, + } => ethabi::encode(&[ + Token::Uint(self.index().into()), + Token::Bytes(ethabi::encode(&[ + Token::Address(*token), + Token::Address(*recipient), + Token::Uint(U256::from(*amount)), + ])), + ]), + } + } +} + +/// Message which is awaiting processing in the MessageQueue pallet +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub struct QueuedMessage { + /// Message ID + pub id: H256, + /// Channel ID + pub channel_id: ChannelId, + /// Command to execute in the Gateway contract + pub command: Command, +} + +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +#[cfg_attr(feature = "std", derive(PartialEq))] +/// Fee for delivering message +pub struct Fee +where + Balance: BaseArithmetic + Unsigned + Copy, +{ + /// Fee to cover cost of processing the message locally + pub local: Balance, + /// Fee to cover cost processing the message remotely + pub remote: Balance, +} + +impl Fee +where + Balance: BaseArithmetic + Unsigned + Copy, +{ + pub fn total(&self) -> Balance { + self.local.saturating_add(self.remote) + } +} + +impl From<(Balance, Balance)> for Fee +where + Balance: BaseArithmetic + Unsigned + Copy, +{ + fn from((local, remote): (Balance, Balance)) -> Self { + Self { local, remote } + } +} + +/// A trait for sending messages to Ethereum +pub trait SendMessage: SendMessageFeeProvider { + type Ticket: Clone + Encode + Decode; + + /// Validate an outbound message and return a tuple: + /// 1. Ticket for submitting the message + /// 2. Delivery fee + fn validate( + message: &Message, + ) -> Result<(Self::Ticket, Fee<::Balance>), SendError>; + + /// Submit the message ticket for eventual delivery to Ethereum + fn deliver(ticket: Self::Ticket) -> Result; +} + +pub trait Ticket: Encode + Decode + Clone { + fn message_id(&self) -> H256; +} + +pub trait GasMeter { + /// All the gas used for submitting a message to Ethereum, minus the cost of dispatching + /// the command within the message + const MAXIMUM_BASE_GAS: u64; + + /// Total gas consumed at most, including verification & dispatch + fn maximum_gas_used_at_most(command: &Command) -> u64 { + Self::MAXIMUM_BASE_GAS + Self::maximum_dispatch_gas_used_at_most(command) + } + + /// Measures the maximum amount of gas a command payload will require to *dispatch*, NOT + /// including validation & verification. + fn maximum_dispatch_gas_used_at_most(command: &Command) -> u64; +} + +/// A meter that assigns a constant amount of gas for the execution of a command +/// +/// The gas figures are extracted from this report: +/// > forge test --match-path test/Gateway.t.sol --gas-report +/// +/// A healthy buffer is added on top of these figures to account for: +/// * The EIP-150 63/64 rule +/// * Future EVM upgrades that may increase gas cost +pub struct ConstantGasMeter; + +impl GasMeter for ConstantGasMeter { + // The base transaction cost, which includes: + // 21_000 transaction cost, roughly worst case 64_000 for calldata, and 100_000 + // for message verification + const MAXIMUM_BASE_GAS: u64 = 185_000; + + fn maximum_dispatch_gas_used_at_most(command: &Command) -> u64 { + match command { + Command::SetOperatingMode { .. } => 40_000, + Command::AgentExecute { command, .. } => match command { + // Execute IERC20.transferFrom + // + // Worst-case assumptions are important: + // * No gas refund for clearing storage slot of source account in ERC20 contract + // * Assume dest account in ERC20 contract does not yet have a storage slot + // * ERC20.transferFrom possibly does other business logic besides updating balances + AgentExecuteCommand::TransferToken { .. } => 200_000, + }, + Command::Upgrade { initializer, .. } => { + let initializer_max_gas = match *initializer { + Some(Initializer { + maximum_required_gas, + .. + }) => maximum_required_gas, + None => 0, + }; + // total maximum gas must also include the gas used for updating the proxy before + // the the initializer is called. + 50_000 + initializer_max_gas + } + Command::SetTokenTransferFees { .. } => 60_000, + Command::SetPricingParameters { .. } => 60_000, + Command::UnlockNativeToken { .. } => 200_000, + Command::RegisterForeignToken { .. } => 1_200_000, + Command::MintForeignToken { .. } => 100_000, + } + } +} + +impl GasMeter for () { + const MAXIMUM_BASE_GAS: u64 = 1; + + fn maximum_dispatch_gas_used_at_most(_: &Command) -> u64 { + 1 + } +} + +pub const ETHER_DECIMALS: u8 = 18; diff --git a/operator/primitives/snowbridge/outbound-queue/src/v1/mod.rs b/operator/primitives/snowbridge/outbound-queue/src/v1/mod.rs new file mode 100644 index 00000000..f90ed90d --- /dev/null +++ b/operator/primitives/snowbridge/outbound-queue/src/v1/mod.rs @@ -0,0 +1,3 @@ +pub mod message; + +pub use message::*; diff --git a/operator/primitives/snowbridge/test-utils/src/mock_outbound_queue.rs b/operator/primitives/snowbridge/test-utils/src/mock_outbound_queue.rs index 3f06ecd8..8adb84e5 100644 --- a/operator/primitives/snowbridge/test-utils/src/mock_outbound_queue.rs +++ b/operator/primitives/snowbridge/test-utils/src/mock_outbound_queue.rs @@ -2,6 +2,7 @@ // SPDX-FileCopyrightText: 2023 Snowfork use snowbridge_outbound_queue_primitives::{ + v1::{Fee, Message as MessageV1, SendMessage as SendMessageV1}, v2::{Message, SendMessage}, SendMessageFeeProvider, }; @@ -29,3 +30,29 @@ impl SendMessageFeeProvider for MockOkOutboundQueue { 0 } } + +pub struct MockOkOutboundQueueV1; +impl SendMessageV1 for MockOkOutboundQueueV1 { + type Ticket = (); + + fn validate( + _: &MessageV1, + ) -> Result< + (Self::Ticket, Fee<::Balance>), + snowbridge_outbound_queue_primitives::SendError, + > { + Ok(((), Fee::from((0, 0)))) + } + + fn deliver(_: Self::Ticket) -> Result { + Ok(H256::zero()) + } +} + +impl SendMessageFeeProvider for MockOkOutboundQueueV1 { + type Balance = u128; + + fn local_fee() -> Self::Balance { + 0 + } +} diff --git a/operator/runtime/Cargo.toml b/operator/runtime/Cargo.toml index 61f06238..db1441d3 100644 --- a/operator/runtime/Cargo.toml +++ b/operator/runtime/Cargo.toml @@ -61,6 +61,7 @@ polkadot-runtime-common = { workspace = true } scale-info = { features = ["derive", "serde"], workspace = true } serde_json = { workspace = true, default-features = false, features = ["alloc"] } snowbridge-beacon-primitives = { workspace = true } +snowbridge-core = { workspace = true } snowbridge-inbound-queue-primitives = { workspace = true } snowbridge-merkle-tree = { workspace = true } snowbridge-outbound-queue-primitives = { workspace = true } @@ -68,6 +69,9 @@ snowbridge-outbound-queue-v2-runtime-api = { workspace = true } snowbridge-pallet-ethereum-client = { workspace = true } snowbridge-pallet-inbound-queue-v2 = { workspace = true } snowbridge-pallet-outbound-queue-v2 = { workspace = true } +snowbridge-pallet-system = { workspace = true } +snowbridge-pallet-system-v2 = { workspace = true } +snowbridge-system-v2-runtime-api = { workspace = true } snowbridge-verification-primitives = { workspace = true } sp-api = { workspace = true } sp-block-builder = { workspace = true } @@ -144,11 +148,15 @@ std = [ "snowbridge-pallet-outbound-queue-v2/std", "snowbridge-merkle-tree/std", "snowbridge-outbound-queue-v2-runtime-api/std", + "snowbridge-pallet-system/std", + "snowbridge-pallet-system-v2/std", + "snowbridge-system-v2-runtime-api/std", "dhp-bridge/std", "snowbridge-verification-primitives/std", "sp-api/std", "sp-block-builder/std", "sp-consensus-babe/std", + "sp-consensus-beefy/std", "sp-consensus-grandpa/std", "sp-core/std", "sp-genesis-builder/std", @@ -191,12 +199,13 @@ runtime-benchmarks = [ "pallet-utility/runtime-benchmarks", "polkadot-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", - "polkadot-primitives/runtime-benchmarks", "snowbridge-inbound-queue-primitives/runtime-benchmarks", "snowbridge-pallet-ethereum-client/runtime-benchmarks", "snowbridge-pallet-inbound-queue-v2/runtime-benchmarks", + "snowbridge-pallet-system-v2/runtime-benchmarks", "snowbridge-pallet-outbound-queue-v2/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "snowbridge-pallet-system/runtime-benchmarks", ] try-runtime = [ @@ -230,8 +239,10 @@ try-runtime = [ "polkadot-runtime-common/try-runtime", "snowbridge-pallet-ethereum-client/try-runtime", "snowbridge-pallet-inbound-queue-v2/try-runtime", + "snowbridge-pallet-system-v2/try-runtime", "snowbridge-pallet-outbound-queue-v2/try-runtime", "sp-runtime/try-runtime", + "snowbridge-pallet-system/try-runtime", ] fast-runtime = [ diff --git a/operator/runtime/src/apis.rs b/operator/runtime/src/apis.rs index dc9ae26a..4487857b 100644 --- a/operator/runtime/src/apis.rs +++ b/operator/runtime/src/apis.rs @@ -50,6 +50,7 @@ use pallet_evm::FeeCalculator; use pallet_evm::Runner; use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId}; use polkadot_primitives::Hash; +use snowbridge_core::AgentId; use sp_api::impl_runtime_apis; use sp_consensus_beefy::{ ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature}, @@ -65,6 +66,7 @@ use sp_runtime::{ ApplyExtrinsicResult, Permill, }; use sp_version::RuntimeVersion; +use xcm::VersionedLocation; /// MMR helper types. mod mmr { use super::Runtime; @@ -493,6 +495,12 @@ impl_runtime_apis! { } } + impl snowbridge_system_v2_runtime_api::ControlV2Api for Runtime { + fn agent_id(location: VersionedLocation) -> Option { + snowbridge_pallet_system_v2::api::agent_id::(location) + } + } + #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { fn benchmark_metadata(extra: bool) -> ( diff --git a/operator/runtime/src/configs/mod.rs b/operator/runtime/src/configs/mod.rs index 7747d501..2e0bc284 100644 --- a/operator/runtime/src/configs/mod.rs +++ b/operator/runtime/src/configs/mod.rs @@ -25,6 +25,14 @@ mod runtime_params; +use super::{ + deposit, AccountId, Babe, Balance, Balances, BeefyMmrLeaf, Block, BlockNumber, + EthereumBeaconClient, EvmChainId, Hash, Historical, ImOnline, MessageQueue, Nonce, Offences, + OriginCaller, OutboundQueueV2, PalletInfo, Preimage, Runtime, RuntimeCall, RuntimeEvent, + RuntimeFreezeReason, RuntimeHoldReason, RuntimeOrigin, RuntimeTask, Session, SessionKeys, + Signature, System, Timestamp, ValidatorSet, EXISTENTIAL_DEPOSIT, SLOT_DURATION, + STORAGE_BYTE_FEE, SUPPLY_FACTOR, UNIT, VERSION, +}; use codec::{Decode, Encode}; use datahaven_runtime_common::{ gas::WEIGHT_PER_GAS, @@ -47,7 +55,7 @@ use frame_support::{ }; use frame_system::{ limits::{BlockLength, BlockWeights}, - EnsureRoot, + EnsureRoot, EnsureRootWithSuccess, }; use pallet_ethereum::PostLogContent; use pallet_evm::{ @@ -61,14 +69,22 @@ use pallet_transaction_payment::{ ConstFeeMultiplier, FungibleAdapter, Multiplier, Pallet as TransactionPayment, }; use polkadot_primitives::Moment; +use runtime_params::RuntimeParameters; use snowbridge_beacon_primitives::{Fork, ForkVersions}; +use snowbridge_core::{gwei, meth, AgentIdOf, PricingParameters, Rewards}; use snowbridge_inbound_queue_primitives::RewardLedger; -use snowbridge_outbound_queue_primitives::v2::ConstantGasMeter; +use snowbridge_outbound_queue_primitives::{ + v1::{Fee, Message, SendMessage}, + v2::ConstantGasMeter, + SendError, SendMessageFeeProvider, +}; +use snowbridge_pallet_system::BalanceOf; use sp_consensus_beefy::{ ecdsa_crypto::AuthorityId as BeefyId, mmr::{BeefyDataProvider, MmrLeafVersion}, }; use sp_core::{crypto::KeyTypeId, Get, H160, H256, U256}; +use sp_runtime::FixedU128; use sp_runtime::{ traits::{ConvertInto, IdentityLookup, Keccak256, One, OpaqueKeys, UniqueSaturatedInto}, FixedPointNumber, Perbill, @@ -80,16 +96,7 @@ use sp_std::{ }; use sp_version::RuntimeVersion; use xcm::latest::NetworkId; - -use super::{ - deposit, AccountId, Babe, Balance, Balances, BeefyMmrLeaf, Block, BlockNumber, - EthereumBeaconClient, EvmChainId, Hash, Historical, ImOnline, MessageQueue, Nonce, Offences, - OriginCaller, OutboundQueueV2, PalletInfo, Preimage, Runtime, RuntimeCall, RuntimeEvent, - RuntimeFreezeReason, RuntimeHoldReason, RuntimeOrigin, RuntimeTask, Session, SessionKeys, - Signature, System, Timestamp, ValidatorSet, EXISTENTIAL_DEPOSIT, SLOT_DURATION, - STORAGE_BYTE_FEE, SUPPLY_FACTOR, UNIT, VERSION, -}; -use runtime_params::RuntimeParameters; +use xcm::prelude::*; #[cfg(feature = "runtime-benchmarks")] use bridge_hub_common::AggregateMessageOrigin; @@ -619,6 +626,72 @@ impl pallet_evm_chain_id::Config for Runtime {} //║ SNOWBRIDGE PALLETS ║ //╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════╝ +// --- Snowbridge Config Constants & Parameter Types --- +parameter_types! { + pub UniversalLocation: InteriorLocation = Here.into(); + pub InboundDeliveryCost: BalanceOf = 0; + pub RootLocation: Location = Location::here(); + pub Parameters: PricingParameters = PricingParameters { + exchange_rate: FixedU128::from_rational(1, 400), + fee_per_gas: gwei(20), + rewards: Rewards { local: 1 * UNIT, remote: meth(1) }, + multiplier: FixedU128::from_rational(1, 1), + }; + pub EthereumLocation: Location = Location::new(1, EthereumNetwork::get()); + pub TreasuryAccountId: AccountId = AccountId::from([0u8; 20]); +} + +pub struct DoNothingOutboundQueue; +impl SendMessage for DoNothingOutboundQueue { + type Ticket = (); + + fn validate( + _: &Message, + ) -> Result<(Self::Ticket, Fee<::Balance>), SendError> { + Ok(((), Fee::from((0, 0)))) + } + + fn deliver(_: Self::Ticket) -> Result { + Ok(H256::zero()) + } +} + +impl SendMessageFeeProvider for DoNothingOutboundQueue { + type Balance = u128; + + fn local_fee() -> Self::Balance { + 1 + } +} + +// Implement the Snowbridge System V1 config trait +impl snowbridge_pallet_system::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type OutboundQueue = DoNothingOutboundQueue; + type SiblingOrigin = EnsureRootWithSuccess; + type AgentIdOf = AgentIdOf; + type Token = Balances; + type TreasuryAccount = TreasuryAccountId; + type DefaultPricingParameters = Parameters; + type InboundDeliveryCost = InboundDeliveryCost; + type WeightInfo = (); + type UniversalLocation = UniversalLocation; + type EthereumLocation = EthereumLocation; + #[cfg(feature = "runtime-benchmarks")] + type Helper = (); +} + +// Implement the Snowbridge System v2 config trait +impl snowbridge_pallet_system_v2::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type OutboundQueue = OutboundQueueV2; + type FrontendOrigin = EnsureRootWithSuccess; + type GovernanceOrigin = EnsureRootWithSuccess; + type WeightInfo = (); + #[cfg(feature = "runtime-benchmarks")] + type Helper = (); +} + // For tests, benchmarks and fast-runtime configurations we use the mocked fork versions #[cfg(any( feature = "std", @@ -742,6 +815,7 @@ impl snowbridge_pallet_outbound_queue_v2::Config for Runtime { type MaxMessagesPerBlock = ConstU32<32>; type OnNewCommitment = (); type WeightToFee = IdentityFee; + type WeightInfo = (); type Verifier = EthereumBeaconClient; type GatewayAddress = runtime_params::dynamic_params::runtime_config::EthereumGatewayAddress; type RewardKind = (); @@ -749,7 +823,6 @@ impl snowbridge_pallet_outbound_queue_v2::Config for Runtime { type RewardPayment = DummyRewardPayment; type EthereumNetwork = EthereumNetwork; type ConvertAssetId = (); - type WeightInfo = (); } //╔═══════════════════════════════════════════════════════════════════════════════════════════════════════════════╗ @@ -762,15 +835,28 @@ impl snowbridge_pallet_outbound_queue_v2::Config for Runtime { #[cfg(feature = "runtime-benchmarks")] pub mod benchmark_helpers { + use crate::RuntimeOrigin; use crate::{EthereumBeaconClient, Runtime}; use snowbridge_beacon_primitives::BeaconHeader; use snowbridge_pallet_inbound_queue_v2::BenchmarkHelper as InboundQueueBenchmarkHelperV2; - // use snowbridge_pallet_outbound_queue_v2::BenchmarkHelper as OutboundQueueBenchmarkHelperV2; use sp_core::H256; + use xcm::opaque::latest::Location; impl InboundQueueBenchmarkHelperV2 for Runtime { fn initialize_storage(beacon_header: BeaconHeader, block_roots_root: H256) { EthereumBeaconClient::store_finalized_header(beacon_header, block_roots_root).unwrap(); } } + + impl snowbridge_pallet_system::BenchmarkHelper for () { + fn make_xcm_origin(_location: Location) -> RuntimeOrigin { + RuntimeOrigin::root() + } + } + + impl snowbridge_pallet_system_v2::BenchmarkHelper for () { + fn make_xcm_origin(_location: Location) -> RuntimeOrigin { + RuntimeOrigin::root() + } + } } diff --git a/operator/runtime/src/lib.rs b/operator/runtime/src/lib.rs index 6e97374b..6117b170 100644 --- a/operator/runtime/src/lib.rs +++ b/operator/runtime/src/lib.rs @@ -218,6 +218,7 @@ where UncheckedExtrinsic::new_bare(call) } } + // Create the runtime by composing the FRAME pallets that were previously configured. #[frame_support::runtime] mod runtime { @@ -332,6 +333,12 @@ mod runtime { #[runtime::pallet_index(62)] pub type OutboundQueueV2 = snowbridge_pallet_outbound_queue_v2; + + #[runtime::pallet_index(63)] + pub type SnowbridgeSystem = snowbridge_pallet_system; + + #[runtime::pallet_index(64)] + pub type SnowbridgeSystemV2 = snowbridge_pallet_system_v2; // ╚══════════════════════ Snowbridge Pallets ═══════════════════════╝ // ╔══════════════════════ StorageHub Pallets ═══════════════════════╗