6 Commits

Author SHA1 Message Date
Luke Parker
a2d558ee34 Have apply return Ok even if calls failed
This ensures fees are paid, and block building isn't interrupted, even for TXs
which error.
2025-02-26 08:00:07 -05:00
Luke Parker
3273a4b725 Serialize BoundedVec not with a u32 length, but the minimum-viable uN where N%8==0
This does break borsh's definition of a Vec EXCEPT if the BoundedVec is
considered an enum. For sufficiently low bounds, this is viable, though it
requires automated code generation to be sane.
2025-02-26 07:41:07 -05:00
Luke Parker
df87abbae0 Correct distinction/flow of check/validate/apply 2025-02-26 07:24:58 -05:00
Luke Parker
fdf2ec8e92 Make transaction an enum of Unsigned, Signed 2025-02-26 06:54:42 -05:00
Luke Parker
f92fe922a6 Remove RuntimeCall from Transaction
I believe this was originally here as we needed to return a reference, not an
owned instance, so this caching enabled returning a reference? Regardless, it
isn't valuable now.
2025-02-26 05:19:04 -05:00
Luke Parker
121a48b55c Add traits necessary for serai_abi::Transaction to be usable in-runtime 2025-02-26 05:05:35 -05:00
13 changed files with 610 additions and 378 deletions

249
Cargo.lock generated
View File

@@ -1052,7 +1052,7 @@ dependencies = [
"bitflags 2.8.0",
"cexpr",
"clang-sys",
"itertools 0.10.5",
"itertools 0.12.1",
"lazy_static",
"lazycell",
"proc-macro2",
@@ -2685,7 +2685,7 @@ checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
[[package]]
name = "fork-tree"
version = "13.0.1"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"parity-scale-codec",
]
@@ -2718,7 +2718,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa"
[[package]]
name = "frame-benchmarking"
version = "39.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"frame-support",
"frame-support-procedural",
@@ -2742,7 +2742,7 @@ dependencies = [
[[package]]
name = "frame-executive"
version = "39.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"frame-support",
"frame-system",
@@ -2771,7 +2771,7 @@ dependencies = [
[[package]]
name = "frame-support"
version = "39.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"array-bytes",
"bitflags 1.3.2",
@@ -2806,7 +2806,7 @@ dependencies = [
[[package]]
name = "frame-support-procedural"
version = "31.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"Inflector",
"cfg-expr",
@@ -2825,7 +2825,7 @@ dependencies = [
[[package]]
name = "frame-support-procedural-tools"
version = "13.0.1"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"frame-support-procedural-tools-derive",
"proc-macro-crate 3.2.0",
@@ -2837,7 +2837,7 @@ dependencies = [
[[package]]
name = "frame-support-procedural-tools-derive"
version = "12.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"proc-macro2",
"quote",
@@ -2847,7 +2847,7 @@ dependencies = [
[[package]]
name = "frame-system"
version = "39.1.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"cfg-if",
"frame-support",
@@ -2866,7 +2866,7 @@ dependencies = [
[[package]]
name = "frame-system-rpc-runtime-api"
version = "35.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"parity-scale-codec",
"sp-api",
@@ -2875,7 +2875,7 @@ dependencies = [
[[package]]
name = "frame-try-runtime"
version = "0.45.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"frame-support",
"parity-scale-codec",
@@ -5618,7 +5618,7 @@ dependencies = [
[[package]]
name = "pallet-authorship"
version = "39.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"frame-support",
"frame-system",
@@ -5631,7 +5631,7 @@ dependencies = [
[[package]]
name = "pallet-babe"
version = "39.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"frame-benchmarking",
"frame-support",
@@ -5654,7 +5654,7 @@ dependencies = [
[[package]]
name = "pallet-grandpa"
version = "39.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"frame-benchmarking",
"frame-support",
@@ -5676,7 +5676,7 @@ dependencies = [
[[package]]
name = "pallet-session"
version = "39.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"frame-support",
"frame-system",
@@ -5697,7 +5697,7 @@ dependencies = [
[[package]]
name = "pallet-timestamp"
version = "38.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"frame-benchmarking",
"frame-support",
@@ -5715,7 +5715,7 @@ dependencies = [
[[package]]
name = "pallet-transaction-payment"
version = "39.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"frame-benchmarking",
"frame-support",
@@ -5731,7 +5731,7 @@ dependencies = [
[[package]]
name = "pallet-transaction-payment-rpc"
version = "42.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"jsonrpsee",
"pallet-transaction-payment-rpc-runtime-api",
@@ -5747,7 +5747,7 @@ dependencies = [
[[package]]
name = "pallet-transaction-payment-rpc-runtime-api"
version = "39.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"pallet-transaction-payment",
"parity-scale-codec",
@@ -6306,7 +6306,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0f3e5beed80eb580c68e2c600937ac2c4eedabdfd5ef1e5b7ea4f3fba84497b"
dependencies = [
"heck 0.5.0",
"itertools 0.10.5",
"itertools 0.13.0",
"log",
"multimap",
"once_cell",
@@ -6326,7 +6326,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "157c5a9d7ea5c2ed2d9fb8f495b64759f7816c7eaea54ba3978f0d63000162e3"
dependencies = [
"anyhow",
"itertools 0.10.5",
"itertools 0.13.0",
"proc-macro2",
"quote",
"syn 2.0.98",
@@ -7076,7 +7076,7 @@ dependencies = [
[[package]]
name = "sc-allocator"
version = "30.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"log",
"sp-core",
@@ -7087,7 +7087,7 @@ dependencies = [
[[package]]
name = "sc-authority-discovery"
version = "0.48.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"async-trait",
"futures",
@@ -7117,7 +7117,7 @@ dependencies = [
[[package]]
name = "sc-basic-authorship"
version = "0.48.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"futures",
"futures-timer",
@@ -7139,7 +7139,7 @@ dependencies = [
[[package]]
name = "sc-block-builder"
version = "0.43.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"parity-scale-codec",
"sp-api",
@@ -7154,7 +7154,7 @@ dependencies = [
[[package]]
name = "sc-chain-spec"
version = "41.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"array-bytes",
"log",
@@ -7180,7 +7180,7 @@ dependencies = [
[[package]]
name = "sc-chain-spec-derive"
version = "12.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
@@ -7191,7 +7191,7 @@ dependencies = [
[[package]]
name = "sc-cli"
version = "0.50.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"array-bytes",
"chrono",
@@ -7232,7 +7232,7 @@ dependencies = [
[[package]]
name = "sc-client-api"
version = "38.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"fnv",
"futures",
@@ -7258,7 +7258,7 @@ dependencies = [
[[package]]
name = "sc-client-db"
version = "0.45.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"hash-db",
"kvdb",
@@ -7284,7 +7284,7 @@ dependencies = [
[[package]]
name = "sc-consensus"
version = "0.47.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"async-trait",
"futures",
@@ -7308,7 +7308,7 @@ dependencies = [
[[package]]
name = "sc-consensus-babe"
version = "0.48.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"async-trait",
"fork-tree",
@@ -7344,7 +7344,7 @@ dependencies = [
[[package]]
name = "sc-consensus-epochs"
version = "0.47.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"fork-tree",
"parity-scale-codec",
@@ -7357,7 +7357,7 @@ dependencies = [
[[package]]
name = "sc-consensus-grandpa"
version = "0.33.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"ahash",
"array-bytes",
@@ -7401,7 +7401,7 @@ dependencies = [
[[package]]
name = "sc-consensus-slots"
version = "0.47.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"async-trait",
"futures",
@@ -7424,7 +7424,7 @@ dependencies = [
[[package]]
name = "sc-executor"
version = "0.41.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"parity-scale-codec",
"parking_lot 0.12.3",
@@ -7446,7 +7446,7 @@ dependencies = [
[[package]]
name = "sc-executor-common"
version = "0.36.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"sc-allocator",
"sp-maybe-compressed-blob",
@@ -7458,7 +7458,7 @@ dependencies = [
[[package]]
name = "sc-executor-wasmtime"
version = "0.36.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"anyhow",
"log",
@@ -7474,7 +7474,7 @@ dependencies = [
[[package]]
name = "sc-informant"
version = "0.47.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"console",
"futures",
@@ -7491,7 +7491,7 @@ dependencies = [
[[package]]
name = "sc-keystore"
version = "34.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"array-bytes",
"parking_lot 0.12.3",
@@ -7505,7 +7505,7 @@ dependencies = [
[[package]]
name = "sc-network"
version = "0.48.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"array-bytes",
"async-channel",
@@ -7551,7 +7551,7 @@ dependencies = [
[[package]]
name = "sc-network-common"
version = "0.47.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"bitflags 1.3.2",
"parity-scale-codec",
@@ -7562,7 +7562,7 @@ dependencies = [
[[package]]
name = "sc-network-gossip"
version = "0.48.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"ahash",
"futures",
@@ -7581,7 +7581,7 @@ dependencies = [
[[package]]
name = "sc-network-light"
version = "0.47.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"array-bytes",
"async-channel",
@@ -7602,7 +7602,7 @@ dependencies = [
[[package]]
name = "sc-network-sync"
version = "0.47.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"array-bytes",
"async-channel",
@@ -7637,7 +7637,7 @@ dependencies = [
[[package]]
name = "sc-network-transactions"
version = "0.47.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"array-bytes",
"futures",
@@ -7656,7 +7656,7 @@ dependencies = [
[[package]]
name = "sc-network-types"
version = "0.15.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"bs58",
"ed25519-dalek",
@@ -7674,7 +7674,7 @@ dependencies = [
[[package]]
name = "sc-offchain"
version = "43.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"futures",
"num_cpus",
@@ -7698,7 +7698,7 @@ dependencies = [
[[package]]
name = "sc-proposer-metrics"
version = "0.18.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"log",
"substrate-prometheus-endpoint",
@@ -7707,7 +7707,7 @@ dependencies = [
[[package]]
name = "sc-rpc"
version = "43.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"futures",
"jsonrpsee",
@@ -7737,7 +7737,7 @@ dependencies = [
[[package]]
name = "sc-rpc-api"
version = "0.47.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"jsonrpsee",
"parity-scale-codec",
@@ -7756,7 +7756,7 @@ dependencies = [
[[package]]
name = "sc-rpc-server"
version = "20.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"dyn-clone",
"forwarded-header-value",
@@ -7780,7 +7780,7 @@ dependencies = [
[[package]]
name = "sc-rpc-spec-v2"
version = "0.48.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"array-bytes",
"futures",
@@ -7812,7 +7812,7 @@ dependencies = [
[[package]]
name = "sc-service"
version = "0.49.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"async-trait",
"directories",
@@ -7875,7 +7875,7 @@ dependencies = [
[[package]]
name = "sc-state-db"
version = "0.37.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"log",
"parity-scale-codec",
@@ -7886,7 +7886,7 @@ dependencies = [
[[package]]
name = "sc-sysinfo"
version = "41.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"derive_more",
"futures",
@@ -7907,7 +7907,7 @@ dependencies = [
[[package]]
name = "sc-telemetry"
version = "28.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"chrono",
"futures",
@@ -7927,7 +7927,7 @@ dependencies = [
[[package]]
name = "sc-tracing"
version = "38.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"chrono",
"console",
@@ -7954,7 +7954,7 @@ dependencies = [
[[package]]
name = "sc-tracing-proc-macro"
version = "11.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
@@ -7965,7 +7965,7 @@ dependencies = [
[[package]]
name = "sc-transaction-pool"
version = "38.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"async-trait",
"futures",
@@ -7996,7 +7996,7 @@ dependencies = [
[[package]]
name = "sc-transaction-pool-api"
version = "38.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"async-trait",
"futures",
@@ -8012,7 +8012,7 @@ dependencies = [
[[package]]
name = "sc-utils"
version = "18.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"async-channel",
"futures",
@@ -8266,9 +8266,11 @@ version = "0.1.0"
dependencies = [
"bitvec",
"borsh",
"frame-support",
"parity-scale-codec",
"scale-info",
"serai-primitives",
"serde",
"sp-core",
"sp-runtime",
]
@@ -8880,6 +8882,7 @@ dependencies = [
"borsh",
"ciphersuite",
"dkg",
"parity-scale-codec",
"sp-core",
"zeroize",
]
@@ -9192,38 +9195,12 @@ dependencies = [
"frame-executive",
"frame-support",
"frame-system",
"frame-system-rpc-runtime-api",
"hashbrown 0.15.2",
"pallet-authorship",
"pallet-babe",
"pallet-grandpa",
"pallet-timestamp",
"pallet-transaction-payment",
"pallet-transaction-payment-rpc-runtime-api",
"parity-scale-codec",
"scale-info",
"serai-abi",
"serai-coins-pallet",
"serai-dex-pallet",
"serai-economic-security-pallet",
"serai-emissions-pallet",
"serai-genesis-liquidity-pallet",
"serai-in-instructions-pallet",
"serai-primitives",
"serai-signals-pallet",
"serai-validator-sets-pallet",
"sp-api",
"sp-authority-discovery",
"sp-block-builder",
"sp-consensus-babe",
"sp-consensus-grandpa",
"sp-core",
"sp-inherents",
"sp-offchain",
"sp-runtime",
"sp-session",
"sp-std",
"sp-transaction-pool",
"sp-version",
"substrate-wasm-builder",
]
@@ -9583,7 +9560,7 @@ dependencies = [
[[package]]
name = "sp-api"
version = "35.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"hash-db",
"log",
@@ -9604,7 +9581,7 @@ dependencies = [
[[package]]
name = "sp-api-proc-macro"
version = "21.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"Inflector",
"blake2",
@@ -9618,7 +9595,7 @@ dependencies = [
[[package]]
name = "sp-application-crypto"
version = "39.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"parity-scale-codec",
"scale-info",
@@ -9630,7 +9607,7 @@ dependencies = [
[[package]]
name = "sp-arithmetic"
version = "26.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"integer-sqrt",
"num-traits",
@@ -9643,7 +9620,7 @@ dependencies = [
[[package]]
name = "sp-authority-discovery"
version = "35.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"parity-scale-codec",
"scale-info",
@@ -9655,7 +9632,7 @@ dependencies = [
[[package]]
name = "sp-block-builder"
version = "35.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"sp-api",
"sp-inherents",
@@ -9665,7 +9642,7 @@ dependencies = [
[[package]]
name = "sp-blockchain"
version = "38.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"futures",
"parity-scale-codec",
@@ -9684,7 +9661,7 @@ dependencies = [
[[package]]
name = "sp-consensus"
version = "0.41.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"async-trait",
"futures",
@@ -9699,7 +9676,7 @@ dependencies = [
[[package]]
name = "sp-consensus-babe"
version = "0.41.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"async-trait",
"parity-scale-codec",
@@ -9717,7 +9694,7 @@ dependencies = [
[[package]]
name = "sp-consensus-grandpa"
version = "22.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"finality-grandpa",
"log",
@@ -9734,7 +9711,7 @@ dependencies = [
[[package]]
name = "sp-consensus-slots"
version = "0.41.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"parity-scale-codec",
"scale-info",
@@ -9745,7 +9722,7 @@ dependencies = [
[[package]]
name = "sp-core"
version = "35.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"array-bytes",
"bitflags 1.3.2",
@@ -9786,7 +9763,7 @@ dependencies = [
[[package]]
name = "sp-crypto-hashing"
version = "0.1.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"blake2b_simd",
"byteorder",
@@ -9797,7 +9774,7 @@ dependencies = [
[[package]]
name = "sp-crypto-hashing-proc-macro"
version = "0.1.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"quote",
"sp-crypto-hashing",
@@ -9807,7 +9784,7 @@ dependencies = [
[[package]]
name = "sp-database"
version = "10.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"kvdb",
"parking_lot 0.12.3",
@@ -9816,7 +9793,7 @@ dependencies = [
[[package]]
name = "sp-debug-derive"
version = "14.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"proc-macro2",
"quote",
@@ -9826,7 +9803,7 @@ dependencies = [
[[package]]
name = "sp-externalities"
version = "0.30.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"environmental",
"parity-scale-codec",
@@ -9836,7 +9813,7 @@ dependencies = [
[[package]]
name = "sp-genesis-builder"
version = "0.16.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"parity-scale-codec",
"scale-info",
@@ -9848,7 +9825,7 @@ dependencies = [
[[package]]
name = "sp-inherents"
version = "35.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"async-trait",
"impl-trait-for-tuples",
@@ -9861,7 +9838,7 @@ dependencies = [
[[package]]
name = "sp-io"
version = "39.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"bytes",
"log",
@@ -9882,7 +9859,7 @@ dependencies = [
[[package]]
name = "sp-keyring"
version = "40.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"sp-core",
"sp-runtime",
@@ -9892,7 +9869,7 @@ dependencies = [
[[package]]
name = "sp-keystore"
version = "0.41.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"parity-scale-codec",
"parking_lot 0.12.3",
@@ -9903,7 +9880,7 @@ dependencies = [
[[package]]
name = "sp-maybe-compressed-blob"
version = "11.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"thiserror 2.0.11",
"zstd 0.13.2",
@@ -9912,7 +9889,7 @@ dependencies = [
[[package]]
name = "sp-metadata-ir"
version = "0.8.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"frame-metadata",
"parity-scale-codec",
@@ -9922,7 +9899,7 @@ dependencies = [
[[package]]
name = "sp-offchain"
version = "35.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"sp-api",
"sp-core",
@@ -9932,7 +9909,7 @@ dependencies = [
[[package]]
name = "sp-panic-handler"
version = "13.0.1"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"backtrace",
"regex",
@@ -9941,7 +9918,7 @@ dependencies = [
[[package]]
name = "sp-rpc"
version = "33.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"rustc-hash 1.1.0",
"serde",
@@ -9951,7 +9928,7 @@ dependencies = [
[[package]]
name = "sp-runtime"
version = "40.1.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"either",
"hash256-std-hasher",
@@ -9977,7 +9954,7 @@ dependencies = [
[[package]]
name = "sp-runtime-interface"
version = "29.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"bytes",
"impl-trait-for-tuples",
@@ -9995,7 +9972,7 @@ dependencies = [
[[package]]
name = "sp-runtime-interface-proc-macro"
version = "18.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"Inflector",
"expander",
@@ -10008,7 +9985,7 @@ dependencies = [
[[package]]
name = "sp-session"
version = "37.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"parity-scale-codec",
"scale-info",
@@ -10022,7 +9999,7 @@ dependencies = [
[[package]]
name = "sp-staking"
version = "37.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"impl-trait-for-tuples",
"parity-scale-codec",
@@ -10035,7 +10012,7 @@ dependencies = [
[[package]]
name = "sp-state-machine"
version = "0.44.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"hash-db",
"log",
@@ -10055,12 +10032,12 @@ dependencies = [
[[package]]
name = "sp-std"
version = "14.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
[[package]]
name = "sp-storage"
version = "22.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"impl-serde",
"parity-scale-codec",
@@ -10072,7 +10049,7 @@ dependencies = [
[[package]]
name = "sp-timestamp"
version = "35.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"async-trait",
"parity-scale-codec",
@@ -10084,7 +10061,7 @@ dependencies = [
[[package]]
name = "sp-tracing"
version = "17.0.1"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"parity-scale-codec",
"tracing",
@@ -10095,7 +10072,7 @@ dependencies = [
[[package]]
name = "sp-transaction-pool"
version = "35.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"sp-api",
"sp-runtime",
@@ -10104,7 +10081,7 @@ dependencies = [
[[package]]
name = "sp-trie"
version = "38.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"ahash",
"hash-db",
@@ -10126,7 +10103,7 @@ dependencies = [
[[package]]
name = "sp-version"
version = "38.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"impl-serde",
"parity-scale-codec",
@@ -10143,7 +10120,7 @@ dependencies = [
[[package]]
name = "sp-version-proc-macro"
version = "15.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"parity-scale-codec",
"proc-macro-warning",
@@ -10155,7 +10132,7 @@ dependencies = [
[[package]]
name = "sp-wasm-interface"
version = "21.0.1"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"anyhow",
"impl-trait-for-tuples",
@@ -10167,7 +10144,7 @@ dependencies = [
[[package]]
name = "sp-weights"
version = "31.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"bounded-collections",
"parity-scale-codec",
@@ -10328,7 +10305,7 @@ dependencies = [
[[package]]
name = "substrate-bip39"
version = "0.6.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"hmac",
"pbkdf2",
@@ -10353,12 +10330,12 @@ dependencies = [
[[package]]
name = "substrate-build-script-utils"
version = "11.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
[[package]]
name = "substrate-frame-rpc-system"
version = "42.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"frame-system-rpc-runtime-api",
"futures",
@@ -10377,7 +10354,7 @@ dependencies = [
[[package]]
name = "substrate-prometheus-endpoint"
version = "0.17.1"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"http-body-util",
"hyper 1.4.1",
@@ -10391,7 +10368,7 @@ dependencies = [
[[package]]
name = "substrate-wasm-builder"
version = "25.0.0"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#1aac7f6d602ea1c4f2059c4e80caacba3cbf3286"
source = "git+https://github.com/serai-dex/polkadot-sdk?branch=serai-next#401f7b8da28413278acd51284ab21bbf98ec1d45"
dependencies = [
"build-helper",
"cargo_metadata",

View File

@@ -28,6 +28,7 @@ serde = { version = "1", default-features = false, features = ["derive"], option
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"], optional = true }
scale-info = { version = "2", default-features = false, features = ["derive"], optional = true }
sp-runtime = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false, features = ["serde"], optional = true }
frame-support = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false, optional = true }
serai-primitives = { path = "../primitives", version = "0.1", default-features = false }
@@ -42,8 +43,10 @@ std = [
"scale?/std",
"scale-info?/std",
"sp-runtime?/std",
"frame-support?/std",
"serai-primitives/std",
]
substrate = ["serde", "scale", "scale-info", "sp-runtime"]
substrate = ["serde", "scale", "scale-info", "sp-runtime", "frame-support"]
try-runtime = ["sp-runtime/try-runtime"]
default = ["std"]

View File

@@ -11,14 +11,13 @@ pub struct HeaderV1 {
///
/// The genesis block has number 0.
pub number: u64,
/// The block this header builds upon.
pub parent_hash: BlockHash,
/// The commitment to the DAG this header builds upon.
pub builds_upon: BlockHash,
/// The UNIX time in milliseconds this block was created at.
pub unix_time_in_millis: u64,
/// The root of a Merkle tree commiting to the transactions within this block.
// TODO: Review the format of this defined by Substrate. We don't want to commit to the signature
// TODO: Some transactions don't have unique hashes due to assuming vaalidators set unique keys
pub transactions_root: [u8; 32],
/// The commitment to the transactions within this block.
// TODO: Some transactions don't have unique hashes due to assuming validators set unique keys
pub transactions_commitment: [u8; 32],
/// A commitment to the consensus data used to justify adding this block to the blockchain.
pub consensus_commitment: [u8; 32],
}
@@ -37,16 +36,16 @@ impl Header {
Header::V1(HeaderV1 { number, .. }) => *number,
}
}
/// Get the hash of the header.
pub fn parent_hash(&self) -> BlockHash {
/// Get the commitment to the DAG this header builds upon.
pub fn builds_upon(&self) -> BlockHash {
match self {
Header::V1(HeaderV1 { parent_hash, .. }) => *parent_hash,
Header::V1(HeaderV1 { builds_upon, .. }) => *builds_upon,
}
}
/// Get the hash of the header.
pub fn transactions_root(&self) -> [u8; 32] {
/// The commitment to the transactions within this block.
pub fn transactions_commitment(&self) -> [u8; 32] {
match self {
Header::V1(HeaderV1 { transactions_root, .. }) => *transactions_root,
Header::V1(HeaderV1 { transactions_commitment, .. }) => *transactions_commitment,
}
}
/// Get the hash of the header.
@@ -69,23 +68,46 @@ pub struct Block {
#[cfg(feature = "substrate")]
mod substrate {
use core::fmt::Debug;
use scale::{Encode, Decode};
use scale_info::TypeInfo;
use sp_core::H256;
use sp_runtime::{
generic::Digest,
generic::{DigestItem, Digest},
traits::{Header as HeaderTrait, HeaderProvider, Block as BlockTrait},
};
use super::*;
/// The digest for all of the Serai-specific header fields.
#[derive(Clone, Copy, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
pub struct SeraiDigest {
/// The commitment to the DAG this header builds upon.
pub builds_upon: BlockHash,
/// The UNIX time in milliseconds this block was created at.
pub unix_time_in_millis: u64,
/// The commitment to the transactions within this block.
pub transactions_commitment: [u8; 32],
}
impl SeraiDigest {
const CONSENSUS_ID: [u8; 4] = *b"SRID";
}
/// The consensus data for a V1 header.
///
/// This is not considered part of the protocol proper and may be pruned in the future. It's
/// solely considered used for consensus now.
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, sp_runtime::Serialize)]
pub struct ConsensusV1 {
/// The hash of the immediately preceding block.
parent_hash: H256,
/// The root for the Merkle tree of transactions, as defined by Substrate.
///
/// The format of this differs from Serai's format for the commitment to the transactions.
transactions_root: H256,
/// The state root.
state_root: H256,
/// The consensus digests.
@@ -96,8 +118,6 @@ mod substrate {
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, sp_runtime::Serialize)]
pub struct SubstrateHeaderV1 {
number: u64,
parent_hash: H256,
transactions_root: H256,
consensus: ConsensusV1,
}
@@ -110,41 +130,40 @@ mod substrate {
impl From<&SubstrateHeader> for Header {
fn from(header: &SubstrateHeader) -> Self {
use sp_consensus_babe::SlotDuration;
use sc_consensus_babe::CompatibleDigestItem;
match header {
SubstrateHeader::V1(header) => Header::V1(HeaderV1 {
number: header.number,
parent_hash: BlockHash(header.parent_hash.0),
unix_time_in_millis: header
.consensus
.digest
.logs()
.iter()
.find_map(|digest_item| {
digest_item.as_babe_pre_digest().map(|pre_digest| {
pre_digest
.slot()
.timestamp(SlotDuration::from_millis(
serai_primitives::constants::TARGET_BLOCK_TIME.as_millis().try_into().unwrap(),
))
// This returns `None` if the slot is so far in the future, it'd cause an
// overflow.
.unwrap_or(sp_timestamp::Timestamp::new(u64::MAX))
.as_millis()
})
})
.unwrap_or(0),
transactions_root: header.transactions_root.0,
consensus_commitment: sp_core::blake2_256(&header.consensus.encode()),
}),
SubstrateHeader::V1(header) => {
let digest =
header.consensus.digest.logs().iter().find_map(|digest_item| match digest_item {
DigestItem::PreRuntime(consensus, encoded)
if *consensus == SeraiDigest::CONSENSUS_ID =>
{
SeraiDigest::deserialize_reader(&mut encoded.as_slice()).ok()
}
_ => None,
});
Header::V1(HeaderV1 {
number: header.number,
builds_upon: digest
.as_ref()
.map(|digest| digest.builds_upon)
.unwrap_or(BlockHash::from([0; 32])),
unix_time_in_millis: digest
.as_ref()
.map(|digest| digest.unix_time_in_millis)
.unwrap_or(0),
transactions_commitment: digest
.as_ref()
.map(|digest| digest.transactions_commitment)
.unwrap_or([0; 32]),
consensus_commitment: sp_core::blake2_256(&header.consensus.encode()),
})
}
}
}
}
/// A block, as needed by Substrate.
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, sp_runtime::Serialize)]
#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode, sp_runtime::Serialize)]
pub struct SubstrateBlock {
header: SubstrateHeader,
#[serde(skip)] // This makes this unsafe to deserialize, but we don't impl `Deserialize`
@@ -165,9 +184,12 @@ mod substrate {
) -> Self {
SubstrateHeader::V1(SubstrateHeaderV1 {
number,
parent_hash,
transactions_root: extrinsics_root,
consensus: ConsensusV1 { state_root, digest },
consensus: ConsensusV1 {
parent_hash,
transactions_root: extrinsics_root,
state_root,
digest,
},
})
}
@@ -186,13 +208,13 @@ mod substrate {
fn extrinsics_root(&self) -> &Self::Hash {
match self {
SubstrateHeader::V1(SubstrateHeaderV1 { transactions_root, .. }) => transactions_root,
SubstrateHeader::V1(SubstrateHeaderV1 { consensus, .. }) => &consensus.transactions_root,
}
}
fn set_extrinsics_root(&mut self, extrinsics_root: Self::Hash) {
match self {
SubstrateHeader::V1(SubstrateHeaderV1 { transactions_root, .. }) => {
*transactions_root = extrinsics_root;
SubstrateHeader::V1(SubstrateHeaderV1 { consensus, .. }) => {
consensus.transactions_root = extrinsics_root;
}
}
}
@@ -212,13 +234,13 @@ mod substrate {
fn parent_hash(&self) -> &Self::Hash {
match self {
SubstrateHeader::V1(SubstrateHeaderV1 { parent_hash, .. }) => parent_hash,
SubstrateHeader::V1(SubstrateHeaderV1 { consensus, .. }) => &consensus.parent_hash,
}
}
fn set_parent_hash(&mut self, parent_hash: Self::Hash) {
match self {
SubstrateHeader::V1(SubstrateHeaderV1 { parent_hash: existing, .. }) => {
*existing = parent_hash;
SubstrateHeader::V1(SubstrateHeaderV1 { consensus, .. }) => {
consensus.parent_hash = parent_hash;
}
}
}

View File

@@ -1,25 +1,33 @@
use core::num::NonZero;
use alloc::{vec, vec::Vec};
use alloc::vec::Vec;
use borsh::{io, BorshSerialize, BorshDeserialize};
use serai_primitives::{address::SeraiAddress, crypto::Signature};
use sp_core::{ConstU32, bounded::BoundedVec};
use serai_primitives::{BlockHash, address::SeraiAddress, balance::Amount, crypto::Signature};
use crate::Call;
// use frame_support::dispatch::GetDispatchInfo;
/// The maximum amount of calls allowed in a transaction.
pub const MAX_CALLS: u32 = 8;
/// An error regarding `SignedCalls`.
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum SignedCallsError {
/// No calls were included.
NoCalls,
/// Too many calls were included.
TooManyCalls,
/// An unsigned call was included.
IncludedUnsignedCall,
}
/// A `Vec` of signed calls.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct SignedCalls(Vec<Call>);
// We don't implement BorshDeserialize due to to maintained invariants on this struct.
#[derive(Clone, PartialEq, Eq, Debug, BorshSerialize)]
pub struct SignedCalls(
#[borsh(serialize_with = "serai_primitives::sp_borsh::borsh_serialize_bounded_vec")]
BoundedVec<Call, ConstU32<{ MAX_CALLS }>>,
);
impl TryFrom<Vec<Call>> for SignedCalls {
type Error = SignedCallsError;
fn try_from(calls: Vec<Call>) -> Result<Self, Self::Error> {
@@ -31,7 +39,7 @@ impl TryFrom<Vec<Call>> for SignedCalls {
Err(SignedCallsError::IncludedUnsignedCall)?;
}
}
Ok(SignedCalls(calls))
calls.try_into().map_err(|_| SignedCallsError::TooManyCalls).map(SignedCalls)
}
}
@@ -43,7 +51,8 @@ pub enum UnsignedCallError {
}
/// An unsigned call.
#[derive(Clone, PartialEq, Eq, Debug)]
// We don't implement BorshDeserialize due to to maintained invariants on this struct.
#[derive(Clone, PartialEq, Eq, Debug, BorshSerialize)]
pub struct UnsignedCall(Call);
impl TryFrom<Call> for UnsignedCall {
type Error = UnsignedCallError;
@@ -58,10 +67,10 @@ impl TryFrom<Call> for UnsignedCall {
/// Part of the context used to sign with, from the protocol.
#[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
pub struct ImplicitContext {
/// The ID of the the protocol.
pub protocol_id: [u8; 32],
/// The genesis hash of the blockchain.
pub genesis: [u8; 32],
pub genesis: BlockHash,
/// The ID of the current protocol.
pub protocol_id: [u8; 32],
}
/// Part of the context used to sign with, specified within the transaction itself.
@@ -70,13 +79,12 @@ pub struct ExplicitContext {
/// The historic block this transaction builds upon.
///
/// This transaction can not be included in a blockchain which does not include this block.
pub historic_block: [u8; 32],
pub historic_block: BlockHash,
/// The block this transaction expires at.
/// The UNIX time this transaction must be included by (and expires after).
///
/// This transaction can not be included in a block whose number is equal or greater to this
/// value.
pub expires_at: Option<NonZero<u64>>,
/// This transaction can not be included in a block whose time is equal or greater to this value.
pub include_by: Option<NonZero<u64>>,
/// The signer.
pub signer: SeraiAddress,
@@ -84,10 +92,10 @@ pub struct ExplicitContext {
/// The signer's nonce.
pub nonce: u32,
/// The fee paid to the network for inclusion.
/// The fee, in SRI, paid to the network for inclusion.
///
/// This fee is paid regardless of the success of any of the calls.
pub fee: u64,
pub fee: Amount,
}
/// A signature, with context.
@@ -99,67 +107,87 @@ pub struct ContextualizedSignature {
signature: Signature,
}
/// The Serai transaction type.
/// A Serai transaction.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Transaction<RuntimeCall: 'static + From<Call> = Call> {
/// The calls, as defined in Serai's ABI.
///
/// These calls are executed atomically. Either all successfully execute or none do. The
/// transaction's fee is paid regardless.
// TODO: Bound
calls: Vec<Call>,
/// The calls, as defined by Substrate.
runtime_calls: Vec<RuntimeCall>,
/// The signature, if present.
contextualized_signature: Option<ContextualizedSignature>,
pub enum Transaction {
/// An unsigned transaction.
Unsigned {
/// The contained call.
call: UnsignedCall,
},
/// A signed transaction.
Signed {
/// The calls.
///
/// These calls are executed atomically. Either all successfully execute or none do. The
/// transaction's fee is paid regardless.
calls: SignedCalls,
/// The signature for this transaction.
///
/// This is not checked on deserializtion and may be invalid.
contextualized_signature: ContextualizedSignature,
},
}
impl<RuntimeCall: 'static + From<Call>> BorshSerialize for Transaction<RuntimeCall> {
impl BorshSerialize for Transaction {
fn serialize<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
// Write the calls
self.calls.serialize(writer)?;
// Write the signature, if present. Presence is deterministic to the calls
if let Some(contextualized_signature) = self.contextualized_signature.as_ref() {
contextualized_signature.serialize(writer)?;
}
Ok(())
}
}
match self {
Transaction::Unsigned { call } => {
/*
`Signed` `Transaction`s encode the length of their `Vec<Call>` here. Since that `Vec` is
bound to be non-empty, it will never write `0`, enabling `Unsigned` to use it.
impl<RuntimeCall: 'static + From<Call>> BorshDeserialize for Transaction<RuntimeCall> {
fn deserialize_reader<R: io::Read>(reader: &mut R) -> io::Result<Self> {
// Read the calls
let calls = Vec::<Call>::deserialize_reader(reader)?;
// Populate the runtime calls
let mut runtime_calls = Vec::with_capacity(calls.len());
for call in calls.iter().cloned() {
runtime_calls.push(RuntimeCall::from(call));
}
// Determine if this is signed or unsigned
let mut signed = None;
for call in &calls {
let call_is_signed = call.is_signed();
if signed.is_none() {
signed = Some(call_is_signed)
};
if signed != Some(call_is_signed) {
Err(io::Error::new(io::ErrorKind::Other, "calls were a mixture of signed and unsigned"))?;
The benefit to these not overlapping is in the ability to determine if the `Transaction`
has a signature or not. If this wrote a `1`, for the amount of `Call`s present in the
`Transaction`, that `Call` would have to be introspected for if its signed or not. With
the usage of `0`, given how low `MAX_CALLS` is, this `Transaction` can technically be
defined as an enum of
`0 Call, 1 Call ContextualizedSignature, 2 Call Call ContextualizedSignature ...`, to
maintain compatbility with the borsh specification without wrapper functions. The checks
here on `Call` types/quantity could be moved to later validation functions.
*/
writer.write_all(&[0])?;
call.serialize(writer)
}
Transaction::Signed { calls, contextualized_signature } => {
serai_primitives::sp_borsh::borsh_serialize_bounded_vec(&calls.0, writer)?;
contextualized_signature.serialize(writer)
}
}
let Some(signed) = signed else {
Err(io::Error::new(io::ErrorKind::Other, "transaction had no calls"))?
};
// Read the signature, if these calls are signed
let contextualized_signature =
if signed { Some(<ContextualizedSignature>::deserialize_reader(reader)?) } else { None };
Ok(Transaction { calls, runtime_calls, contextualized_signature })
}
}
impl<RuntimeCall: 'static + From<Call>> Transaction<RuntimeCall> {
impl BorshDeserialize for Transaction {
fn deserialize_reader<R: io::Read>(reader: &mut R) -> io::Result<Self> {
let mut len = [0xff];
reader.read_exact(&mut len)?;
let len = len[0];
if len == 0 {
let call = Call::deserialize_reader(reader)?;
if call.is_signed() {
Err(io::Error::new(io::ErrorKind::Other, "call was signed but marked unsigned"))?;
}
Ok(Transaction::Unsigned { call: UnsignedCall(call) })
} else {
if u32::from(len) > MAX_CALLS {
Err(io::Error::new(io::ErrorKind::Other, "too many calls"))?;
}
let mut calls = BoundedVec::with_bounded_capacity(len.into());
for _ in 0 .. len {
let call = Call::deserialize_reader(reader)?;
if !call.is_signed() {
Err(io::Error::new(io::ErrorKind::Other, "call was unsigned but included as signed"))?;
}
calls.try_push(call).unwrap();
}
let contextualized_signature = ContextualizedSignature::deserialize_reader(reader)?;
Ok(Transaction::Signed { calls: SignedCalls(calls), contextualized_signature })
}
}
}
impl Transaction {
/// The message to sign to produce a signature.
pub fn signature_message(
calls: &SignedCalls,
@@ -171,149 +199,323 @@ impl<RuntimeCall: 'static + From<Call>> Transaction<RuntimeCall> {
core::mem::size_of::<ImplicitContext>() +
core::mem::size_of::<ExplicitContext>(),
);
calls.0.serialize(&mut message).unwrap();
calls.serialize(&mut message).unwrap();
implicit_context.serialize(&mut message).unwrap();
explicit_context.serialize(&mut message).unwrap();
message
}
/// A transaction with signed calls.
pub fn is_signed(
calls: SignedCalls,
explicit_context: ExplicitContext,
signature: Signature,
) -> Self {
let calls = calls.0;
let mut runtime_calls = Vec::with_capacity(calls.len());
for call in calls.iter().cloned() {
runtime_calls.push(call.into());
}
Self {
calls,
runtime_calls,
contextualized_signature: Some(ContextualizedSignature { explicit_context, signature }),
}
}
/// A transaction with an unsigned call.
pub fn unsigned(call: UnsignedCall) -> Self {
let call = call.0;
Self {
calls: vec![call.clone()],
runtime_calls: vec![call.into()],
contextualized_signature: None,
}
}
}
#[cfg(feature = "substrate")]
mod substrate {
use core::fmt::Debug;
use alloc::vec;
use scale::{Encode, Decode};
use sp_runtime::{
transaction_validity::*,
traits::{Verify, ExtrinsicLike, Dispatchable, ValidateUnsigned, Checkable, Applyable},
Weight,
};
#[rustfmt::skip]
use frame_support::dispatch::{DispatchClass, Pays, DispatchInfo, GetDispatchInfo, PostDispatchInfo};
use super::*;
impl scale::Encode for Transaction {
impl Encode for Transaction {
fn encode(&self) -> Vec<u8> {
borsh::to_vec(self).unwrap()
}
}
impl scale::Decode for Transaction {
impl Decode for Transaction {
fn decode<I: scale::Input>(input: &mut I) -> Result<Self, scale::Error> {
struct ScaleRead<'a, I: scale::Input>(&'a mut I);
struct ScaleRead<'a, I: scale::Input>(&'a mut I, Option<scale::Error>);
impl<I: scale::Input> borsh::io::Read for ScaleRead<'_, I> {
fn read(&mut self, buf: &mut [u8]) -> borsh::io::Result<usize> {
let remaining_len = self
.0
.remaining_len()
.map_err(|err| borsh::io::Error::new(borsh::io::ErrorKind::Other, err))?;
let remaining_len = self.0.remaining_len().map_err(|err| {
self.1 = Some(err);
borsh::io::Error::new(borsh::io::ErrorKind::Other, "")
})?;
// If we're still calling `read`, we try to read at least one more byte
let to_read = buf.len().min(remaining_len.unwrap_or(1));
self
.0
.read(&mut buf[.. to_read])
.map_err(|err| borsh::io::Error::new(borsh::io::ErrorKind::Other, err))?;
self.0.read(&mut buf[.. to_read]).map_err(|err| {
self.1 = Some(err);
borsh::io::Error::new(borsh::io::ErrorKind::Other, "")
})?;
Ok(to_read)
}
}
Self::deserialize_reader(&mut ScaleRead(input)).map_err(|err| err.downcast().unwrap())
let mut input = ScaleRead(input, None);
match Self::deserialize_reader(&mut input) {
Ok(res) => Ok(res),
Err(_) => Err(input.1.unwrap()),
}
}
}
impl<RuntimeCall: 'static + From<Call>> sp_runtime::traits::ExtrinsicLike
for Transaction<RuntimeCall>
{
/// The context which transactions are executed in.
pub trait TransactionContext: 'static + Send + Sync + Clone + PartialEq + Eq + Debug {
/// The base weight for a signed transaction.
const SIGNED_WEIGHT: Weight;
/// The call type for the runtime.
type RuntimeCall: From<Call>
+ GetDispatchInfo
+ Dispatchable<
RuntimeOrigin: From<Option<SeraiAddress>>,
Info = DispatchInfo,
PostInfo = PostDispatchInfo,
>;
/// The implicit context to verify transactions with.
fn implicit_context() -> &'static ImplicitContext;
/// If a block is present in the blockchain.
fn block_is_present_in_blockchain(&self, hash: &BlockHash) -> bool;
/// The time embedded into the current block.
///
/// Returns `None` if the time has yet to be set.
fn current_time(&self) -> Option<u64>;
/// The next nonce for an account.
fn next_nonce(&self, signer: &SeraiAddress) -> u32;
/// If the signer can pay the SRI fee.
fn can_pay_fee(
&self,
signer: &SeraiAddress,
fee: Amount,
) -> Result<(), TransactionValidityError>;
/// Have the transaction pay its SRI fee.
fn pay_fee(&self, signer: &SeraiAddress, fee: Amount) -> Result<(), TransactionValidityError>;
}
/// A transaction with the context necessary to evaluate it within Substrate.
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)]
pub struct TransactionWithContext<Context: TransactionContext>(
Transaction,
#[codec(skip)] Context,
);
impl ExtrinsicLike for Transaction {
fn is_signed(&self) -> Option<bool> {
Some(self.calls[0].is_signed())
Some(matches!(self, Transaction::Signed { .. }))
}
fn is_bare(&self) -> bool {
!self.calls[0].is_signed()
}
}
/*
impl<
Call: 'static + TransactionMember + From<Call> + TryInto<Call>,
> sp_runtime::traits::Extrinsic for Transaction<Call>
{
type Call = Call;
type SignaturePayload = (SeraiAddress, Signature, Extra);
fn is_signed(&self) -> Option<bool> {
Some(self.signature.is_some())
}
fn new(call: Call, signature: Option<Self::SignaturePayload>) -> Option<Self> {
Some(Self { call: call.clone().try_into().ok()?, mapped_call: call, signature })
matches!(self, Transaction::Unsigned { .. })
}
}
impl<
Call: 'static + TransactionMember + From<crate::Call> + TryInto<crate::Call>,
> frame_support::traits::ExtrinsicCall for Transaction<Call, Extra>
{
fn call(&self) -> &Call {
&self.mapped_call
impl<Context: TransactionContext> GetDispatchInfo for TransactionWithContext<Context> {
fn get_dispatch_info(&self) -> DispatchInfo {
match &self.0 {
Transaction::Unsigned { call } => DispatchInfo {
call_weight: Context::RuntimeCall::from(call.0.clone()).get_dispatch_info().call_weight,
extension_weight: Weight::zero(),
class: DispatchClass::Operational,
pays_fee: Pays::No,
},
Transaction::Signed { calls, .. } => DispatchInfo {
call_weight: calls
.0
.iter()
.cloned()
.map(|call| Context::RuntimeCall::from(call).get_dispatch_info().call_weight)
.fold(Weight::zero(), |accum, item| accum + item),
extension_weight: Context::SIGNED_WEIGHT,
class: DispatchClass::Normal,
pays_fee: Pays::Yes,
},
}
}
}
impl<
Call: 'static + TransactionMember + From<crate::Call>,
> sp_runtime::traits::ExtrinsicMetadata for Transaction<Call, Extra>
{
type SignedExtensions = Extra;
impl<Context: TransactionContext> Checkable<Context> for Transaction {
type Checked = TransactionWithContext<Context>;
const VERSION: u8 = 0;
}
impl<
Call: 'static + TransactionMember + From<crate::Call> + GetDispatchInfo,
> GetDispatchInfo for Transaction<Call, Extra>
{
fn get_dispatch_info(&self) -> frame_support::dispatch::DispatchInfo {
self.mapped_call.get_dispatch_info()
}
}
impl<
Call: 'static + TransactionMember + From<crate::Call>,
> sp_runtime::traits::BlindCheckable for Transaction<Call, Extra>
{
type Checked = sp_runtime::generic::CheckedExtrinsic<Public, Call, Extra>;
fn check(
self,
) -> Result<Self::Checked, sp_runtime::transaction_validity::TransactionValidityError> {
Ok(match self.signature {
Some((signer, signature, extra)) => {
if !signature.verify(
(&self.call, &extra, extra.additional_signed()?).encode().as_slice(),
&signer.into(),
fn check(self, context: &Context) -> Result<Self::Checked, TransactionValidityError> {
match &self {
Transaction::Unsigned { .. } => {}
Transaction::Signed {
calls,
contextualized_signature: ContextualizedSignature { explicit_context, signature },
} => {
if !sp_core::sr25519::Signature::from(*signature).verify(
Transaction::signature_message(calls, Context::implicit_context(), explicit_context)
.as_slice(),
&sp_core::sr25519::Public::from(explicit_context.signer),
) {
Err(sp_runtime::transaction_validity::InvalidTransaction::BadProof)?
}
sp_runtime::generic::CheckedExtrinsic {
signed: Some((signer.into(), extra)),
function: self.mapped_call,
Err(InvalidTransaction::BadProof)?;
}
}
None => sp_runtime::generic::CheckedExtrinsic { signed: None, function: self.mapped_call },
})
}
Ok(TransactionWithContext(self, context.clone()))
}
#[cfg(feature = "try-runtime")]
fn unchecked_into_checked_i_know_what_i_am_doing(
self,
c: &Context,
) -> Result<Self::Checked, TransactionValidityError> {
// This satisfies the API, not necessarily the intent, yet this fn is only intended to be used
// within tests. Accordingly, it's fine to be stricter than necessarily
self.check(c)
}
}
impl<Context: TransactionContext> TransactionWithContext<Context> {
fn validate_except_fee<V: ValidateUnsigned<Call = Context::RuntimeCall>>(
&self,
source: TransactionSource,
mempool_priority_if_signed: u64,
) -> TransactionValidity {
match &self.0 {
Transaction::Unsigned { call } => {
let ValidTransaction { priority: _, requires, provides, longevity: _, propagate: _ } =
V::validate_unsigned(source, &Context::RuntimeCall::from(call.0.clone()))?;
Ok(ValidTransaction {
// We should always try to include unsigned transactions prior to signed
priority: u64::MAX,
requires,
provides,
// This is valid until included
longevity: u64::MAX,
// Ensure this is propagated
propagate: true,
})
}
Transaction::Signed { calls: _, contextualized_signature } => {
let ExplicitContext { historic_block, include_by, signer, nonce, fee: _ } =
&contextualized_signature.explicit_context;
if !self.1.block_is_present_in_blockchain(historic_block) {
// We don't know if this is a block from a fundamentally distinct blockchain or a
// continuation of this blockchain we have yet to sync (which would be `Future`)
Err(TransactionValidityError::Unknown(UnknownTransaction::CannotLookup))?;
}
if let Some(include_by) = *include_by {
if let Some(current_time) = self.1.current_time() {
if current_time >= u64::from(include_by) {
// Since this transaction has a time bound which has passed, error
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale))?;
}
} else {
// Since this transaction has a time bound, yet we don't know the time, error
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale))?;
}
}
match self.1.next_nonce(signer).cmp(nonce) {
core::cmp::Ordering::Less => {
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale))?
}
core::cmp::Ordering::Equal => {}
core::cmp::Ordering::Greater => {
Err(TransactionValidityError::Invalid(InvalidTransaction::Future))?
}
}
let requires = if let Some(prior_nonce) = nonce.checked_sub(1) {
vec![borsh::to_vec(&(signer, prior_nonce)).unwrap()]
} else {
vec![]
};
let provides = vec![borsh::to_vec(&(signer, nonce)).unwrap()];
Ok(ValidTransaction {
priority: mempool_priority_if_signed,
requires,
provides,
// This revalidates the transaction every block. This is required due to this being
// denominated in blocks, and our transaction expiration being denominated in seconds.
longevity: 1,
propagate: true,
})
}
}
}
}
impl<Context: TransactionContext> Applyable for TransactionWithContext<Context> {
type Call = Context::RuntimeCall;
fn validate<V: ValidateUnsigned<Call = Context::RuntimeCall>>(
&self,
source: TransactionSource,
info: &DispatchInfo,
_len: usize,
) -> TransactionValidity {
let mempool_priority_if_signed = match &self.0 {
Transaction::Unsigned { .. } => {
// Since this is the priority if signed, and this isn't signed, we return 0
0
}
Transaction::Signed {
calls: _,
contextualized_signature:
ContextualizedSignature { explicit_context: ExplicitContext { signer, fee, .. }, .. },
} => {
self.1.can_pay_fee(signer, *fee)?;
// Prioritize transactions by their fees
{
let fee = fee.0;
Weight::from_all(fee).checked_div_per_component(&info.call_weight).unwrap_or(0)
}
}
};
self.validate_except_fee::<V>(source, mempool_priority_if_signed)
}
fn apply<V: ValidateUnsigned<Call = Context::RuntimeCall>>(
self,
_info: &DispatchInfo,
_len: usize,
) -> sp_runtime::ApplyExtrinsicResultWithInfo<PostDispatchInfo> {
// We use 0 for the mempool priority, as this is no longer in the mempool so it's irrelevant
self.validate_except_fee::<V>(TransactionSource::InBlock, 0)?;
match self.0 {
Transaction::Unsigned { call } => {
let call = Context::RuntimeCall::from(call.0);
V::pre_dispatch(&call)?;
match call.dispatch(None.into()) {
Ok(res) => Ok(Ok(res)),
// Unsigned transactions should only be included if valid in all regards
Err(_err) => Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(0))),
}
}
Transaction::Signed {
calls,
contextualized_signature:
ContextualizedSignature { explicit_context: ExplicitContext { signer, fee, .. }, .. },
} => {
// Start by paying the fee
self.1.pay_fee(&signer, fee)?;
let _res = frame_support::storage::transactional::with_storage_layer(|| {
for call in calls.0 {
let call = Context::RuntimeCall::from(call);
match call.dispatch(Some(signer).into()) {
Ok(_res) => {}
// Because this call errored, don't continue and revert all prior calls
Err(e) => return Err(e),
}
}
Ok(())
});
// We don't care if the individual calls succeeded or failed.
// The transaction was valid for inclusion and the fee was paid.
// Either the calls passed, as desired, or they failed and the storage was reverted.
Ok(Ok(PostDispatchInfo {
// `None` stands for the worst case, which is what we want
actual_weight: None,
// Signed transactions always pay their fee
// TODO: Do we want to handle this so we can not charge fees on removing genesis
// liquidity?
pays_fee: Pays::Yes,
}))
}
}
}
}
*/
}
#[cfg(feature = "substrate")]
pub use substrate::*;

View File

@@ -20,6 +20,7 @@ pub enum Call {
/// The keys being set.
key_pair: KeyPair,
/// The participants in the validator set who signed off on these keys.
// TODO: Bound
#[borsh(
serialize_with = "serai_primitives::sp_borsh::borsh_serialize_bitvec",
deserialize_with = "serai_primitives::sp_borsh::borsh_deserialize_bitvec"

View File

@@ -60,8 +60,8 @@ dockertest = "0.5"
serai-docker-tests = { path = "../../tests/docker" }
[features]
serai = ["thiserror/std", "serde", "serde_json", "serai-abi/serde", "multiaddr", "sp-core", "sp-runtime", "frame-system", "simple-request"]
borsh = ["serai-abi/borsh"]
serai = ["thiserror/std", "serde", "serde_json", "multiaddr", "sp-core", "sp-runtime", "frame-system", "simple-request"]
borsh = []
networks = []
bitcoin = ["networks", "dep:bitcoin"]

View File

@@ -1,4 +1,4 @@
use sp_core::bounded_vec::BoundedVec;
use sp_core::bounded::BoundedVec;
use serai_abi::primitives::{Amount, Coin, ExternalCoin, SeraiAddress};
use crate::{SeraiError, TemporalSerai};

View File

@@ -6,7 +6,7 @@ use rand_core::OsRng;
use sp_core::{
ConstU32,
bounded_vec::BoundedVec,
bounded::BoundedVec,
sr25519::{Pair, Signature},
Pair as PairTrait,
};

View File

@@ -1,6 +1,6 @@
use rand_core::{RngCore, OsRng};
use sp_core::{Pair as PairTrait, bounded_vec::BoundedVec};
use sp_core::{Pair as PairTrait, bounded::BoundedVec};
use serai_abi::in_instructions::primitives::DexCall;

View File

@@ -22,7 +22,7 @@
use super::*;
use frame_benchmarking::{benchmarks, whitelisted_caller};
use frame_support::{assert_ok, storage::bounded_vec::BoundedVec};
use frame_support::{assert_ok, storage::bounded::BoundedVec};
use frame_system::RawOrigin as SystemOrigin;
use sp_runtime::traits::StaticLookup;

View File

@@ -20,6 +20,7 @@ zeroize = { version = "^1.5", features = ["derive"] }
borsh = { version = "1", default-features = false, features = ["derive", "de_strict_order"] }
bitvec = { version = "1", default-features = false, features = ["alloc"] }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
sp-core = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, features = ["alloc", "ristretto"] }

View File

@@ -23,6 +23,8 @@ const HUMAN_READABLE_PART: bech32::Hrp = bech32::Hrp::parse_unchecked("sri");
/// The address for an account on Serai.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Zeroize, BorshSerialize, BorshDeserialize)]
#[rustfmt::skip]
#[derive(scale::Encode, scale::Decode)] // This is safe as scale and borsh share an encoding here
pub struct SeraiAddress(pub [u8; 32]);
impl SeraiAddress {

View File

@@ -2,8 +2,6 @@ use borsh::{io::*, BorshSerialize, BorshDeserialize};
use sp_core::{ConstU32, bounded::BoundedVec};
// TODO: Don't serialize this as a Vec<u8>. Shorten the length-prefix, technically encoding as an
// enum.
pub fn borsh_serialize_bitvec<W: Write>(
bitvec: &bitvec::vec::BitVec<u8, bitvec::order::Lsb0>,
writer: &mut W,
@@ -19,19 +17,45 @@ pub fn borsh_deserialize_bitvec<R: Read>(
Ok(bitvec::vec::BitVec::from_vec(bitvec))
}
type SerializeBoundedVecAs<T> = alloc::vec::Vec<T>;
pub fn borsh_serialize_bounded_vec<W: Write, T: BorshSerialize, const B: u32>(
bounded: &BoundedVec<T, ConstU32<B>>,
writer: &mut W,
) -> Result<()> {
let vec: &SerializeBoundedVecAs<T> = bounded.as_ref();
BorshSerialize::serialize(vec, writer)
// Won't panic as `bytes_for_length` is <= 4
let bytes_for_length =
usize::try_from((u32::BITS - B.leading_zeros()).div_ceil(u8::BITS)).unwrap();
// Won't panic as this vec is bounded to a length specified as a u32
let length = u32::try_from(bounded.len()).unwrap().to_le_bytes();
writer.write_all(&length[0 .. bytes_for_length])?;
for item in bounded.as_slice() {
BorshSerialize::serialize(item, writer)?;
}
Ok(())
}
pub fn borsh_deserialize_bounded_vec<R: Read, T: BorshDeserialize, const B: u32>(
reader: &mut R,
) -> Result<BoundedVec<T, ConstU32<B>>> {
let vec: SerializeBoundedVecAs<T> = BorshDeserialize::deserialize_reader(reader)?;
vec.try_into().map_err(|_| Error::new(ErrorKind::Other, "bound exceeded"))
// Won't panic as `bytes_for_length` is <= 4
let bytes_for_length =
usize::try_from((u32::BITS - B.leading_zeros()).div_ceil(u8::BITS)).unwrap();
let mut length = [0u8; 4];
reader.read_exact(&mut length[.. bytes_for_length])?;
let length = u32::from_le_bytes(length);
if length > B {
Err(Error::new(ErrorKind::Other, "bound exceeded"))?;
}
// Won't panic so long as usize >= u32
const {
assert!(usize::BITS >= u32::BITS, "wasn't compiled for at least a 32-bit platform");
}
let mut vec = alloc::vec::Vec::with_capacity(length.try_into().unwrap());
for _ in 0 .. length {
vec.push(T::deserialize_reader(reader)?);
}
// Won't panic as we already checked against the bound
Ok(vec.try_into().map_err(|_| ()).unwrap())
}