diff --git a/Cargo.lock b/Cargo.lock
index 943315a..77cdb8a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -136,47 +136,48 @@ dependencies = [
[[package]]
name = "anstream"
-version = "0.6.13"
+version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
+checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
+ "is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
-version = "1.0.6"
+version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
+checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
[[package]]
name = "anstyle-parse"
-version = "0.2.3"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
+checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
-version = "1.0.2"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
+checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
-version = "3.0.2"
+version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
+checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
@@ -585,7 +586,7 @@ dependencies = [
"futures-lite",
"parking",
"polling",
- "rustix 0.38.33",
+ "rustix 0.38.34",
"slab",
"tracing",
"windows-sys 0.52.0",
@@ -637,9 +638,9 @@ dependencies = [
[[package]]
name = "autocfg"
-version = "1.2.0"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
+checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "backtrace"
@@ -1002,9 +1003,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.0.95"
+version = "1.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b"
+checksum = "065a29261d53ba54260972629f9ca6bffa69bac13cd1fed61420f7fa68b9f8bd"
dependencies = [
"jobserver",
"libc",
@@ -1186,9 +1187,9 @@ dependencies = [
[[package]]
name = "colorchoice"
-version = "1.0.0"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
+checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
[[package]]
name = "comfy-table"
@@ -1225,9 +1226,9 @@ checksum = "2382f75942f4b3be3690fe4f86365e9c853c1587d6ee58212cebf6e2a9ccd101"
[[package]]
name = "concurrent-queue"
-version = "2.4.0"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363"
+checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
dependencies = [
"crossbeam-utils",
]
@@ -1619,15 +1620,15 @@ dependencies = [
[[package]]
name = "data-encoding"
-version = "2.5.0"
+version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
+checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
[[package]]
name = "data-encoding-macro"
-version = "0.1.14"
+version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20c01c06f5f429efdf2bae21eb67c28b3df3cf85b7dd2d8ef09c0838dac5d33e"
+checksum = "f1559b6cba622276d6d63706db152618eeb15b89b3e4041446b05876e352e639"
dependencies = [
"data-encoding",
"data-encoding-macro-internal",
@@ -1635,9 +1636,9 @@ dependencies = [
[[package]]
name = "data-encoding-macro-internal"
-version = "0.1.12"
+version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0047d07f2c89b17dd631c80450d69841a6b5d7fb17278cbc43d7e4cfcf2576f3"
+checksum = "332d754c0af53bc87c108fed664d121ecf59207ec4196041f04d6ab9002ad33f"
dependencies = [
"data-encoding",
"syn 1.0.109",
@@ -2082,9 +2083,9 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
[[package]]
name = "fastrand"
-version = "2.0.2"
+version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
+checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
[[package]]
name = "fdlimit"
@@ -2121,9 +2122,9 @@ dependencies = [
[[package]]
name = "fiat-crypto"
-version = "0.2.7"
+version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c007b1ae3abe1cb6f85a16305acd418b7ca6343b953633fee2b76d8f108b830f"
+checksum = "38793c55593b33412e3ae40c2c9781ffaa6f438f6f8c10f24e71846fbd7ae01e"
[[package]]
name = "file-per-thread-logger"
@@ -2159,7 +2160,7 @@ dependencies = [
"log",
"num-traits",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"scale-info",
]
@@ -2183,9 +2184,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]]
name = "flate2"
-version = "1.0.28"
+version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
+checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae"
dependencies = [
"crc32fast",
"libz-sys",
@@ -2830,9 +2831,9 @@ dependencies = [
[[package]]
name = "hashbrown"
-version = "0.14.3"
+version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
"ahash 0.8.11",
"allocator-api2",
@@ -2844,7 +2845,7 @@ version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7"
dependencies = [
- "hashbrown 0.14.3",
+ "hashbrown 0.14.5",
]
[[package]]
@@ -3003,7 +3004,7 @@ dependencies = [
"httpdate",
"itoa",
"pin-project-lite 0.2.14",
- "socket2 0.5.6",
+ "socket2 0.5.7",
"tokio",
"tower-service",
"tracing",
@@ -3020,7 +3021,7 @@ dependencies = [
"http",
"hyper",
"log",
- "rustls 0.21.11",
+ "rustls 0.21.12",
"rustls-native-certs",
"tokio",
"tokio-rustls",
@@ -3166,7 +3167,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
dependencies = [
"equivalent",
- "hashbrown 0.14.3",
+ "hashbrown 0.14.5",
]
[[package]]
@@ -3232,7 +3233,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f"
dependencies = [
- "socket2 0.5.6",
+ "socket2 0.5.7",
"widestring",
"windows-sys 0.48.0",
"winreg",
@@ -3255,6 +3256,12 @@ dependencies = [
"windows-sys 0.52.0",
]
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
+
[[package]]
name = "itertools"
version = "0.10.5"
@@ -3272,9 +3279,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "jobserver"
-version = "0.1.30"
+version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "685a7d121ee3f65ae4fddd72b25a04bb36b6af81bc0828f7d5434c0fe60fa3a2"
+checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e"
dependencies = [
"libc",
]
@@ -3341,7 +3348,7 @@ dependencies = [
"globset",
"hyper",
"jsonrpsee-types",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"rand",
"rustc-hash",
"serde",
@@ -3476,7 +3483,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf7a85fe66f9ff9cd74e169fdd2c94c6e1e74c412c99a73b4df3200b5d3760b2"
dependencies = [
"kvdb",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
]
[[package]]
@@ -3487,7 +3494,7 @@ checksum = "b644c70b92285f66bfc2032922a79000ea30af7bc2ab31902992a5dcb9b434f6"
dependencies = [
"kvdb",
"num_cpus",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"regex",
"rocksdb",
"smallvec",
@@ -3507,9 +3514,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
-version = "0.2.153"
+version = "0.2.154"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
+checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
[[package]]
name = "libloading"
@@ -3601,7 +3608,7 @@ dependencies = [
"multihash",
"multistream-select",
"once_cell",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"pin-project",
"quick-protobuf",
"rand",
@@ -3621,7 +3628,7 @@ dependencies = [
"futures",
"libp2p-core",
"log",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"smallvec",
"trust-dns-resolver",
]
@@ -3783,7 +3790,7 @@ dependencies = [
"libp2p-identity",
"libp2p-tls",
"log",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"quinn-proto",
"rand",
"rustls 0.20.9",
@@ -3899,7 +3906,7 @@ dependencies = [
"futures-rustls",
"libp2p-core",
"log",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"quicksink",
"rw-stream-sink",
"soketto",
@@ -4061,11 +4068,29 @@ dependencies = [
"keystream",
]
+[[package]]
+name = "lite-json"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd0e787ffe1153141a0f6f6d759fdf1cc34b1226e088444523812fd412a5cca2"
+dependencies = [
+ "lite-parser",
+]
+
+[[package]]
+name = "lite-parser"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3d5f9dc37c52d889a21fd701983d02bb6a84f852c5140a6c80ef4557f7dc29e"
+dependencies = [
+ "paste",
+]
+
[[package]]
name = "lock_api"
-version = "0.4.11"
+version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
+checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [
"autocfg",
"scopeguard",
@@ -4230,7 +4255,7 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64"
dependencies = [
- "rustix 0.38.33",
+ "rustix 0.38.34",
]
[[package]]
@@ -4314,7 +4339,7 @@ dependencies = [
"hashlink",
"lioness",
"log",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"rand",
"rand_chacha",
"rand_distr",
@@ -4581,6 +4606,7 @@ dependencies = [
"sp-inherents",
"sp-io",
"sp-keyring",
+ "sp-keystore",
"sp-runtime",
"sp-timestamp",
"substrate-build-script-utils",
@@ -4599,6 +4625,7 @@ dependencies = [
"frame-system-benchmarking",
"frame-system-rpc-runtime-api",
"frame-try-runtime",
+ "log",
"pallet-aura",
"pallet-balances",
"pallet-grandpa",
@@ -4716,9 +4743,9 @@ dependencies = [
[[package]]
name = "num-traits"
-version = "0.2.18"
+version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
"libm",
@@ -4920,11 +4947,16 @@ dependencies = [
"frame-benchmarking",
"frame-support",
"frame-system",
+ "lite-json",
+ "log",
"parity-scale-codec",
"scale-info",
+ "serde",
+ "serde_json",
"sp-core",
"sp-io",
"sp-runtime",
+ "sp-std 8.0.0",
]
[[package]]
@@ -5005,7 +5037,7 @@ dependencies = [
"log",
"lz4",
"memmap2",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"rand",
"siphasher",
"snap",
@@ -5070,12 +5102,12 @@ dependencies = [
[[package]]
name = "parking_lot"
-version = "0.12.1"
+version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb"
dependencies = [
"lock_api",
- "parking_lot_core 0.9.9",
+ "parking_lot_core 0.9.10",
]
[[package]]
@@ -5094,15 +5126,15 @@ dependencies = [
[[package]]
name = "parking_lot_core"
-version = "0.9.9"
+version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
+checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if",
"libc",
- "redox_syscall 0.4.1",
+ "redox_syscall 0.5.1",
"smallvec",
- "windows-targets 0.48.5",
+ "windows-targets 0.52.5",
]
[[package]]
@@ -5149,9 +5181,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pest"
-version = "2.7.9"
+version = "2.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95"
+checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8"
dependencies = [
"memchr",
"thiserror",
@@ -5160,9 +5192,9 @@ dependencies = [
[[package]]
name = "pest_derive"
-version = "2.7.9"
+version = "2.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c"
+checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459"
dependencies = [
"pest",
"pest_generator",
@@ -5170,9 +5202,9 @@ dependencies = [
[[package]]
name = "pest_generator"
-version = "2.7.9"
+version = "2.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd"
+checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687"
dependencies = [
"pest",
"pest_meta",
@@ -5183,9 +5215,9 @@ dependencies = [
[[package]]
name = "pest_meta"
-version = "2.7.9"
+version = "2.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca"
+checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd"
dependencies = [
"once_cell",
"pest",
@@ -5301,15 +5333,15 @@ dependencies = [
[[package]]
name = "polling"
-version = "3.6.0"
+version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0c976a60b2d7e99d6f229e414670a9b85d13ac305cc6d1e9c134de58c5aaaf6"
+checksum = "645493cf344456ef24219d02a768cf1fb92ddf8c92161679ae3d91b91a637be3"
dependencies = [
"cfg-if",
"concurrent-queue",
"hermit-abi",
"pin-project-lite 0.2.14",
- "rustix 0.38.33",
+ "rustix 0.38.34",
"tracing",
"windows-sys 0.52.0",
]
@@ -5502,15 +5534,15 @@ dependencies = [
[[package]]
name = "prometheus"
-version = "0.13.3"
+version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c"
+checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1"
dependencies = [
"cfg-if",
"fnv",
"lazy_static",
"memchr",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"thiserror",
]
@@ -5522,7 +5554,7 @@ checksum = "5d6fa99d535dd930d1249e6c79cb3c2915f9172a540fe2b02a4c8f9ca954721e"
dependencies = [
"dtoa",
"itoa",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"prometheus-client-derive-encode",
]
@@ -5786,6 +5818,15 @@ dependencies = [
"bitflags 1.3.2",
]
+[[package]]
+name = "redox_syscall"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e"
+dependencies = [
+ "bitflags 2.5.0",
+]
+
[[package]]
name = "redox_users"
version = "0.4.5"
@@ -6037,9 +6078,9 @@ dependencies = [
[[package]]
name = "rustix"
-version = "0.38.33"
+version = "0.38.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3cc72858054fcff6d7dea32df2aeaee6a7c24227366d7ea429aada2f26b16ad"
+checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
dependencies = [
"bitflags 2.5.0",
"errno",
@@ -6062,9 +6103,9 @@ dependencies = [
[[package]]
name = "rustls"
-version = "0.21.11"
+version = "0.21.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4"
+checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e"
dependencies = [
"log",
"ring 0.17.8",
@@ -6278,7 +6319,7 @@ dependencies = [
"futures",
"log",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"sc-executor",
"sc-transaction-pool-api",
"sc-utils",
@@ -6309,7 +6350,7 @@ dependencies = [
"log",
"parity-db",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"sc-client-api",
"sc-state-db",
"schnellru",
@@ -6333,7 +6374,7 @@ dependencies = [
"libp2p-identity",
"log",
"mockall",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"sc-client-api",
"sc-utils",
"serde",
@@ -6391,7 +6432,7 @@ dependencies = [
"futures-timer",
"log",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"rand",
"sc-block-builder",
"sc-chain-spec",
@@ -6447,7 +6488,7 @@ version = "0.10.0-dev"
source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.6.0#481165d92297d7dfd5eaf9c7f442441761fc0a12"
dependencies = [
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"sc-executor-common",
"sc-executor-wasmtime",
"schnellru",
@@ -6484,7 +6525,7 @@ dependencies = [
"cfg-if",
"libc",
"log",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"rustix 0.36.17",
"sc-allocator",
"sc-executor-common",
@@ -6516,7 +6557,7 @@ version = "4.0.0-dev"
source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.6.0#481165d92297d7dfd5eaf9c7f442441761fc0a12"
dependencies = [
"array-bytes 6.2.2",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"serde_json",
"sp-application-crypto",
"sp-core",
@@ -6540,7 +6581,7 @@ dependencies = [
"mixnet",
"multiaddr",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"sc-client-api",
"sc-network",
"sc-transaction-pool-api",
@@ -6573,7 +6614,7 @@ dependencies = [
"log",
"mockall",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"partial_sort",
"pin-project",
"rand",
@@ -6745,7 +6786,7 @@ dependencies = [
"num_cpus",
"once_cell",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"rand",
"sc-client-api",
"sc-network",
@@ -6780,7 +6821,7 @@ dependencies = [
"jsonrpsee",
"log",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"sc-block-builder",
"sc-chain-spec",
"sc-client-api",
@@ -6850,7 +6891,7 @@ dependencies = [
"jsonrpsee",
"log",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"sc-chain-spec",
"sc-client-api",
"sc-transaction-pool-api",
@@ -6880,7 +6921,7 @@ dependencies = [
"jsonrpsee",
"log",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"pin-project",
"rand",
"sc-chain-spec",
@@ -6937,7 +6978,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.6.0
dependencies = [
"log",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"sp-core",
]
@@ -6948,7 +6989,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.6.0
dependencies = [
"log",
"parity-db",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"sc-client-api",
"sc-keystore",
"sp-api",
@@ -6989,7 +7030,7 @@ dependencies = [
"futures",
"libp2p",
"log",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"pin-project",
"rand",
"sc-utils",
@@ -7011,7 +7052,7 @@ dependencies = [
"libc",
"log",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"regex",
"rustc-hash",
"sc-client-api",
@@ -7051,7 +7092,7 @@ dependencies = [
"linked-hash-map",
"log",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"sc-client-api",
"sc-transaction-pool-api",
"sc-utils",
@@ -7092,7 +7133,7 @@ dependencies = [
"futures-timer",
"lazy_static",
"log",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"prometheus",
"sp-arithmetic",
]
@@ -7227,11 +7268,11 @@ dependencies = [
[[package]]
name = "security-framework"
-version = "2.10.0"
+version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6"
+checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0"
dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.5.0",
"core-foundation",
"core-foundation-sys",
"libc",
@@ -7240,9 +7281,9 @@ dependencies = [
[[package]]
name = "security-framework-sys"
-version = "2.10.0"
+version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef"
+checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7"
dependencies = [
"core-foundation-sys",
"libc",
@@ -7274,9 +7315,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
-version = "1.0.198"
+version = "1.0.200"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc"
+checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f"
dependencies = [
"serde_derive",
]
@@ -7292,9 +7333,9 @@ dependencies = [
[[package]]
name = "serde_derive"
-version = "1.0.198"
+version = "1.0.200"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9"
+checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb"
dependencies = [
"proc-macro2",
"quote",
@@ -7482,9 +7523,9 @@ dependencies = [
[[package]]
name = "socket2"
-version = "0.5.6"
+version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871"
+checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
dependencies = [
"libc",
"windows-sys 0.52.0",
@@ -7606,7 +7647,7 @@ dependencies = [
"futures",
"log",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"schnellru",
"sp-api",
"sp-consensus",
@@ -7720,7 +7761,7 @@ dependencies = [
"log",
"merlin",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"paste",
"primitive-types",
"rand",
@@ -7769,7 +7810,7 @@ dependencies = [
[[package]]
name = "sp-crypto-ec-utils"
version = "0.10.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#921265ca7889b9c9bc615af0eced9c6918c8af9f"
+source = "git+https://github.com/paritytech/polkadot-sdk#73c89d308fefcedfc3619f0273e13b6623766b81"
dependencies = [
"ark-bls12-377",
"ark-bls12-377-ext",
@@ -7792,7 +7833,7 @@ version = "4.0.0-dev"
source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.6.0#481165d92297d7dfd5eaf9c7f442441761fc0a12"
dependencies = [
"kvdb",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
]
[[package]]
@@ -7808,7 +7849,7 @@ dependencies = [
[[package]]
name = "sp-debug-derive"
version = "14.0.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#921265ca7889b9c9bc615af0eced9c6918c8af9f"
+source = "git+https://github.com/paritytech/polkadot-sdk#73c89d308fefcedfc3619f0273e13b6623766b81"
dependencies = [
"proc-macro2",
"quote",
@@ -7829,7 +7870,7 @@ dependencies = [
[[package]]
name = "sp-externalities"
version = "0.25.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#921265ca7889b9c9bc615af0eced9c6918c8af9f"
+source = "git+https://github.com/paritytech/polkadot-sdk#73c89d308fefcedfc3619f0273e13b6623766b81"
dependencies = [
"environmental",
"parity-scale-codec",
@@ -7901,7 +7942,7 @@ version = "0.27.0"
source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.6.0#481165d92297d7dfd5eaf9c7f442441761fc0a12"
dependencies = [
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"sp-core",
"sp-externalities 0.19.0",
"thiserror",
@@ -8014,7 +8055,7 @@ dependencies = [
[[package]]
name = "sp-runtime-interface"
version = "24.0.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#921265ca7889b9c9bc615af0eced9c6918c8af9f"
+source = "git+https://github.com/paritytech/polkadot-sdk#73c89d308fefcedfc3619f0273e13b6623766b81"
dependencies = [
"bytes",
"impl-trait-for-tuples",
@@ -8046,7 +8087,7 @@ dependencies = [
[[package]]
name = "sp-runtime-interface-proc-macro"
version = "17.0.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#921265ca7889b9c9bc615af0eced9c6918c8af9f"
+source = "git+https://github.com/paritytech/polkadot-sdk#73c89d308fefcedfc3619f0273e13b6623766b81"
dependencies = [
"Inflector",
"expander",
@@ -8093,7 +8134,7 @@ dependencies = [
"hash-db",
"log",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"rand",
"smallvec",
"sp-core",
@@ -8138,7 +8179,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.6.0
[[package]]
name = "sp-std"
version = "14.0.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#921265ca7889b9c9bc615af0eced9c6918c8af9f"
+source = "git+https://github.com/paritytech/polkadot-sdk#73c89d308fefcedfc3619f0273e13b6623766b81"
[[package]]
name = "sp-storage"
@@ -8156,7 +8197,7 @@ dependencies = [
[[package]]
name = "sp-storage"
version = "19.0.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#921265ca7889b9c9bc615af0eced9c6918c8af9f"
+source = "git+https://github.com/paritytech/polkadot-sdk#73c89d308fefcedfc3619f0273e13b6623766b81"
dependencies = [
"impl-serde",
"parity-scale-codec",
@@ -8193,7 +8234,7 @@ dependencies = [
[[package]]
name = "sp-tracing"
version = "16.0.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#921265ca7889b9c9bc615af0eced9c6918c8af9f"
+source = "git+https://github.com/paritytech/polkadot-sdk#73c89d308fefcedfc3619f0273e13b6623766b81"
dependencies = [
"parity-scale-codec",
"tracing",
@@ -8236,7 +8277,7 @@ dependencies = [
"memory-db",
"nohash-hasher",
"parity-scale-codec",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"rand",
"scale-info",
"schnellru",
@@ -8293,7 +8334,7 @@ dependencies = [
[[package]]
name = "sp-wasm-interface"
version = "20.0.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#921265ca7889b9c9bc615af0eced9c6918c8af9f"
+source = "git+https://github.com/paritytech/polkadot-sdk#73c89d308fefcedfc3619f0273e13b6623766b81"
dependencies = [
"impl-trait-for-tuples",
"log",
@@ -8617,7 +8658,7 @@ checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
dependencies = [
"cfg-if",
"fastrand",
- "rustix 0.38.33",
+ "rustix 0.38.34",
"windows-sys 0.52.0",
]
@@ -8636,7 +8677,7 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7"
dependencies = [
- "rustix 0.38.33",
+ "rustix 0.38.34",
"windows-sys 0.48.0",
]
@@ -8767,10 +8808,10 @@ dependencies = [
"libc",
"mio",
"num_cpus",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"pin-project-lite 0.2.14",
"signal-hook-registry",
- "socket2 0.5.6",
+ "socket2 0.5.7",
"tokio-macros",
"windows-sys 0.48.0",
]
@@ -8803,7 +8844,7 @@ version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
dependencies = [
- "rustls 0.21.11",
+ "rustls 0.21.12",
"tokio",
]
@@ -8821,9 +8862,9 @@ dependencies = [
[[package]]
name = "tokio-util"
-version = "0.7.10"
+version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
+checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
dependencies = [
"bytes",
"futures-core",
@@ -8831,7 +8872,6 @@ dependencies = [
"futures-sink",
"pin-project-lite 0.2.14",
"tokio",
- "tracing",
]
[[package]]
@@ -8896,7 +8936,7 @@ dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
- "winnow 0.6.6",
+ "winnow 0.6.8",
]
[[package]]
@@ -9115,7 +9155,7 @@ dependencies = [
"ipconfig",
"lazy_static",
"lru-cache",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"resolv-conf",
"smallvec",
"thiserror",
@@ -9231,9 +9271,9 @@ dependencies = [
[[package]]
name = "unicode-width"
-version = "0.1.11"
+version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
+checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
[[package]]
name = "unicode-xid"
@@ -9750,14 +9790,14 @@ dependencies = [
"either",
"home",
"once_cell",
- "rustix 0.38.33",
+ "rustix 0.38.34",
]
[[package]]
name = "wide"
-version = "0.7.16"
+version = "0.7.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81a1851a719f11d1d2fea40e15c72f6c00de8c142d7ac47c1441cc7e4d0d5bc6"
+checksum = "0f0e39d2c603fdc0504b12b458cf1f34e0b937ed2f4f2dc20796e3e86f34e11f"
dependencies = [
"bytemuck",
"safe_arch",
@@ -9787,11 +9827,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
-version = "0.1.6"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
+checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b"
dependencies = [
- "winapi",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -10044,9 +10084,9 @@ dependencies = [
[[package]]
name = "winnow"
-version = "0.6.6"
+version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352"
+checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d"
dependencies = [
"memchr",
]
@@ -10120,7 +10160,7 @@ dependencies = [
"futures",
"log",
"nohash-hasher",
- "parking_lot 0.12.1",
+ "parking_lot 0.12.2",
"rand",
"static_assertions",
]
@@ -10136,18 +10176,18 @@ dependencies = [
[[package]]
name = "zerocopy"
-version = "0.7.32"
+version = "0.7.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
+checksum = "087eca3c1eaf8c47b94d02790dd086cd594b912d2043d4de4bfdd466b3befb7c"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
-version = "0.7.32"
+version = "0.7.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
+checksum = "6f4b6c273f496d8fd4eaf18853e6b448760225dc030ff2c485a786859aea6393"
dependencies = [
"proc-macro2",
"quote",
diff --git a/node/Cargo.toml b/node/Cargo.toml
index 398c95a..4d8c781 100644
--- a/node/Cargo.toml
+++ b/node/Cargo.toml
@@ -41,6 +41,7 @@ sp-io = { version = "23.0.0", git = "https://github.com/paritytech/polkadot-sdk.
sp-timestamp = { version = "4.0.0-dev", git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.6.0" }
sp-inherents = { version = "4.0.0-dev", git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.6.0" }
sp-keyring = { version = "24.0.0", git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.6.0" }
+sp-keystore = {git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.6.0" }
frame-system = { version = "4.0.0-dev", git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.6.0" }
pallet-transaction-payment = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.6.0" }
diff --git a/node/src/service.rs b/node/src/service.rs
index fabacf9..bfb792f 100644
--- a/node/src/service.rs
+++ b/node/src/service.rs
@@ -66,6 +66,23 @@ pub fn new_partial(
)?;
let client = Arc::new(client);
+
+ let keystore = keystore_container.keystore();
+ if config.offchain_worker.enabled {
+ // Initialize seed for signing transaction using off-chain workers. This is a convenience
+ // so learners can see the transactions submitted simply running the node.
+ // Typically these keys should be inserted with RPC calls to `author_insertKey`.
+
+ // For pallet-ocw
+ sp_keystore::Keystore::sr25519_generate_new(
+ &*keystore,
+ node_template_runtime::pallet_template::KEY_TYPE,
+ Some("//Alice"),
+ ).expect("Creating key with account Alice should succeed.");
+
+ // For pallet-example-offchain-worker
+ }
+
let telemetry = telemetry.map(|(worker, telemetry)| {
task_manager.spawn_handle().spawn("telemetry", None, worker.run());
telemetry
diff --git a/pallets/template/Cargo.toml b/pallets/template/Cargo.toml
index 424b6d8..d090e1e 100644
--- a/pallets/template/Cargo.toml
+++ b/pallets/template/Cargo.toml
@@ -16,15 +16,22 @@ targets = ["x86_64-unknown-linux-gnu"]
codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = [
"derive",
] }
+lite-json = { version = "0.2.0", default-features = false }
+
+serde = { version = "1.0.197", features = ["derive"], optional = true }
+serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
+
scale-info = { version = "2.5.0", default-features = false, features = ["derive"] }
frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.6.0" }
frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.6.0" }
frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.6.0" }
+log = { version = "0.4.21", default-features = false }
+sp-io = { version = "23.0.0", git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.6.0", default-features = false }
+sp-std = { version = "8.0.0", git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.6.0", default-features = false }
+sp-core = { version = "21.0.0", git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.6.0", default-features = false }
+sp-runtime = { version = "24.0.0", git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.6.0", default-features = false }
[dev-dependencies]
-sp-core = { version = "21.0.0", git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.6.0" }
-sp-io = { version = "23.0.0", git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.6.0" }
-sp-runtime = { version = "24.0.0", git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.6.0" }
[features]
default = ["std"]
@@ -34,6 +41,12 @@ std = [
"frame-support/std",
"frame-system/std",
"scale-info/std",
+ "log/std",
+ "sp-io/std",
+ "serde",
+ "sp-std/std",
+ "lite-json/std",
+ "serde_json/std",
]
runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"]
try-runtime = ["frame-support/try-runtime"]
diff --git a/pallets/template/src/lib.rs b/pallets/template/src/lib.rs
index 9550d3d..05779ca 100644
--- a/pallets/template/src/lib.rs
+++ b/pallets/template/src/lib.rs
@@ -1,108 +1,1059 @@
-#![cfg_attr(not(feature = "std"), no_std)]
+// This file is part of Substrate.
-/// Edit this file to define custom logic or remove it if it is not needed.
-/// Learn more about FRAME and the core library of Substrate FRAME pallets:
-///
-pub use pallet::*;
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
-#[cfg(test)]
-mod mock;
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//!
+//! # Offchain Worker Example Pallet
+//!
+//! The Offchain Worker Example: A simple pallet demonstrating
+//! concepts, APIs and structures common to most offchain workers.
+//!
+//! Run `cargo doc --package pallet-example-offchain-worker --open` to view this module's
+//! documentation.
+//!
+//! - [`Config`]
+//! - [`Call`]
+//! - [`Pallet`]
+//!
+//! **This pallet serves as an example showcasing Substrate off-chain worker and is not meant to
+//! be used in production.**
+//!
+//! ## Overview
+//!
+//! In this example we are going to build a very simplistic, naive and definitely NOT
+//! production-ready oracle for BTC/USD price.
+//! Offchain Worker (OCW) will be triggered after every block, fetch the current price
+//! and prepare either signed or unsigned transaction to feed the result back on chain.
+//! The on-chain logic will simply aggregate the results and store last `64` values to compute
+//! the average price.
+//! Additional logic in OCW is put in place to prevent spamming the network with both signed
+//! and unsigned transactions, and custom `UnsignedValidator` makes sure that there is only
+//! one unsigned transaction floating in the network.
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use codec::{Decode, Encode};
+use frame_support::traits::Get;
+use frame_system::{
+ self as system,
+ offchain::{
+ AppCrypto, CreateSignedTransaction, SendSignedTransaction, SendUnsignedTransaction,
+ SignedPayload, Signer, SigningTypes, SubmitTransaction,
+ },
+ pallet_prelude::BlockNumberFor,
+};
+use lite_json::json::JsonValue;
+use scale_info::prelude::string::String;
+use sp_core::crypto::KeyTypeId;
+use sp_runtime::{
+ offchain::{
+ http,
+ storage::{MutateStorageError, StorageRetrievalError, StorageValueRef},
+ Duration,
+ },
+ traits::Zero,
+ transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction},
+ BoundedVec, RuntimeDebug,
+};
+use sp_std::vec::Vec;
#[cfg(test)]
mod tests;
-#[cfg(feature = "runtime-benchmarks")]
-mod benchmarking;
-pub mod weights;
-pub use weights::*;
+/// Defines application identifier for crypto keys of this module.
+///
+/// Every module that deals with signatures needs to declare its unique identifier for
+/// its crypto keys.
+/// When offchain worker is signing transactions it's going to request keys of type
+/// `KeyTypeId` from the keystore and use the ones it finds to sign the transaction.
+/// The keys can be inserted manually via RPC (see `author_insertKey`).
+pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"btc!");
+
+/// Based on the above `KeyTypeId` we need to generate a pallet-specific crypto type wrappers.
+/// We can use from supported crypto kinds (`sr25519`, `ed25519` and `ecdsa`) and augment
+/// the types with this pallet-specific identifier.
+pub mod crypto {
+ use super::KEY_TYPE;
+ use sp_core::sr25519::Signature as Sr25519Signature;
+ use sp_runtime::{
+ app_crypto::{app_crypto, sr25519},
+ traits::Verify,
+ MultiSignature, MultiSigner,
+ };
+ app_crypto!(sr25519, KEY_TYPE);
+
+ pub struct TestAuthId;
+
+ impl frame_system::offchain::AppCrypto for TestAuthId {
+ type RuntimeAppPublic = Public;
+ type GenericSignature = sp_core::sr25519::Signature;
+ type GenericPublic = sp_core::sr25519::Public;
+ }
+
+ // implemented for mock runtime in test
+ impl frame_system::offchain::AppCrypto<::Signer, Sr25519Signature>
+ for TestAuthId
+ {
+ type RuntimeAppPublic = Public;
+ type GenericSignature = sp_core::sr25519::Signature;
+ type GenericPublic = sp_core::sr25519::Public;
+ }
+}
+
+pub use pallet::*;
#[frame_support::pallet]
pub mod pallet {
use super::*;
- use frame_support::pallet_prelude::*;
+ use frame_support::pallet_prelude::{OptionQuery, *};
use frame_system::pallet_prelude::*;
- #[pallet::pallet]
- pub struct Pallet(_);
-
- /// Configure the pallet by specifying the parameters and types on which it depends.
+ /// This pallet's configuration trait
#[pallet::config]
- pub trait Config: frame_system::Config {
- /// Because this pallet emits events, it depends on the runtime's definition of an event.
+ pub trait Config: CreateSignedTransaction> + frame_system::Config {
+ /// The identifier type for an offchain worker.
+ type AuthorityId: AppCrypto;
+
+ /// The overarching event type.
type RuntimeEvent: From> + IsType<::RuntimeEvent>;
- /// Type representing the weight of this pallet
- type WeightInfo: WeightInfo;
+
+ // Configuration parameters
+
+ /// A grace period after we send transaction.
+ ///
+ /// To avoid sending too many transactions, we only attempt to send one
+ /// every `GRACE_PERIOD` blocks. We use Local Storage to coordinate
+ /// sending between distinct runs of this offchain worker.
+ #[pallet::constant]
+ type GracePeriod: Get>;
+
+ /// Number of blocks of cooldown after unsigned transaction is included.
+ ///
+ /// This ensures that we only accept unsigned transactions once, every `UnsignedInterval`
+ /// blocks.
+ #[pallet::constant]
+ type UnsignedInterval: Get>;
+
+ /// A configuration for base priority of unsigned transactions.
+ ///
+ /// This is exposed so that it can be tuned for particular runtime, when
+ /// multiple pallets send unsigned transactions.
+ #[pallet::constant]
+ type UnsignedPriority: Get;
+
+ /// Maximum number of prices.
+ #[pallet::constant]
+ type MaxPrices: Get;
+
+ #[pallet::constant]
+ type StringLimit: Get;
}
- // The pallet's runtime storage items.
- // https://docs.substrate.io/main-docs/build/runtime-storage/
- #[pallet::storage]
- #[pallet::getter(fn something)]
- // Learn more about declaring storage items:
- // https://docs.substrate.io/main-docs/build/runtime-storage/#declaring-storage-items
- pub type Something = StorageValue<_, u32>;
+ // Define string_limit variable of type Get
- // Pallets use events to inform users when important changes are made.
- // https://docs.substrate.io/main-docs/build/events-errors/
- #[pallet::event]
- #[pallet::generate_deposit(pub(super) fn deposit_event)]
- pub enum Event {
- /// Event documentation should end with an array that provides descriptive names for event
- /// parameters. [something, who]
- SomethingStored { something: u32, who: T::AccountId },
+ #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
+ #[derive(
+ Encode,
+ Decode,
+ Clone,
+ PartialEq,
+ Eq,
+ MaxEncodedLen,
+ frame_support::pallet_prelude::RuntimeDebugNoBound,
+ TypeInfo,
+ )]
+ #[scale_info(skip_type_params(T))]
+ pub struct PropertyInfoData {
+ pub id: u32,
+ pub bedrooms: u32,
+ pub bathrooms: u32,
+ pub summary: BoundedVec::StringLimit>,
+ pub property_sub_type: BoundedVec::StringLimit>,
+ pub first_visible_date: BoundedVec::StringLimit>,
+ pub display_size: BoundedVec::StringLimit>,
+ pub display_address: BoundedVec::StringLimit>,
+ // pub property_images: BoundedVec::StringLimit>,
}
- // Errors inform users that something went wrong.
- #[pallet::error]
- pub enum Error {
- /// Error names should be descriptive.
- NoneValue,
- /// Errors should have helpful documentation associated with them.
- StorageOverflow,
+ #[pallet::pallet]
+ pub struct Pallet(_);
+
+ #[pallet::hooks]
+ impl Hooks> for Pallet {
+ /// Offchain Worker entry point.
+ ///
+ /// By implementing `fn offchain_worker` you declare a new offchain worker.
+ /// This function will be called when the node is fully synced and a new best block is
+ /// successfully imported.
+ /// Note that it's not guaranteed for offchain workers to run on EVERY block, there might
+ /// be cases where some blocks are skipped, or for some the worker runs twice (re-orgs),
+ /// so the code should be able to handle that.
+ /// You can use `Local Storage` API to coordinate runs of the worker.
+ fn offchain_worker(block_number: BlockNumberFor) {
+ // Note that having logs compiled to WASM may cause the size of the blob to increase
+ // significantly. You can use `RuntimeDebug` custom derive to hide details of the types
+ // in WASM. The `sp-api` crate also provides a feature `disable-logging` to disable
+ // all logging and thus, remove any logging from the WASM.
+ log::info!("Hello World from offchain workers!");
+
+ let price = Self::fetch_price().map_err(|_| "Failed to fetch price");
+ TestProperties::::put(price.unwrap());
+
+ // Since off-chain workers are just part of the runtime code, they have direct access
+ // to the storage and other included pallets.
+ //
+ // We can easily import `frame_system` and retrieve a block hash of the parent block.
+ let parent_hash = >::block_hash(block_number - 1u32.into());
+ log::debug!("Current block: {:?} (parent hash: {:?})", block_number, parent_hash);
+
+ // It's a good practice to keep `fn offchain_worker()` function minimal, and move most
+ // of the code to separate `impl` block.
+ // Here we call a helper function to calculate current average price.
+ // This function reads storage entries of the current state.
+ let average: Option = Self::average_price();
+ log::debug!("Current price: {:?}", average);
+
+ // For this example we are going to send both signed and unsigned transactions
+ // depending on the block number.
+ // Usually it's enough to choose one or the other.
+ let should_send = Self::choose_transaction_type(block_number);
+ let res = match should_send {
+ TransactionType::Signed => Self::fetch_price_and_send_signed(),
+ TransactionType::UnsignedForAny =>
+ Self::fetch_price_and_send_unsigned_for_any_account(block_number),
+ TransactionType::UnsignedForAll =>
+ Self::fetch_price_and_send_unsigned_for_all_accounts(block_number),
+ TransactionType::Raw => Self::fetch_price_and_send_raw_unsigned(block_number),
+ TransactionType::None => Ok(()),
+ };
+ if let Err(e) = res {
+ log::error!("Error: {}", e);
+ }
+ }
}
- // Dispatchable functions allows users to interact with the pallet and invoke state changes.
- // These functions materialize as "extrinsics", which are often compared to transactions.
- // Dispatchable functions must be annotated with a weight and must return a DispatchResult.
+ /// A public part of the pallet.
#[pallet::call]
impl Pallet {
- /// An example dispatchable that takes a singles value as a parameter, writes the value to
- /// storage and emits an event. This function must be dispatched by a signed extrinsic.
+ /// Submit new price to the list.
+ ///
+ /// This method is a public function of the module and can be called from within
+ /// a transaction. It appends given `price` to current list of prices.
+ /// In our example the `offchain worker` will create, sign & submit a transaction that
+ /// calls this function passing the price.
+ ///
+ /// The transaction needs to be signed (see `ensure_signed`) check, so that the caller
+ /// pays a fee to execute it.
+ /// This makes sure that it's not easy (or rather cheap) to attack the chain by submitting
+ /// excessive transactions, but note that it doesn't ensure the price oracle is actually
+ /// working and receives (and provides) meaningful data.
+ /// This example is not focused on correctness of the oracle itself, but rather its
+ /// purpose is to showcase offchain worker capabilities.
#[pallet::call_index(0)]
- #[pallet::weight(T::WeightInfo::do_something())]
- pub fn do_something(origin: OriginFor, something: u32) -> DispatchResult {
- // Check that the extrinsic was signed and get the signer.
- // This function will return an error if the extrinsic is not signed.
- // https://docs.substrate.io/main-docs/build/origins/
+ #[pallet::weight({0})]
+ pub fn submit_price(
+ origin: OriginFor,
+ price: PropertyInfoData,
+ ) -> DispatchResultWithPostInfo {
+ // Retrieve sender of the transaction.
let who = ensure_signed(origin)?;
+ // Add the price to the on-chain list.
+ // Self::add_price(Some(who), price);
+ TestProperties::::put(price.clone());
+ Self::deposit_event(Event::NewPrice { price: price.id.clone(), who });
+ Ok(().into())
+ }
- // Update storage.
- >::put(something);
+ /// Submit new price to the list via unsigned transaction.
+ ///
+ /// Works exactly like the `submit_price` function, but since we allow sending the
+ /// transaction without a signature, and hence without paying any fees,
+ /// we need a way to make sure that only some transactions are accepted.
+ /// This function can be called only once every `T::UnsignedInterval` blocks.
+ /// Transactions that call that function are de-duplicated on the pool level
+ /// via `validate_unsigned` implementation and also are rendered invalid if
+ /// the function has already been called in current "session".
+ ///
+ /// It's important to specify `weight` for unsigned calls as well, because even though
+ /// they don't charge fees, we still don't want a single block to contain unlimited
+ /// number of such transactions.
+ ///
+ /// This example is not focused on correctness of the oracle itself, but rather its
+ /// purpose is to showcase offchain worker capabilities.
+ #[pallet::call_index(1)]
+ #[pallet::weight({0})]
+ pub fn submit_price_unsigned(
+ origin: OriginFor,
+ _block_number: BlockNumberFor,
+ price: PropertyInfoData,
+ ) -> DispatchResultWithPostInfo {
+ // This ensures that the function can only be called via unsigned transaction.
+ ensure_none(origin)?;
+ // Add the price to the on-chain list, but mark it as coming from an empty address.
+ // Self::add_price(None, price);
+ // now increment the block number at which we expect next unsigned transaction.
+ let current_block = >::block_number();
+ >::put(current_block + T::UnsignedInterval::get());
+ Ok(().into())
+ }
- // Emit an event.
- Self::deposit_event(Event::SomethingStored { something, who });
- // Return a successful DispatchResultWithPostInfo
- Ok(())
+ #[pallet::call_index(2)]
+ #[pallet::weight({0})]
+ pub fn submit_price_unsigned_with_signed_payload(
+ origin: OriginFor,
+ price_payload: PricePayload>,
+ _signature: T::Signature,
+ ) -> DispatchResultWithPostInfo {
+ // This ensures that the function can only be called via unsigned transaction.
+ ensure_none(origin)?;
+ // Add the price to the on-chain list, but mark it as coming from an empty address.
+ // Self::add_price(None, price_payload.price);
+ // now increment the block number at which we expect next unsigned transaction.
+ let current_block = >::block_number();
+ >::put(current_block + T::UnsignedInterval::get());
+ Ok(().into())
}
+ }
- /// An example dispatchable that may throw a custom error.
- #[pallet::call_index(1)]
- #[pallet::weight(T::WeightInfo::cause_error())]
- pub fn cause_error(origin: OriginFor) -> DispatchResult {
- let _who = ensure_signed(origin)?;
-
- // Read a value from storage.
- match >::get() {
- // Return an error if the value has not been set.
- None => return Err(Error::::NoneValue.into()),
- Some(old) => {
- // Increment the value read from storage; will error in the event of overflow.
- let new = old.checked_add(1).ok_or(Error::::StorageOverflow)?;
- // Update the value in storage with the incremented result.
- >::put(new);
- Ok(())
+ /// Events for the pallet.
+ #[pallet::event]
+ #[pallet::generate_deposit(pub(super) fn deposit_event)]
+ pub enum Event {
+ /// Event generated when new price is accepted to contribute to the average.
+ NewPrice { price: u32, who: T::AccountId },
+ }
+
+ #[pallet::validate_unsigned]
+ impl ValidateUnsigned for Pallet {
+ type Call = Call;
+
+ /// Validate unsigned call to this module.
+ ///
+ /// By default unsigned transactions are disallowed, but implementing the validator
+ /// here we make sure that some particular calls (the ones produced by offchain worker)
+ /// are being whitelisted and marked as valid.
+ fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity {
+ // Firstly let's check that we call the right function.
+ if let Call::submit_price_unsigned_with_signed_payload {
+ price_payload: ref payload,
+ ref signature,
+ } = call
+ {
+ let signature_valid =
+ SignedPayload::::verify::(payload, signature.clone());
+ if !signature_valid {
+ return InvalidTransaction::BadProof.into()
+ }
+ Self::validate_transaction_parameters(&payload.block_number)
+ } else if let Call::submit_price_unsigned { block_number, price: new_price } = call {
+ Self::validate_transaction_parameters(block_number)
+ } else {
+ InvalidTransaction::Call.into()
+ }
+ }
+ }
+
+ /// A vector of recently submitted prices.
+ ///
+ /// This is used to calculate average price, should have bounded size.
+ #[pallet::storage]
+ pub(super) type Prices = StorageValue<_, BoundedVec, ValueQuery>;
+
+ /// Defines the block when next unsigned transaction will be accepted.
+ ///
+ /// To prevent spam of unsigned (and unpaid!) transactions on the network,
+ /// we only allow one transaction every `T::UnsignedInterval` blocks.
+ /// This storage entry defines when new transaction is going to be accepted.
+ #[pallet::storage]
+ pub(super) type NextUnsignedAt = StorageValue<_, BlockNumberFor, ValueQuery>;
+
+ // A List of test properties
+ #[pallet::storage]
+ #[pallet::getter(fn testproperties)]
+ pub type TestProperties = StorageValue<_, PropertyInfoData, OptionQuery>;
+}
+
+/// Payload used by this example crate to hold price
+/// data required to submit a transaction.
+#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, scale_info::TypeInfo)]
+pub struct PricePayload {
+ block_number: BlockNumber,
+ price: u32,
+ public: Public,
+}
+
+impl SignedPayload for PricePayload> {
+ fn public(&self) -> T::Public {
+ self.public.clone()
+ }
+}
+
+enum TransactionType {
+ Signed,
+ UnsignedForAny,
+ UnsignedForAll,
+ Raw,
+ None,
+}
+
+impl Pallet {
+ /// Chooses which transaction type to send.
+ ///
+ /// This function serves mostly to showcase `StorageValue` helper
+ /// and local storage usage.
+ ///
+ /// Returns a type of transaction that should be produced in current run.
+ fn choose_transaction_type(block_number: BlockNumberFor) -> TransactionType {
+ /// A friendlier name for the error that is going to be returned in case we are in the grace
+ /// period.
+ const RECENTLY_SENT: () = ();
+
+ // Start off by creating a reference to Local Storage value.
+ // Since the local storage is common for all offchain workers, it's a good practice
+ // to prepend your entry with the module name.
+ let val = StorageValueRef::persistent(b"example_ocw::last_send");
+ // The Local Storage is persisted and shared between runs of the offchain workers,
+ // and offchain workers may run concurrently. We can use the `mutate` function, to
+ // write a storage entry in an atomic fashion. Under the hood it uses `compare_and_set`
+ // low-level method of local storage API, which means that only one worker
+ // will be able to "acquire a lock" and send a transaction if multiple workers
+ // happen to be executed concurrently.
+ let res =
+ val.mutate(|last_send: Result