mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 21:01:05 +00:00
rpc: bump jsonrpsee v0.22 and fix race in rpc v2 chain_head (#3230)
Close #2992 Breaking changes: - rpc server grafana metric `substrate_rpc_requests_started` is removed (not possible to implement anymore) - rpc server grafana metric `substrate_rpc_requests_finished` is removed (not possible to implement anymore) - rpc server ws ping/pong not ACK:ed within 30 seconds more than three times then the connection will be closed Added - rpc server grafana metric `substrate_rpc_sessions_time` is added to get the duration for each websocket session
This commit is contained in:
Generated
+186
-84
@@ -86,16 +86,16 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aes-gcm"
|
name = "aes-gcm"
|
||||||
version = "0.9.4"
|
version = "0.9.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6"
|
checksum = "bc3be92e19a7ef47457b8e6f90707e12b6ac5d20c6f3866584fa3be0787d839f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aead 0.4.3",
|
"aead 0.4.3",
|
||||||
"aes 0.7.5",
|
"aes 0.7.5",
|
||||||
"cipher 0.3.0",
|
"cipher 0.3.0",
|
||||||
"ctr 0.8.0",
|
"ctr 0.7.0",
|
||||||
"ghash 0.4.4",
|
"ghash 0.4.4",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -109,7 +109,7 @@ dependencies = [
|
|||||||
"cipher 0.4.4",
|
"cipher 0.4.4",
|
||||||
"ctr 0.9.2",
|
"ctr 0.9.2",
|
||||||
"ghash 0.5.0",
|
"ghash 0.5.0",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1099,7 +1099,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35"
|
checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"concurrent-queue",
|
"concurrent-queue",
|
||||||
"event-listener",
|
"event-listener 2.5.3",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1109,7 +1109,7 @@ version = "1.5.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb"
|
checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-lock",
|
"async-lock 2.8.0",
|
||||||
"async-task",
|
"async-task",
|
||||||
"concurrent-queue",
|
"concurrent-queue",
|
||||||
"fastrand 1.9.0",
|
"fastrand 1.9.0",
|
||||||
@@ -1123,7 +1123,7 @@ version = "1.6.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06"
|
checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-lock",
|
"async-lock 2.8.0",
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"blocking",
|
"blocking",
|
||||||
"futures-lite",
|
"futures-lite",
|
||||||
@@ -1135,7 +1135,7 @@ version = "1.13.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af"
|
checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-lock",
|
"async-lock 2.8.0",
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"concurrent-queue",
|
"concurrent-queue",
|
||||||
@@ -1155,7 +1155,18 @@ version = "2.8.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b"
|
checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"event-listener",
|
"event-listener 2.5.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-lock"
|
||||||
|
version = "3.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b"
|
||||||
|
dependencies = [
|
||||||
|
"event-listener 4.0.3",
|
||||||
|
"event-listener-strategy",
|
||||||
|
"pin-project-lite 0.2.12",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1177,11 +1188,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9"
|
checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-io",
|
"async-io",
|
||||||
"async-lock",
|
"async-lock 2.8.0",
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"blocking",
|
"blocking",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"event-listener",
|
"event-listener 2.5.3",
|
||||||
"futures-lite",
|
"futures-lite",
|
||||||
"rustix 0.37.23",
|
"rustix 0.37.23",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
@@ -1580,7 +1591,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65"
|
checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-channel",
|
"async-channel",
|
||||||
"async-lock",
|
"async-lock 2.8.0",
|
||||||
"async-task",
|
"async-task",
|
||||||
"atomic-waker",
|
"atomic-waker",
|
||||||
"fastrand 1.9.0",
|
"fastrand 1.9.0",
|
||||||
@@ -3467,7 +3478,7 @@ checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array 0.14.7",
|
"generic-array 0.14.7",
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -3499,24 +3510,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
|
checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array 0.14.7",
|
"generic-array 0.14.7",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-mac"
|
name = "crypto-mac"
|
||||||
version = "0.11.1"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714"
|
checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array 0.14.7",
|
"generic-array 0.14.7",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ctr"
|
name = "ctr"
|
||||||
version = "0.8.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea"
|
checksum = "a232f92a03f37dd7d7dd2adc67166c77e9cd88de5b019b9a9eecfaeaf7bfd481"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cipher 0.3.0",
|
"cipher 0.3.0",
|
||||||
]
|
]
|
||||||
@@ -4356,7 +4367,7 @@ dependencies = [
|
|||||||
"byteorder",
|
"byteorder",
|
||||||
"digest 0.8.1",
|
"digest 0.8.1",
|
||||||
"rand_core 0.5.1",
|
"rand_core 0.5.1",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -4369,7 +4380,7 @@ dependencies = [
|
|||||||
"byteorder",
|
"byteorder",
|
||||||
"digest 0.9.0",
|
"digest 0.9.0",
|
||||||
"rand_core 0.5.1",
|
"rand_core 0.5.1",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -4386,7 +4397,7 @@ dependencies = [
|
|||||||
"fiat-crypto",
|
"fiat-crypto",
|
||||||
"platforms",
|
"platforms",
|
||||||
"rustc_version 0.4.0",
|
"rustc_version 0.4.0",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -4610,7 +4621,7 @@ dependencies = [
|
|||||||
"block-buffer 0.10.4",
|
"block-buffer 0.10.4",
|
||||||
"const-oid",
|
"const-oid",
|
||||||
"crypto-common",
|
"crypto-common",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4816,7 +4827,7 @@ dependencies = [
|
|||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"serde",
|
"serde",
|
||||||
"sha2 0.10.7",
|
"sha2 0.10.7",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -4870,7 +4881,7 @@ dependencies = [
|
|||||||
"pkcs8",
|
"pkcs8",
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"sec1",
|
"sec1",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -5098,6 +5109,27 @@ version = "2.5.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "event-listener"
|
||||||
|
version = "4.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e"
|
||||||
|
dependencies = [
|
||||||
|
"concurrent-queue",
|
||||||
|
"parking",
|
||||||
|
"pin-project-lite 0.2.12",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "event-listener-strategy"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3"
|
||||||
|
dependencies = [
|
||||||
|
"event-listener 4.0.3",
|
||||||
|
"pin-project-lite 0.2.12",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "exit-future"
|
name = "exit-future"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@@ -5244,7 +5276,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449"
|
checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -5861,9 +5893,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures"
|
name = "futures"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
|
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@@ -5892,9 +5924,9 @@ checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-executor"
|
name = "futures-executor"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
|
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
@@ -6166,7 +6198,7 @@ checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"ff",
|
"ff",
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -6319,7 +6351,7 @@ version = "0.11.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b"
|
checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crypto-mac 0.11.1",
|
"crypto-mac 0.11.0",
|
||||||
"digest 0.9.0",
|
"digest 0.9.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -6447,9 +6479,9 @@ dependencies = [
|
|||||||
"hyper",
|
"hyper",
|
||||||
"log",
|
"log",
|
||||||
"rustls 0.21.6",
|
"rustls 0.21.6",
|
||||||
"rustls-native-certs",
|
"rustls-native-certs 0.6.3",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls",
|
"tokio-rustls 0.24.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -6777,9 +6809,9 @@ checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpsee"
|
name = "jsonrpsee"
|
||||||
version = "0.20.3"
|
version = "0.22.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "affdc52f7596ccb2d7645231fc6163bb314630c989b64998f3699a28b4d5d4dc"
|
checksum = "4a95f7cc23d5fab0cdeeaf6bad8c8f5e7a3aa7f0d211957ea78232b327ab27b0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jsonrpsee-core",
|
"jsonrpsee-core",
|
||||||
"jsonrpsee-http-client",
|
"jsonrpsee-http-client",
|
||||||
@@ -6793,19 +6825,20 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpsee-client-transport"
|
name = "jsonrpsee-client-transport"
|
||||||
version = "0.20.3"
|
version = "0.22.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b5b005c793122d03217da09af68ba9383363caa950b90d3436106df8cabce935"
|
checksum = "6b1736cfa3845fd9f8f43751f2b8e0e83f7b6081e754502f7d63b6587692cc83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http",
|
"http",
|
||||||
"jsonrpsee-core",
|
"jsonrpsee-core",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"rustls-native-certs",
|
"rustls-native-certs 0.7.0",
|
||||||
|
"rustls-pki-types",
|
||||||
"soketto",
|
"soketto",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls",
|
"tokio-rustls 0.25.0",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tracing",
|
"tracing",
|
||||||
"url",
|
"url",
|
||||||
@@ -6813,12 +6846,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpsee-core"
|
name = "jsonrpsee-core"
|
||||||
version = "0.20.3"
|
version = "0.22.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "da2327ba8df2fdbd5e897e2b5ed25ce7f299d345b9736b6828814c3dbd1fd47b"
|
checksum = "82030d038658974732103e623ba2e0abec03bbbe175b39c0a2fafbada60c5868"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-lock",
|
"async-lock 3.3.0",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"beef",
|
"beef",
|
||||||
"futures-timer",
|
"futures-timer",
|
||||||
@@ -6826,21 +6859,22 @@ dependencies = [
|
|||||||
"hyper",
|
"hyper",
|
||||||
"jsonrpsee-types",
|
"jsonrpsee-types",
|
||||||
"parking_lot 0.12.1",
|
"parking_lot 0.12.1",
|
||||||
|
"pin-project",
|
||||||
"rand",
|
"rand",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"soketto",
|
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpsee-http-client"
|
name = "jsonrpsee-http-client"
|
||||||
version = "0.20.3"
|
version = "0.22.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5f80c17f62c7653ce767e3d7288b793dfec920f97067ceb189ebdd3570f2bc20"
|
checksum = "36a06ef0de060005fddf772d54597bb6a8b0413da47dcffd304b0306147b9678"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"hyper",
|
"hyper",
|
||||||
@@ -6858,12 +6892,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpsee-proc-macros"
|
name = "jsonrpsee-proc-macros"
|
||||||
version = "0.20.3"
|
version = "0.22.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "29110019693a4fa2dbda04876499d098fa16d70eba06b1e6e2b3f1b251419515"
|
checksum = "69fc56131589f82e57805f7338b87023db4aafef813555708b159787e34ad6bc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro-crate 1.3.1",
|
"proc-macro-crate 3.0.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
@@ -6871,15 +6905,16 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpsee-server"
|
name = "jsonrpsee-server"
|
||||||
version = "0.20.3"
|
version = "0.22.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "82c39a00449c9ef3f50b84fc00fc4acba20ef8f559f07902244abf4c15c5ab9c"
|
checksum = "d85be77fe5b2a94589e3164fb780017f7aff7d646b49278c0d0346af16975c8e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http",
|
"http",
|
||||||
"hyper",
|
"hyper",
|
||||||
"jsonrpsee-core",
|
"jsonrpsee-core",
|
||||||
"jsonrpsee-types",
|
"jsonrpsee-types",
|
||||||
|
"pin-project",
|
||||||
"route-recognizer",
|
"route-recognizer",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -6894,23 +6929,22 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpsee-types"
|
name = "jsonrpsee-types"
|
||||||
version = "0.20.3"
|
version = "0.22.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5be0be325642e850ed0bdff426674d2e66b2b7117c9be23a7caef68a2902b7d9"
|
checksum = "9a48fdc1202eafc51c63e00406575e59493284ace8b8b61aa16f3a6db5d64f1a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"beef",
|
"beef",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tracing",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpsee-ws-client"
|
name = "jsonrpsee-ws-client"
|
||||||
version = "0.20.3"
|
version = "0.22.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bca9cb3933ccae417eb6b08c3448eb1cb46e39834e5b503e395e5e5bd08546c0"
|
checksum = "c5ce25d70a8e4d3cc574bbc3cad0137c326ad64b194793d5e7bbdd3fa4504181"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"http",
|
"http",
|
||||||
"jsonrpsee-client-transport",
|
"jsonrpsee-client-transport",
|
||||||
@@ -7639,7 +7673,7 @@ checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"crunchy",
|
"crunchy",
|
||||||
"digest 0.9.0",
|
"digest 0.9.0",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -8136,7 +8170,7 @@ dependencies = [
|
|||||||
"rand",
|
"rand",
|
||||||
"rand_chacha 0.3.1",
|
"rand_chacha 0.3.1",
|
||||||
"rand_distr",
|
"rand_distr",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
@@ -11542,7 +11576,7 @@ version = "0.8.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa"
|
checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crypto-mac 0.11.1",
|
"crypto-mac 0.11.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -13859,7 +13893,7 @@ checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cpufeatures",
|
"cpufeatures",
|
||||||
"opaque-debug 0.3.0",
|
"opaque-debug 0.3.0",
|
||||||
"universal-hash 0.4.1",
|
"universal-hash 0.4.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -13882,7 +13916,7 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures",
|
||||||
"opaque-debug 0.3.0",
|
"opaque-debug 0.3.0",
|
||||||
"universal-hash 0.4.1",
|
"universal-hash 0.4.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -14705,12 +14739,12 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite 0.2.12",
|
"pin-project-lite 0.2.12",
|
||||||
"rustls 0.21.6",
|
"rustls 0.21.6",
|
||||||
"rustls-pemfile",
|
"rustls-pemfile 1.0.3",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls",
|
"tokio-rustls 0.24.1",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"url",
|
"url",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
@@ -14737,7 +14771,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2"
|
checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hmac 0.12.1",
|
"hmac 0.12.1",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -15218,10 +15252,24 @@ checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"ring 0.16.20",
|
"ring 0.16.20",
|
||||||
"rustls-webpki",
|
"rustls-webpki 0.101.4",
|
||||||
"sct",
|
"sct",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls"
|
||||||
|
version = "0.22.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"ring 0.17.7",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"rustls-webpki 0.102.2",
|
||||||
|
"subtle 2.5.0",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-native-certs"
|
name = "rustls-native-certs"
|
||||||
version = "0.6.3"
|
version = "0.6.3"
|
||||||
@@ -15229,7 +15277,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
|
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"openssl-probe",
|
"openssl-probe",
|
||||||
"rustls-pemfile",
|
"rustls-pemfile 1.0.3",
|
||||||
|
"schannel",
|
||||||
|
"security-framework",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-native-certs"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792"
|
||||||
|
dependencies = [
|
||||||
|
"openssl-probe",
|
||||||
|
"rustls-pemfile 2.0.0",
|
||||||
|
"rustls-pki-types",
|
||||||
"schannel",
|
"schannel",
|
||||||
"security-framework",
|
"security-framework",
|
||||||
]
|
]
|
||||||
@@ -15243,6 +15304,22 @@ dependencies = [
|
|||||||
"base64 0.21.2",
|
"base64 0.21.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-pemfile"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "35e4980fa29e4c4b212ffb3db068a564cbf560e51d3944b7c88bd8bf5bec64f4"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.21.2",
|
||||||
|
"rustls-pki-types",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-pki-types"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0a716eb65e3158e90e17cd93d855216e27bde02745ab842f2cab4a39dba1bacf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
version = "0.101.4"
|
version = "0.101.4"
|
||||||
@@ -15253,6 +15330,17 @@ dependencies = [
|
|||||||
"untrusted 0.7.1",
|
"untrusted 0.7.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-webpki"
|
||||||
|
version = "0.102.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610"
|
||||||
|
dependencies = [
|
||||||
|
"ring 0.17.7",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"untrusted 0.9.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.14"
|
version = "1.0.14"
|
||||||
@@ -16410,9 +16498,12 @@ dependencies = [
|
|||||||
name = "sc-rpc-server"
|
name = "sc-rpc-server"
|
||||||
version = "11.0.0"
|
version = "11.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"futures",
|
||||||
"http",
|
"http",
|
||||||
|
"hyper",
|
||||||
"jsonrpsee",
|
"jsonrpsee",
|
||||||
"log",
|
"log",
|
||||||
|
"pin-project",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"substrate-prometheus-endpoint",
|
"substrate-prometheus-endpoint",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -16860,7 +16951,7 @@ dependencies = [
|
|||||||
"merlin 2.0.1",
|
"merlin 2.0.1",
|
||||||
"rand_core 0.5.1",
|
"rand_core 0.5.1",
|
||||||
"sha2 0.8.2",
|
"sha2 0.8.2",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -16895,7 +16986,7 @@ dependencies = [
|
|||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"serde_bytes",
|
"serde_bytes",
|
||||||
"sha2 0.10.7",
|
"sha2 0.10.7",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -16937,7 +17028,7 @@ dependencies = [
|
|||||||
"der",
|
"der",
|
||||||
"generic-array 0.14.7",
|
"generic-array 0.14.7",
|
||||||
"pkcs8",
|
"pkcs8",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -17457,7 +17548,7 @@ dependencies = [
|
|||||||
"async-executor",
|
"async-executor",
|
||||||
"async-fs",
|
"async-fs",
|
||||||
"async-io",
|
"async-io",
|
||||||
"async-lock",
|
"async-lock 2.8.0",
|
||||||
"async-net",
|
"async-net",
|
||||||
"async-process",
|
"async-process",
|
||||||
"blocking",
|
"blocking",
|
||||||
@@ -17480,7 +17571,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "c0bb30cf57b7b5f6109ce17c3164445e2d6f270af2cb48f6e4d31c2967c9a9f5"
|
checksum = "c0bb30cf57b7b5f6109ce17c3164445e2d6f270af2cb48f6e4d31c2967c9a9f5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec 0.7.4",
|
"arrayvec 0.7.4",
|
||||||
"async-lock",
|
"async-lock 2.8.0",
|
||||||
"atomic-take",
|
"atomic-take",
|
||||||
"base64 0.21.2",
|
"base64 0.21.2",
|
||||||
"bip39",
|
"bip39",
|
||||||
@@ -17491,7 +17582,7 @@ dependencies = [
|
|||||||
"derive_more",
|
"derive_more",
|
||||||
"ed25519-zebra 4.0.3",
|
"ed25519-zebra 4.0.3",
|
||||||
"either",
|
"either",
|
||||||
"event-listener",
|
"event-listener 2.5.3",
|
||||||
"fnv",
|
"fnv",
|
||||||
"futures-lite",
|
"futures-lite",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@@ -17534,12 +17625,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "256b5bad1d6b49045e95fe87492ce73d5af81545d8b4d8318a872d2007024c33"
|
checksum = "256b5bad1d6b49045e95fe87492ce73d5af81545d8b4d8318a872d2007024c33"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-channel",
|
"async-channel",
|
||||||
"async-lock",
|
"async-lock 2.8.0",
|
||||||
"base64 0.21.2",
|
"base64 0.21.2",
|
||||||
"blake2-rfc",
|
"blake2-rfc",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"either",
|
"either",
|
||||||
"event-listener",
|
"event-listener 2.5.3",
|
||||||
"fnv",
|
"fnv",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-lite",
|
"futures-lite",
|
||||||
@@ -17575,7 +17666,7 @@ version = "0.9.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0c9d1425eb528a21de2755c75af4c9b5d57f50a0d4c3b7f1828a4cd03f8ba155"
|
checksum = "0c9d1425eb528a21de2755c75af4c9b5d57f50a0d4c3b7f1828a4cd03f8ba155"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes-gcm 0.9.4",
|
"aes-gcm 0.9.2",
|
||||||
"blake2 0.10.6",
|
"blake2 0.10.6",
|
||||||
"chacha20poly1305",
|
"chacha20poly1305",
|
||||||
"curve25519-dalek 4.1.2",
|
"curve25519-dalek 4.1.2",
|
||||||
@@ -17583,7 +17674,7 @@ dependencies = [
|
|||||||
"ring 0.16.20",
|
"ring 0.16.20",
|
||||||
"rustc_version 0.4.0",
|
"rustc_version 0.4.0",
|
||||||
"sha2 0.10.7",
|
"sha2 0.10.7",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -19425,7 +19516,7 @@ dependencies = [
|
|||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"keccak",
|
"keccak",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -19757,9 +19848,9 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "2.4.1"
|
version = "2.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle-ng"
|
name = "subtle-ng"
|
||||||
@@ -20339,6 +20430,17 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-rustls"
|
||||||
|
version = "0.25.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
|
||||||
|
dependencies = [
|
||||||
|
"rustls 0.22.2",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-stream"
|
name = "tokio-stream"
|
||||||
version = "0.1.14"
|
version = "0.1.14"
|
||||||
@@ -20888,12 +20990,12 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "universal-hash"
|
name = "universal-hash"
|
||||||
version = "0.4.1"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05"
|
checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array 0.14.7",
|
"generic-array 0.14.7",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -20903,7 +21005,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
|
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crypto-common",
|
"crypto-common",
|
||||||
"subtle 2.4.1",
|
"subtle 2.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -22,5 +22,5 @@ sc-client-api = { path = "../../../substrate/client/api" }
|
|||||||
futures = "0.3.28"
|
futures = "0.3.28"
|
||||||
async-trait = "0.1.74"
|
async-trait = "0.1.74"
|
||||||
thiserror = "1.0.48"
|
thiserror = "1.0.48"
|
||||||
jsonrpsee-core = "0.20.3"
|
jsonrpsee-core = "0.22"
|
||||||
parity-scale-codec = "3.6.4"
|
parity-scale-codec = "3.6.4"
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ use sc_client_api::StorageProof;
|
|||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use jsonrpsee_core::Error as JsonRpcError;
|
use jsonrpsee_core::ClientError as JsonRpcError;
|
||||||
use parity_scale_codec::Error as CodecError;
|
use parity_scale_codec::Error as CodecError;
|
||||||
use sp_api::ApiError;
|
use sp_api::ApiError;
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ tokio-util = { version = "0.7.8", features = ["compat"] }
|
|||||||
futures = "0.3.28"
|
futures = "0.3.28"
|
||||||
futures-timer = "3.0.2"
|
futures-timer = "3.0.2"
|
||||||
parity-scale-codec = "3.6.4"
|
parity-scale-codec = "3.6.4"
|
||||||
jsonrpsee = { version = "0.20.3", features = ["ws-client"] }
|
jsonrpsee = { version = "0.22", features = ["ws-client"] }
|
||||||
tracing = "0.1.37"
|
tracing = "0.1.37"
|
||||||
async-trait = "0.1.74"
|
async-trait = "0.1.74"
|
||||||
url = "2.4.0"
|
url = "2.4.0"
|
||||||
|
|||||||
@@ -19,12 +19,9 @@
|
|||||||
//! we treat the light-client as a normal JsonRPC target.
|
//! we treat the light-client as a normal JsonRPC target.
|
||||||
|
|
||||||
use futures::{channel::mpsc::Sender, prelude::*, stream::FuturesUnordered};
|
use futures::{channel::mpsc::Sender, prelude::*, stream::FuturesUnordered};
|
||||||
use jsonrpsee::core::{
|
use jsonrpsee::core::client::{
|
||||||
client::{
|
Client as JsonRpseeClient, ClientBuilder, ClientT, Error, ReceivedMessage, TransportReceiverT,
|
||||||
Client as JsonRpseeClient, ClientBuilder, ClientT, ReceivedMessage, TransportReceiverT,
|
TransportSenderT,
|
||||||
TransportSenderT,
|
|
||||||
},
|
|
||||||
Error,
|
|
||||||
};
|
};
|
||||||
use smoldot_light::{ChainId, Client as SmoldotClient, JsonRpcResponses};
|
use smoldot_light::{ChainId, Client as SmoldotClient, JsonRpcResponses};
|
||||||
use std::{num::NonZeroU32, sync::Arc};
|
use std::{num::NonZeroU32, sync::Arc};
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ use jsonrpsee::{
|
|||||||
core::{
|
core::{
|
||||||
client::{Client as JsonRpcClient, ClientT, Subscription},
|
client::{Client as JsonRpcClient, ClientT, Subscription},
|
||||||
params::ArrayParams,
|
params::ArrayParams,
|
||||||
Error as JsonRpseeError, JsonValue,
|
ClientError as JsonRpseeError, JsonValue,
|
||||||
},
|
},
|
||||||
ws_client::WsClientBuilder,
|
ws_client::WsClientBuilder,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use futures::channel::{
|
|||||||
oneshot::Sender as OneshotSender,
|
oneshot::Sender as OneshotSender,
|
||||||
};
|
};
|
||||||
use jsonrpsee::{
|
use jsonrpsee::{
|
||||||
core::{params::ArrayParams, Error as JsonRpseeError},
|
core::{params::ArrayParams, ClientError as JsonRpseeError},
|
||||||
rpc_params,
|
rpc_params,
|
||||||
};
|
};
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ clap = { version = "4.4.18", features = ["derive"] }
|
|||||||
log = { workspace = true, default-features = true }
|
log = { workspace = true, default-features = true }
|
||||||
codec = { package = "parity-scale-codec", version = "3.0.0" }
|
codec = { package = "parity-scale-codec", version = "3.0.0" }
|
||||||
serde = { version = "1.0.195", features = ["derive"] }
|
serde = { version = "1.0.195", features = ["derive"] }
|
||||||
jsonrpsee = { version = "0.20.3", features = ["server"] }
|
jsonrpsee = { version = "0.22", features = ["server"] }
|
||||||
futures = "0.3.28"
|
futures = "0.3.28"
|
||||||
serde_json = "1.0.111"
|
serde_json = "1.0.111"
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ coretime-rococo-runtime = { path = "../parachains/runtimes/coretime/coretime-roc
|
|||||||
coretime-westend-runtime = { path = "../parachains/runtimes/coretime/coretime-westend" }
|
coretime-westend-runtime = { path = "../parachains/runtimes/coretime/coretime-westend" }
|
||||||
bridge-hub-westend-runtime = { path = "../parachains/runtimes/bridge-hubs/bridge-hub-westend" }
|
bridge-hub-westend-runtime = { path = "../parachains/runtimes/bridge-hubs/bridge-hub-westend" }
|
||||||
penpal-runtime = { path = "../parachains/runtimes/testing/penpal" }
|
penpal-runtime = { path = "../parachains/runtimes/testing/penpal" }
|
||||||
jsonrpsee = { version = "0.20.3", features = ["server"] }
|
jsonrpsee = { version = "0.22", features = ["server"] }
|
||||||
people-rococo-runtime = { path = "../parachains/runtimes/people/people-rococo" }
|
people-rococo-runtime = { path = "../parachains/runtimes/people/people-rococo" }
|
||||||
people-westend-runtime = { path = "../parachains/runtimes/people/people-westend" }
|
people-westend-runtime = { path = "../parachains/runtimes/people/people-westend" }
|
||||||
parachains-common = { path = "../parachains/common" }
|
parachains-common = { path = "../parachains/common" }
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ async-trait = "0.1.74"
|
|||||||
clap = { version = "4.4.18", features = ["derive"] }
|
clap = { version = "4.4.18", features = ["derive"] }
|
||||||
codec = { package = "parity-scale-codec", version = "3.0.0" }
|
codec = { package = "parity-scale-codec", version = "3.0.0" }
|
||||||
criterion = { version = "0.5.1", features = ["async_tokio"] }
|
criterion = { version = "0.5.1", features = ["async_tokio"] }
|
||||||
jsonrpsee = { version = "0.20.3", features = ["server"] }
|
jsonrpsee = { version = "0.22", features = ["server"] }
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
serde = { version = "1.0.195", features = ["derive"] }
|
serde = { version = "1.0.195", features = ["derive"] }
|
||||||
serde_json = "1.0.111"
|
serde_json = "1.0.111"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ description = "Polkadot specific RPC functionality."
|
|||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
jsonrpsee = { version = "0.20.3", features = ["server"] }
|
jsonrpsee = { version = "0.22", features = ["server"] }
|
||||||
polkadot-primitives = { path = "../primitives" }
|
polkadot-primitives = { path = "../primitives" }
|
||||||
sc-client-api = { path = "../../substrate/client/api" }
|
sc-client-api = { path = "../../substrate/client/api" }
|
||||||
sp-blockchain = { path = "../../substrate/primitives/blockchain" }
|
sp-blockchain = { path = "../../substrate/primitives/blockchain" }
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
|
||||||
|
# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
|
||||||
|
|
||||||
|
title: rpc server remove prometheus metrics `substrate_rpc_requests_started/finished` and refactor WS ping/pongs.
|
||||||
|
|
||||||
|
doc:
|
||||||
|
- audience: Node Operator
|
||||||
|
description: |
|
||||||
|
This PR updates the rpc server library to `jsonrpsee v0.22` to utilize new APIs.
|
||||||
|
|
||||||
|
Breaking changes:
|
||||||
|
- Remove prometheus RPC metrics `substrate_rpc_requests_started` and `substrate_rpc_requests_finished`.
|
||||||
|
- The RPC server now disconnects inactive peers that didn't acknowledge WebSocket
|
||||||
|
pings more than three times in time.
|
||||||
|
|
||||||
|
Added:
|
||||||
|
- Add prometheus RPC `substrate_rpc_sessions_time` to collect the duration for each WebSocket
|
||||||
|
session.
|
||||||
|
crates: [ ]
|
||||||
@@ -23,7 +23,7 @@ name = "minimal-node"
|
|||||||
clap = { version = "4.4.18", features = ["derive"] }
|
clap = { version = "4.4.18", features = ["derive"] }
|
||||||
futures = { version = "0.3.21", features = ["thread-pool"] }
|
futures = { version = "0.3.21", features = ["thread-pool"] }
|
||||||
futures-timer = "3.0.1"
|
futures-timer = "3.0.1"
|
||||||
jsonrpsee = { version = "0.20.3", features = ["server"] }
|
jsonrpsee = { version = "0.22", features = ["server"] }
|
||||||
serde_json = "1.0.111"
|
serde_json = "1.0.111"
|
||||||
|
|
||||||
sc-cli = { path = "../../../client/cli" }
|
sc-cli = { path = "../../../client/cli" }
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ frame-system = { path = "../../../frame/system" }
|
|||||||
pallet-transaction-payment = { path = "../../../frame/transaction-payment", default-features = false }
|
pallet-transaction-payment = { path = "../../../frame/transaction-payment", default-features = false }
|
||||||
|
|
||||||
# These dependencies are used for the node template's RPCs
|
# These dependencies are used for the node template's RPCs
|
||||||
jsonrpsee = { version = "0.20.3", features = ["server"] }
|
jsonrpsee = { version = "0.22", features = ["server"] }
|
||||||
sp-api = { path = "../../../primitives/api" }
|
sp-api = { path = "../../../primitives/api" }
|
||||||
sc-rpc-api = { path = "../../../client/rpc-api" }
|
sc-rpc-api = { path = "../../../client/rpc-api" }
|
||||||
sp-blockchain = { path = "../../../primitives/blockchain" }
|
sp-blockchain = { path = "../../../primitives/blockchain" }
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ array-bytes = "6.1"
|
|||||||
clap = { version = "4.4.18", features = ["derive"], optional = true }
|
clap = { version = "4.4.18", features = ["derive"], optional = true }
|
||||||
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
||||||
serde = { version = "1.0.195", features = ["derive"] }
|
serde = { version = "1.0.195", features = ["derive"] }
|
||||||
jsonrpsee = { version = "0.20.3", features = ["server"] }
|
jsonrpsee = { version = "0.22", features = ["server"] }
|
||||||
futures = "0.3.21"
|
futures = "0.3.21"
|
||||||
log = { workspace = true, default-features = true }
|
log = { workspace = true, default-features = true }
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ workspace = true
|
|||||||
targets = ["x86_64-unknown-linux-gnu"]
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
jsonrpsee = { version = "0.20.3", features = ["server"] }
|
jsonrpsee = { version = "0.22", features = ["server"] }
|
||||||
node-primitives = { path = "../primitives" }
|
node-primitives = { path = "../primitives" }
|
||||||
pallet-transaction-payment-rpc = { path = "../../../frame/transaction-payment/rpc" }
|
pallet-transaction-payment-rpc = { path = "../../../frame/transaction-payment/rpc" }
|
||||||
mmr-rpc = { path = "../../../client/merkle-mountain-range/rpc" }
|
mmr-rpc = { path = "../../../client/merkle-mountain-range/rpc" }
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ workspace = true
|
|||||||
targets = ["x86_64-unknown-linux-gnu"]
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
jsonrpsee = { version = "0.20.3", features = ["client-core", "macros", "server"] }
|
jsonrpsee = { version = "0.22", features = ["client-core", "macros", "server"] }
|
||||||
futures = "0.3.21"
|
futures = "0.3.21"
|
||||||
serde = { version = "1.0.195", features = ["derive"] }
|
serde = { version = "1.0.195", features = ["derive"] }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ mod tests {
|
|||||||
let (response, _) = api.raw_json_request(request, 1).await.unwrap();
|
let (response, _) = api.raw_json_request(request, 1).await.unwrap();
|
||||||
let expected = r#"{"jsonrpc":"2.0","result":{"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY":{"primary":[0],"secondary":[1,2,4],"secondary_vrf":[]}},"id":1}"#;
|
let expected = r#"{"jsonrpc":"2.0","result":{"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY":{"primary":[0],"secondary":[1,2,4],"secondary_vrf":[]}},"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(&response.result, expected);
|
assert_eq!(response, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -272,6 +272,6 @@ mod tests {
|
|||||||
let (response, _) = api.raw_json_request(request, 1).await.unwrap();
|
let (response, _) = api.raw_json_request(request, 1).await.unwrap();
|
||||||
let expected = r#"{"jsonrpc":"2.0","error":{"code":-32601,"message":"RPC call is unsafe to be called externally"},"id":1}"#;
|
let expected = r#"{"jsonrpc":"2.0","error":{"code":-32601,"message":"RPC call is unsafe to be called externally"},"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(&response.result, expected);
|
assert_eq!(response, expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
codec = { package = "parity-scale-codec", version = "3.6.1", features = ["derive"] }
|
codec = { package = "parity-scale-codec", version = "3.6.1", features = ["derive"] }
|
||||||
futures = "0.3.21"
|
futures = "0.3.21"
|
||||||
jsonrpsee = { version = "0.20.3", features = ["client-core", "macros", "server"] }
|
jsonrpsee = { version = "0.22", features = ["client-core", "macros", "server"] }
|
||||||
log = { workspace = true, default-features = true }
|
log = { workspace = true, default-features = true }
|
||||||
parking_lot = "0.12.1"
|
parking_lot = "0.12.1"
|
||||||
serde = { version = "1.0.195", features = ["derive"] }
|
serde = { version = "1.0.195", features = ["derive"] }
|
||||||
|
|||||||
@@ -184,10 +184,10 @@ mod tests {
|
|||||||
async fn uninitialized_rpc_handler() {
|
async fn uninitialized_rpc_handler() {
|
||||||
let (rpc, _) = setup_io_handler();
|
let (rpc, _) = setup_io_handler();
|
||||||
let request = r#"{"jsonrpc":"2.0","method":"beefy_getFinalizedHead","params":[],"id":1}"#;
|
let request = r#"{"jsonrpc":"2.0","method":"beefy_getFinalizedHead","params":[],"id":1}"#;
|
||||||
let expected_response = r#"{"jsonrpc":"2.0","error":{"code":1,"message":"BEEFY RPC endpoint not ready"},"id":1}"#.to_string();
|
let expected_response = r#"{"jsonrpc":"2.0","error":{"code":1,"message":"BEEFY RPC endpoint not ready"},"id":1}"#;
|
||||||
let (response, _) = rpc.raw_json_request(&request, 1).await.unwrap();
|
let (response, _) = rpc.raw_json_request(&request, 1).await.unwrap();
|
||||||
|
|
||||||
assert_eq!(expected_response, response.result);
|
assert_eq!(expected_response, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -205,20 +205,18 @@ mod tests {
|
|||||||
\"jsonrpc\":\"2.0\",\
|
\"jsonrpc\":\"2.0\",\
|
||||||
\"result\":\"0x2f0039e93a27221fcf657fb877a1d4f60307106113e885096cb44a461cd0afbf\",\
|
\"result\":\"0x2f0039e93a27221fcf657fb877a1d4f60307106113e885096cb44a461cd0afbf\",\
|
||||||
\"id\":1\
|
\"id\":1\
|
||||||
}"
|
}";
|
||||||
.to_string();
|
|
||||||
let not_ready = "{\
|
let not_ready = "{\
|
||||||
\"jsonrpc\":\"2.0\",\
|
\"jsonrpc\":\"2.0\",\
|
||||||
\"error\":{\"code\":1,\"message\":\"BEEFY RPC endpoint not ready\"},\
|
\"error\":{\"code\":1,\"message\":\"BEEFY RPC endpoint not ready\"},\
|
||||||
\"id\":1\
|
\"id\":1\
|
||||||
}"
|
}";
|
||||||
.to_string();
|
|
||||||
|
|
||||||
let deadline = std::time::Instant::now() + std::time::Duration::from_secs(2);
|
let deadline = std::time::Instant::now() + std::time::Duration::from_secs(2);
|
||||||
while std::time::Instant::now() < deadline {
|
while std::time::Instant::now() < deadline {
|
||||||
let (response, _) = io.raw_json_request(request, 1).await.expect("RPC requests work");
|
let (response, _) = io.raw_json_request(request, 1).await.expect("RPC requests work");
|
||||||
if response.result != not_ready {
|
if response != not_ready {
|
||||||
assert_eq!(response.result, expected);
|
assert_eq!(response, expected);
|
||||||
// Success
|
// Success
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -249,7 +247,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let expected = r#"{"jsonrpc":"2.0","result":false,"id":1}"#;
|
let expected = r#"{"jsonrpc":"2.0","result":false,"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(response.result, expected);
|
assert_eq!(response, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_finality_proof() -> BeefyVersionedFinalityProof<Block> {
|
fn create_finality_proof() -> BeefyVersionedFinalityProof<Block> {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
finality-grandpa = { version = "0.16.2", features = ["derive-codec"] }
|
finality-grandpa = { version = "0.16.2", features = ["derive-codec"] }
|
||||||
futures = "0.3.16"
|
futures = "0.3.16"
|
||||||
jsonrpsee = { version = "0.20.3", features = ["client-core", "macros", "server"] }
|
jsonrpsee = { version = "0.22", features = ["client-core", "macros", "server"] }
|
||||||
log = { workspace = true, default-features = true }
|
log = { workspace = true, default-features = true }
|
||||||
parity-scale-codec = { version = "3.6.1", features = ["derive"] }
|
parity-scale-codec = { version = "3.6.1", features = ["derive"] }
|
||||||
serde = { version = "1.0.195", features = ["derive"] }
|
serde = { version = "1.0.195", features = ["derive"] }
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ mod tests {
|
|||||||
let request = r#"{"jsonrpc":"2.0","method":"grandpa_roundState","params":[],"id":0}"#;
|
let request = r#"{"jsonrpc":"2.0","method":"grandpa_roundState","params":[],"id":0}"#;
|
||||||
let (response, _) = rpc.raw_json_request(&request, 1).await.unwrap();
|
let (response, _) = rpc.raw_json_request(&request, 1).await.unwrap();
|
||||||
|
|
||||||
assert_eq!(expected_response, response.result);
|
assert_eq!(expected_response, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -295,7 +295,7 @@ mod tests {
|
|||||||
|
|
||||||
let request = r#"{"jsonrpc":"2.0","method":"grandpa_roundState","params":[],"id":0}"#;
|
let request = r#"{"jsonrpc":"2.0","method":"grandpa_roundState","params":[],"id":0}"#;
|
||||||
let (response, _) = rpc.raw_json_request(&request, 1).await.unwrap();
|
let (response, _) = rpc.raw_json_request(&request, 1).await.unwrap();
|
||||||
assert_eq!(expected_response, response.result);
|
assert_eq!(expected_response, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -317,7 +317,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let expected = r#"{"jsonrpc":"2.0","result":false,"id":1}"#;
|
let expected = r#"{"jsonrpc":"2.0","result":false,"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(response.result, expected);
|
assert_eq!(response, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_justification() -> GrandpaJustification<Block> {
|
fn create_justification() -> GrandpaJustification<Block> {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ workspace = true
|
|||||||
targets = ["x86_64-unknown-linux-gnu"]
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
jsonrpsee = { version = "0.20.3", features = ["client-core", "macros", "server"] }
|
jsonrpsee = { version = "0.22", features = ["client-core", "macros", "server"] }
|
||||||
assert_matches = "1.3.0"
|
assert_matches = "1.3.0"
|
||||||
async-trait = "0.1.74"
|
async-trait = "0.1.74"
|
||||||
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
||||||
jsonrpsee = { version = "0.20.3", features = ["client-core", "macros", "server"] }
|
jsonrpsee = { version = "0.22", features = ["client-core", "macros", "server"] }
|
||||||
serde = { version = "1.0.195", features = ["derive"] }
|
serde = { version = "1.0.195", features = ["derive"] }
|
||||||
sp-api = { path = "../../../primitives/api" }
|
sp-api = { path = "../../../primitives/api" }
|
||||||
sp-blockchain = { path = "../../../primitives/blockchain" }
|
sp-blockchain = { path = "../../../primitives/blockchain" }
|
||||||
|
|||||||
@@ -28,4 +28,4 @@ sp-core = { path = "../../primitives/core" }
|
|||||||
sp-rpc = { path = "../../primitives/rpc" }
|
sp-rpc = { path = "../../primitives/rpc" }
|
||||||
sp-runtime = { path = "../../primitives/runtime" }
|
sp-runtime = { path = "../../primitives/runtime" }
|
||||||
sp-version = { path = "../../primitives/version" }
|
sp-version = { path = "../../primitives/version" }
|
||||||
jsonrpsee = { version = "0.20.3", features = ["client-core", "macros", "server"] }
|
jsonrpsee = { version = "0.22", features = ["client-core", "macros", "server"] }
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ workspace = true
|
|||||||
targets = ["x86_64-unknown-linux-gnu"]
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
jsonrpsee = { version = "0.20.3", features = ["server"] }
|
jsonrpsee = { version = "0.22", features = ["server"] }
|
||||||
log = { workspace = true, default-features = true }
|
log = { workspace = true, default-features = true }
|
||||||
serde_json = "1.0.111"
|
serde_json = "1.0.111"
|
||||||
tokio = { version = "1.22.0", features = ["parking_lot"] }
|
tokio = { version = "1.22.0", features = ["parking_lot"] }
|
||||||
@@ -24,3 +24,6 @@ prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../..
|
|||||||
tower-http = { version = "0.4.0", features = ["cors"] }
|
tower-http = { version = "0.4.0", features = ["cors"] }
|
||||||
tower = { version = "0.4.13", features = ["util"] }
|
tower = { version = "0.4.13", features = ["util"] }
|
||||||
http = "0.2.8"
|
http = "0.2.8"
|
||||||
|
hyper = "0.14.27"
|
||||||
|
futures = "0.3.29"
|
||||||
|
pin-project = "1.1.3"
|
||||||
|
|||||||
@@ -22,21 +22,32 @@
|
|||||||
|
|
||||||
pub mod middleware;
|
pub mod middleware;
|
||||||
|
|
||||||
use std::{error::Error as StdError, net::SocketAddr, time::Duration};
|
use std::{convert::Infallible, error::Error as StdError, net::SocketAddr, time::Duration};
|
||||||
|
|
||||||
use http::header::HeaderValue;
|
use http::header::HeaderValue;
|
||||||
|
use hyper::{
|
||||||
|
server::conn::AddrStream,
|
||||||
|
service::{make_service_fn, service_fn},
|
||||||
|
};
|
||||||
use jsonrpsee::{
|
use jsonrpsee::{
|
||||||
server::middleware::{HostFilterLayer, ProxyGetRequestLayer},
|
server::{
|
||||||
RpcModule,
|
middleware::{
|
||||||
|
http::{HostFilterLayer, ProxyGetRequestLayer},
|
||||||
|
rpc::RpcServiceBuilder,
|
||||||
|
},
|
||||||
|
stop_channel, ws, PingConfig, StopHandle, TowerServiceBuilder,
|
||||||
|
},
|
||||||
|
Methods, RpcModule,
|
||||||
};
|
};
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
|
use tower::Service;
|
||||||
use tower_http::cors::{AllowOrigin, CorsLayer};
|
use tower_http::cors::{AllowOrigin, CorsLayer};
|
||||||
|
|
||||||
pub use crate::middleware::RpcMetrics;
|
|
||||||
pub use jsonrpsee::core::{
|
pub use jsonrpsee::core::{
|
||||||
id_providers::{RandomIntegerIdProvider, RandomStringIdProvider},
|
id_providers::{RandomIntegerIdProvider, RandomStringIdProvider},
|
||||||
traits::IdProvider,
|
traits::IdProvider,
|
||||||
};
|
};
|
||||||
|
pub use middleware::{MetricsLayer, RpcMetrics};
|
||||||
|
|
||||||
const MEGABYTE: u32 = 1024 * 1024;
|
const MEGABYTE: u32 = 1024 * 1024;
|
||||||
|
|
||||||
@@ -92,7 +103,7 @@ pub async fn start_server<M: Send + Sync + 'static>(
|
|||||||
let local_addr = std_listener.local_addr().ok();
|
let local_addr = std_listener.local_addr().ok();
|
||||||
let host_filter = hosts_filtering(cors.is_some(), local_addr);
|
let host_filter = hosts_filtering(cors.is_some(), local_addr);
|
||||||
|
|
||||||
let middleware = tower::ServiceBuilder::new()
|
let http_middleware = tower::ServiceBuilder::new()
|
||||||
.option_layer(host_filter)
|
.option_layer(host_filter)
|
||||||
// Proxy `GET /health` requests to internal `system_health` method.
|
// Proxy `GET /health` requests to internal `system_health` method.
|
||||||
.layer(ProxyGetRequestLayer::new("/health", "system_health")?)
|
.layer(ProxyGetRequestLayer::new("/health", "system_health")?)
|
||||||
@@ -103,10 +114,15 @@ pub async fn start_server<M: Send + Sync + 'static>(
|
|||||||
.max_response_body_size(max_payload_out_mb.saturating_mul(MEGABYTE))
|
.max_response_body_size(max_payload_out_mb.saturating_mul(MEGABYTE))
|
||||||
.max_connections(max_connections)
|
.max_connections(max_connections)
|
||||||
.max_subscriptions_per_connection(max_subs_per_conn)
|
.max_subscriptions_per_connection(max_subs_per_conn)
|
||||||
.ping_interval(Duration::from_secs(30))
|
.enable_ws_ping(
|
||||||
.set_middleware(middleware)
|
PingConfig::new()
|
||||||
|
.ping_interval(Duration::from_secs(30))
|
||||||
|
.inactive_limit(Duration::from_secs(60))
|
||||||
|
.max_failures(3),
|
||||||
|
)
|
||||||
|
.set_http_middleware(http_middleware)
|
||||||
.set_message_buffer_capacity(message_buffer_capacity)
|
.set_message_buffer_capacity(message_buffer_capacity)
|
||||||
.custom_tokio_runtime(tokio_handle);
|
.custom_tokio_runtime(tokio_handle.clone());
|
||||||
|
|
||||||
if let Some(provider) = id_provider {
|
if let Some(provider) = id_provider {
|
||||||
builder = builder.set_id_provider(provider);
|
builder = builder.set_id_provider(provider);
|
||||||
@@ -114,22 +130,66 @@ pub async fn start_server<M: Send + Sync + 'static>(
|
|||||||
builder = builder.set_id_provider(RandomStringIdProvider::new(16));
|
builder = builder.set_id_provider(RandomStringIdProvider::new(16));
|
||||||
};
|
};
|
||||||
|
|
||||||
let rpc_api = build_rpc_api(rpc_api);
|
let (stop_handle, server_handle) = stop_channel();
|
||||||
let handle = if let Some(metrics) = metrics {
|
let cfg = PerConnection {
|
||||||
let server = builder.set_logger(metrics).build_from_tcp(std_listener)?;
|
methods: build_rpc_api(rpc_api).into(),
|
||||||
server.start(rpc_api)
|
service_builder: builder.to_service_builder(),
|
||||||
} else {
|
metrics,
|
||||||
let server = builder.build_from_tcp(std_listener)?;
|
tokio_handle,
|
||||||
server.start(rpc_api)
|
stop_handle: stop_handle.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let make_service = make_service_fn(move |_conn: &AddrStream| {
|
||||||
|
let cfg = cfg.clone();
|
||||||
|
|
||||||
|
async move {
|
||||||
|
let cfg = cfg.clone();
|
||||||
|
|
||||||
|
Ok::<_, Infallible>(service_fn(move |req| {
|
||||||
|
let PerConnection { service_builder, metrics, tokio_handle, stop_handle, methods } =
|
||||||
|
cfg.clone();
|
||||||
|
|
||||||
|
let is_websocket = ws::is_upgrade_request(&req);
|
||||||
|
let transport_label = if is_websocket { "ws" } else { "http" };
|
||||||
|
|
||||||
|
let metrics = metrics.map(|m| MetricsLayer::new(m, transport_label));
|
||||||
|
let rpc_middleware = RpcServiceBuilder::new().option_layer(metrics.clone());
|
||||||
|
let mut svc =
|
||||||
|
service_builder.set_rpc_middleware(rpc_middleware).build(methods, stop_handle);
|
||||||
|
|
||||||
|
async move {
|
||||||
|
if is_websocket {
|
||||||
|
let on_disconnect = svc.on_session_closed();
|
||||||
|
|
||||||
|
// Spawn a task to handle when the connection is closed.
|
||||||
|
tokio_handle.spawn(async move {
|
||||||
|
let now = std::time::Instant::now();
|
||||||
|
metrics.as_ref().map(|m| m.ws_connect());
|
||||||
|
on_disconnect.await;
|
||||||
|
metrics.as_ref().map(|m| m.ws_disconnect(now));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
svc.call(req).await
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let server = hyper::Server::from_tcp(std_listener)?.serve(make_service);
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let graceful = server.with_graceful_shutdown(async move { stop_handle.shutdown().await });
|
||||||
|
let _ = graceful.await;
|
||||||
|
});
|
||||||
|
|
||||||
log::info!(
|
log::info!(
|
||||||
"Running JSON-RPC server: addr={}, allowed origins={}",
|
"Running JSON-RPC server: addr={}, allowed origins={}",
|
||||||
local_addr.map_or_else(|| "unknown".to_string(), |a| a.to_string()),
|
local_addr.map_or_else(|| "unknown".to_string(), |a| a.to_string()),
|
||||||
format_cors(cors)
|
format_cors(cors)
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(handle)
|
Ok(server_handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hosts_filtering(enabled: bool, addr: Option<SocketAddr>) -> Option<HostFilterLayer> {
|
fn hosts_filtering(enabled: bool, addr: Option<SocketAddr>) -> Option<HostFilterLayer> {
|
||||||
@@ -185,3 +245,12 @@ fn format_cors(maybe_cors: Option<&Vec<String>>) -> String {
|
|||||||
format!("{:?}", ["*"])
|
format!("{:?}", ["*"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct PerConnection<RpcMiddleware, HttpMiddleware> {
|
||||||
|
methods: Methods,
|
||||||
|
stop_handle: StopHandle,
|
||||||
|
metrics: Option<RpcMetrics>,
|
||||||
|
tokio_handle: tokio::runtime::Handle,
|
||||||
|
service_builder: TowerServiceBuilder<RpcMiddleware, HttpMiddleware>,
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,226 +0,0 @@
|
|||||||
// This file is part of Substrate.
|
|
||||||
|
|
||||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! RPC middleware to collect prometheus metrics on RPC calls.
|
|
||||||
|
|
||||||
use jsonrpsee::server::logger::{
|
|
||||||
HttpRequest, Logger, MethodKind, Params, SuccessOrError, TransportProtocol,
|
|
||||||
};
|
|
||||||
use prometheus_endpoint::{
|
|
||||||
register, Counter, CounterVec, HistogramOpts, HistogramVec, Opts, PrometheusError, Registry,
|
|
||||||
U64,
|
|
||||||
};
|
|
||||||
use std::net::SocketAddr;
|
|
||||||
|
|
||||||
/// Histogram time buckets in microseconds.
|
|
||||||
const HISTOGRAM_BUCKETS: [f64; 11] = [
|
|
||||||
5.0,
|
|
||||||
25.0,
|
|
||||||
100.0,
|
|
||||||
500.0,
|
|
||||||
1_000.0,
|
|
||||||
2_500.0,
|
|
||||||
10_000.0,
|
|
||||||
25_000.0,
|
|
||||||
100_000.0,
|
|
||||||
1_000_000.0,
|
|
||||||
10_000_000.0,
|
|
||||||
];
|
|
||||||
|
|
||||||
/// Metrics for RPC middleware storing information about the number of requests started/completed,
|
|
||||||
/// calls started/completed and their timings.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct RpcMetrics {
|
|
||||||
/// Number of RPC requests received since the server started.
|
|
||||||
requests_started: CounterVec<U64>,
|
|
||||||
/// Number of RPC requests completed since the server started.
|
|
||||||
requests_finished: CounterVec<U64>,
|
|
||||||
/// Histogram over RPC execution times.
|
|
||||||
calls_time: HistogramVec,
|
|
||||||
/// Number of calls started.
|
|
||||||
calls_started: CounterVec<U64>,
|
|
||||||
/// Number of calls completed.
|
|
||||||
calls_finished: CounterVec<U64>,
|
|
||||||
/// Number of Websocket sessions opened.
|
|
||||||
ws_sessions_opened: Option<Counter<U64>>,
|
|
||||||
/// Number of Websocket sessions closed.
|
|
||||||
ws_sessions_closed: Option<Counter<U64>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RpcMetrics {
|
|
||||||
/// Create an instance of metrics
|
|
||||||
pub fn new(metrics_registry: Option<&Registry>) -> Result<Option<Self>, PrometheusError> {
|
|
||||||
if let Some(metrics_registry) = metrics_registry {
|
|
||||||
Ok(Some(Self {
|
|
||||||
requests_started: register(
|
|
||||||
CounterVec::new(
|
|
||||||
Opts::new(
|
|
||||||
"substrate_rpc_requests_started",
|
|
||||||
"Number of RPC requests (not calls) received by the server.",
|
|
||||||
),
|
|
||||||
&["protocol"],
|
|
||||||
)?,
|
|
||||||
metrics_registry,
|
|
||||||
)?,
|
|
||||||
requests_finished: register(
|
|
||||||
CounterVec::new(
|
|
||||||
Opts::new(
|
|
||||||
"substrate_rpc_requests_finished",
|
|
||||||
"Number of RPC requests (not calls) processed by the server.",
|
|
||||||
),
|
|
||||||
&["protocol"],
|
|
||||||
)?,
|
|
||||||
metrics_registry,
|
|
||||||
)?,
|
|
||||||
calls_time: register(
|
|
||||||
HistogramVec::new(
|
|
||||||
HistogramOpts::new(
|
|
||||||
"substrate_rpc_calls_time",
|
|
||||||
"Total time [μs] of processed RPC calls",
|
|
||||||
)
|
|
||||||
.buckets(HISTOGRAM_BUCKETS.to_vec()),
|
|
||||||
&["protocol", "method"],
|
|
||||||
)?,
|
|
||||||
metrics_registry,
|
|
||||||
)?,
|
|
||||||
calls_started: register(
|
|
||||||
CounterVec::new(
|
|
||||||
Opts::new(
|
|
||||||
"substrate_rpc_calls_started",
|
|
||||||
"Number of received RPC calls (unique un-batched requests)",
|
|
||||||
),
|
|
||||||
&["protocol", "method"],
|
|
||||||
)?,
|
|
||||||
metrics_registry,
|
|
||||||
)?,
|
|
||||||
calls_finished: register(
|
|
||||||
CounterVec::new(
|
|
||||||
Opts::new(
|
|
||||||
"substrate_rpc_calls_finished",
|
|
||||||
"Number of processed RPC calls (unique un-batched requests)",
|
|
||||||
),
|
|
||||||
&["protocol", "method", "is_error"],
|
|
||||||
)?,
|
|
||||||
metrics_registry,
|
|
||||||
)?,
|
|
||||||
ws_sessions_opened: register(
|
|
||||||
Counter::new(
|
|
||||||
"substrate_rpc_sessions_opened",
|
|
||||||
"Number of persistent RPC sessions opened",
|
|
||||||
)?,
|
|
||||||
metrics_registry,
|
|
||||||
)?
|
|
||||||
.into(),
|
|
||||||
ws_sessions_closed: register(
|
|
||||||
Counter::new(
|
|
||||||
"substrate_rpc_sessions_closed",
|
|
||||||
"Number of persistent RPC sessions closed",
|
|
||||||
)?,
|
|
||||||
metrics_registry,
|
|
||||||
)?
|
|
||||||
.into(),
|
|
||||||
}))
|
|
||||||
} else {
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Logger for RpcMetrics {
|
|
||||||
type Instant = std::time::Instant;
|
|
||||||
|
|
||||||
fn on_connect(
|
|
||||||
&self,
|
|
||||||
_remote_addr: SocketAddr,
|
|
||||||
_request: &HttpRequest,
|
|
||||||
transport: TransportProtocol,
|
|
||||||
) {
|
|
||||||
if let TransportProtocol::WebSocket = transport {
|
|
||||||
self.ws_sessions_opened.as_ref().map(|counter| counter.inc());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_request(&self, transport: TransportProtocol) -> Self::Instant {
|
|
||||||
let transport_label = transport_label_str(transport);
|
|
||||||
let now = std::time::Instant::now();
|
|
||||||
self.requests_started.with_label_values(&[transport_label]).inc();
|
|
||||||
now
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_call(&self, name: &str, params: Params, kind: MethodKind, transport: TransportProtocol) {
|
|
||||||
let transport_label = transport_label_str(transport);
|
|
||||||
log::trace!(
|
|
||||||
target: "rpc_metrics",
|
|
||||||
"[{}] on_call name={} params={:?} kind={}",
|
|
||||||
transport_label,
|
|
||||||
name,
|
|
||||||
params,
|
|
||||||
kind,
|
|
||||||
);
|
|
||||||
self.calls_started.with_label_values(&[transport_label, name]).inc();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_result(
|
|
||||||
&self,
|
|
||||||
name: &str,
|
|
||||||
success_or_error: SuccessOrError,
|
|
||||||
started_at: Self::Instant,
|
|
||||||
transport: TransportProtocol,
|
|
||||||
) {
|
|
||||||
let transport_label = transport_label_str(transport);
|
|
||||||
let micros = started_at.elapsed().as_micros();
|
|
||||||
log::debug!(
|
|
||||||
target: "rpc_metrics",
|
|
||||||
"[{}] {} call took {} μs",
|
|
||||||
transport_label,
|
|
||||||
name,
|
|
||||||
micros,
|
|
||||||
);
|
|
||||||
self.calls_time.with_label_values(&[transport_label, name]).observe(micros as _);
|
|
||||||
|
|
||||||
self.calls_finished
|
|
||||||
.with_label_values(&[
|
|
||||||
transport_label,
|
|
||||||
name,
|
|
||||||
// the label "is_error", so `success` should be regarded as false
|
|
||||||
// and vice-versa to be registrered correctly.
|
|
||||||
if success_or_error.is_success() { "false" } else { "true" },
|
|
||||||
])
|
|
||||||
.inc();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_response(&self, result: &str, started_at: Self::Instant, transport: TransportProtocol) {
|
|
||||||
let transport_label = transport_label_str(transport);
|
|
||||||
log::trace!(target: "rpc_metrics", "[{}] on_response started_at={:?}", transport_label, started_at);
|
|
||||||
log::trace!(target: "rpc_metrics::extra", "[{}] result={:?}", transport_label, result);
|
|
||||||
self.requests_finished.with_label_values(&[transport_label]).inc();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_disconnect(&self, _remote_addr: SocketAddr, transport: TransportProtocol) {
|
|
||||||
if let TransportProtocol::WebSocket = transport {
|
|
||||||
self.ws_sessions_closed.as_ref().map(|counter| counter.inc());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transport_label_str(t: TransportProtocol) -> &'static str {
|
|
||||||
match t {
|
|
||||||
TransportProtocol::Http => "http",
|
|
||||||
TransportProtocol::WebSocket => "ws",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,281 @@
|
|||||||
|
// This file is part of Substrate.
|
||||||
|
|
||||||
|
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! RPC middleware to collect prometheus metrics on RPC calls.
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
future::Future,
|
||||||
|
pin::Pin,
|
||||||
|
task::{Context, Poll},
|
||||||
|
time::Instant,
|
||||||
|
};
|
||||||
|
|
||||||
|
use jsonrpsee::{server::middleware::rpc::RpcServiceT, types::Request, MethodResponse};
|
||||||
|
use pin_project::pin_project;
|
||||||
|
use prometheus_endpoint::{
|
||||||
|
register, Counter, CounterVec, HistogramOpts, HistogramVec, Opts, PrometheusError, Registry,
|
||||||
|
U64,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Histogram time buckets in microseconds.
|
||||||
|
const HISTOGRAM_BUCKETS: [f64; 11] = [
|
||||||
|
5.0,
|
||||||
|
25.0,
|
||||||
|
100.0,
|
||||||
|
500.0,
|
||||||
|
1_000.0,
|
||||||
|
2_500.0,
|
||||||
|
10_000.0,
|
||||||
|
25_000.0,
|
||||||
|
100_000.0,
|
||||||
|
1_000_000.0,
|
||||||
|
10_000_000.0,
|
||||||
|
];
|
||||||
|
|
||||||
|
/// Metrics for RPC middleware storing information about the number of requests started/completed,
|
||||||
|
/// calls started/completed and their timings.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct RpcMetrics {
|
||||||
|
/// Histogram over RPC execution times.
|
||||||
|
calls_time: HistogramVec,
|
||||||
|
/// Number of calls started.
|
||||||
|
calls_started: CounterVec<U64>,
|
||||||
|
/// Number of calls completed.
|
||||||
|
calls_finished: CounterVec<U64>,
|
||||||
|
/// Number of Websocket sessions opened.
|
||||||
|
ws_sessions_opened: Option<Counter<U64>>,
|
||||||
|
/// Number of Websocket sessions closed.
|
||||||
|
ws_sessions_closed: Option<Counter<U64>>,
|
||||||
|
/// Histogram over RPC websocket sessions.
|
||||||
|
ws_sessions_time: HistogramVec,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RpcMetrics {
|
||||||
|
/// Create an instance of metrics
|
||||||
|
pub fn new(metrics_registry: Option<&Registry>) -> Result<Option<Self>, PrometheusError> {
|
||||||
|
if let Some(metrics_registry) = metrics_registry {
|
||||||
|
Ok(Some(Self {
|
||||||
|
calls_time: register(
|
||||||
|
HistogramVec::new(
|
||||||
|
HistogramOpts::new(
|
||||||
|
"substrate_rpc_calls_time",
|
||||||
|
"Total time [μs] of processed RPC calls",
|
||||||
|
)
|
||||||
|
.buckets(HISTOGRAM_BUCKETS.to_vec()),
|
||||||
|
&["protocol", "method"],
|
||||||
|
)?,
|
||||||
|
metrics_registry,
|
||||||
|
)?,
|
||||||
|
calls_started: register(
|
||||||
|
CounterVec::new(
|
||||||
|
Opts::new(
|
||||||
|
"substrate_rpc_calls_started",
|
||||||
|
"Number of received RPC calls (unique un-batched requests)",
|
||||||
|
),
|
||||||
|
&["protocol", "method"],
|
||||||
|
)?,
|
||||||
|
metrics_registry,
|
||||||
|
)?,
|
||||||
|
calls_finished: register(
|
||||||
|
CounterVec::new(
|
||||||
|
Opts::new(
|
||||||
|
"substrate_rpc_calls_finished",
|
||||||
|
"Number of processed RPC calls (unique un-batched requests)",
|
||||||
|
),
|
||||||
|
&["protocol", "method", "is_error"],
|
||||||
|
)?,
|
||||||
|
metrics_registry,
|
||||||
|
)?,
|
||||||
|
ws_sessions_opened: register(
|
||||||
|
Counter::new(
|
||||||
|
"substrate_rpc_sessions_opened",
|
||||||
|
"Number of persistent RPC sessions opened",
|
||||||
|
)?,
|
||||||
|
metrics_registry,
|
||||||
|
)?
|
||||||
|
.into(),
|
||||||
|
ws_sessions_closed: register(
|
||||||
|
Counter::new(
|
||||||
|
"substrate_rpc_sessions_closed",
|
||||||
|
"Number of persistent RPC sessions closed",
|
||||||
|
)?,
|
||||||
|
metrics_registry,
|
||||||
|
)?
|
||||||
|
.into(),
|
||||||
|
ws_sessions_time: register(
|
||||||
|
HistogramVec::new(
|
||||||
|
HistogramOpts::new(
|
||||||
|
"substrate_rpc_sessions_time",
|
||||||
|
"Total time [s] for each websocket session",
|
||||||
|
)
|
||||||
|
.buckets(HISTOGRAM_BUCKETS.to_vec()),
|
||||||
|
&["protocol"],
|
||||||
|
)?,
|
||||||
|
metrics_registry,
|
||||||
|
)?,
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn ws_connect(&self) {
|
||||||
|
self.ws_sessions_opened.as_ref().map(|counter| counter.inc());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn ws_disconnect(&self, now: Instant) {
|
||||||
|
let micros = now.elapsed().as_secs();
|
||||||
|
|
||||||
|
self.ws_sessions_closed.as_ref().map(|counter| counter.inc());
|
||||||
|
self.ws_sessions_time.with_label_values(&["ws"]).observe(micros as _);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Metrics layer.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct MetricsLayer {
|
||||||
|
inner: RpcMetrics,
|
||||||
|
transport_label: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MetricsLayer {
|
||||||
|
/// Create a new [`MetricsLayer`].
|
||||||
|
pub fn new(metrics: RpcMetrics, transport_label: &'static str) -> Self {
|
||||||
|
Self { inner: metrics, transport_label }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn ws_connect(&self) {
|
||||||
|
self.inner.ws_connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn ws_disconnect(&self, now: Instant) {
|
||||||
|
self.inner.ws_disconnect(now)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> tower::Layer<S> for MetricsLayer {
|
||||||
|
type Service = Metrics<S>;
|
||||||
|
|
||||||
|
fn layer(&self, inner: S) -> Self::Service {
|
||||||
|
Metrics::new(inner, self.inner.clone(), self.transport_label)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Metrics middleware.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Metrics<S> {
|
||||||
|
service: S,
|
||||||
|
metrics: RpcMetrics,
|
||||||
|
transport_label: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> Metrics<S> {
|
||||||
|
/// Create a new metrics middleware.
|
||||||
|
pub fn new(service: S, metrics: RpcMetrics, transport_label: &'static str) -> Metrics<S> {
|
||||||
|
Metrics { service, metrics, transport_label }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, S> RpcServiceT<'a> for Metrics<S>
|
||||||
|
where
|
||||||
|
S: Send + Sync + RpcServiceT<'a>,
|
||||||
|
{
|
||||||
|
type Future = ResponseFuture<'a, S::Future>;
|
||||||
|
|
||||||
|
fn call(&self, req: Request<'a>) -> Self::Future {
|
||||||
|
let now = Instant::now();
|
||||||
|
|
||||||
|
log::trace!(
|
||||||
|
target: "rpc_metrics",
|
||||||
|
"[{}] on_call name={} params={:?}",
|
||||||
|
self.transport_label,
|
||||||
|
req.method_name(),
|
||||||
|
req.params(),
|
||||||
|
);
|
||||||
|
self.metrics
|
||||||
|
.calls_started
|
||||||
|
.with_label_values(&[self.transport_label, req.method_name()])
|
||||||
|
.inc();
|
||||||
|
|
||||||
|
ResponseFuture {
|
||||||
|
fut: self.service.call(req.clone()),
|
||||||
|
metrics: self.metrics.clone(),
|
||||||
|
req,
|
||||||
|
now,
|
||||||
|
transport_label: self.transport_label,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Response future for metrics.
|
||||||
|
#[pin_project]
|
||||||
|
pub struct ResponseFuture<'a, F> {
|
||||||
|
#[pin]
|
||||||
|
fut: F,
|
||||||
|
metrics: RpcMetrics,
|
||||||
|
req: Request<'a>,
|
||||||
|
now: Instant,
|
||||||
|
transport_label: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, F> std::fmt::Debug for ResponseFuture<'a, F> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_str("ResponseFuture")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, F: Future<Output = MethodResponse>> Future for ResponseFuture<'a, F> {
|
||||||
|
type Output = F::Output;
|
||||||
|
|
||||||
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
let this = self.project();
|
||||||
|
|
||||||
|
let res = this.fut.poll(cx);
|
||||||
|
if let Poll::Ready(rp) = &res {
|
||||||
|
let method_name = this.req.method_name();
|
||||||
|
let transport_label = &this.transport_label;
|
||||||
|
let now = this.now;
|
||||||
|
let metrics = &this.metrics;
|
||||||
|
|
||||||
|
log::trace!(target: "rpc_metrics", "[{transport_label}] on_response started_at={:?}", now);
|
||||||
|
log::trace!(target: "rpc_metrics::extra", "[{transport_label}] result={:?}", rp);
|
||||||
|
|
||||||
|
let micros = now.elapsed().as_micros();
|
||||||
|
log::debug!(
|
||||||
|
target: "rpc_metrics",
|
||||||
|
"[{transport_label}] {method_name} call took {} μs",
|
||||||
|
micros,
|
||||||
|
);
|
||||||
|
metrics
|
||||||
|
.calls_time
|
||||||
|
.with_label_values(&[transport_label, method_name])
|
||||||
|
.observe(micros as _);
|
||||||
|
metrics
|
||||||
|
.calls_finished
|
||||||
|
.with_label_values(&[
|
||||||
|
transport_label,
|
||||||
|
method_name,
|
||||||
|
// the label "is_error", so `success` should be regarded as false
|
||||||
|
// and vice-versa to be registrered correctly.
|
||||||
|
if rp.is_success() { "false" } else { "true" },
|
||||||
|
])
|
||||||
|
.inc();
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// This file is part of Substrate.
|
||||||
|
|
||||||
|
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! JSON-RPC specific middleware.
|
||||||
|
|
||||||
|
pub mod metrics;
|
||||||
|
|
||||||
|
pub use metrics::*;
|
||||||
@@ -16,7 +16,7 @@ workspace = true
|
|||||||
targets = ["x86_64-unknown-linux-gnu"]
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
jsonrpsee = { version = "0.20.3", features = ["client-core", "macros", "server"] }
|
jsonrpsee = { version = "0.22", features = ["client-core", "macros", "server"] }
|
||||||
# Internal chain structures for "chain_spec".
|
# Internal chain structures for "chain_spec".
|
||||||
sc-chain-spec = { path = "../chain-spec" }
|
sc-chain-spec = { path = "../chain-spec" }
|
||||||
# Pool for submitting extrinsics required by "transaction"
|
# Pool for submitting extrinsics required by "transaction"
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ use super::{
|
|||||||
use assert_matches::assert_matches;
|
use assert_matches::assert_matches;
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use jsonrpsee::{
|
use jsonrpsee::{
|
||||||
core::{EmptyServerParams as EmptyParams, Error},
|
core::EmptyServerParams as EmptyParams, rpc_params, MethodsError as Error, RpcModule,
|
||||||
rpc_params, RpcModule,
|
|
||||||
};
|
};
|
||||||
use sc_block_builder::BlockBuilderBuilder;
|
use sc_block_builder::BlockBuilderBuilder;
|
||||||
use sc_client_api::ChildInfo;
|
use sc_client_api::ChildInfo;
|
||||||
@@ -294,7 +293,7 @@ async fn archive_call() {
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err, Error::Call(err) if err.code() == 3001 && err.message().contains("Invalid parameter"));
|
assert_matches!(err, Error::JsonRpc(err) if err.code() == 3001 && err.message().contains("Invalid parameter"));
|
||||||
|
|
||||||
// Pass an invalid parameters that cannot be decode.
|
// Pass an invalid parameters that cannot be decode.
|
||||||
let err = api
|
let err = api
|
||||||
@@ -305,7 +304,7 @@ async fn archive_call() {
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err, Error::Call(err) if err.code() == 3001 && err.message().contains("Invalid parameter"));
|
assert_matches!(err, Error::JsonRpc(err) if err.code() == 3001 && err.message().contains("Invalid parameter"));
|
||||||
|
|
||||||
// Invalid hash.
|
// Invalid hash.
|
||||||
let result: MethodResult = api
|
let result: MethodResult = api
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
common::events::StorageQuery,
|
common::events::StorageQuery,
|
||||||
};
|
};
|
||||||
use jsonrpsee::proc_macros::rpc;
|
use jsonrpsee::{proc_macros::rpc, server::ResponsePayload};
|
||||||
use sp_rpc::list::ListOrValue;
|
use sp_rpc::list::ListOrValue;
|
||||||
|
|
||||||
#[rpc(client, server)]
|
#[rpc(client, server)]
|
||||||
@@ -59,7 +59,7 @@ pub trait ChainHeadApi<Hash> {
|
|||||||
&self,
|
&self,
|
||||||
follow_subscription: String,
|
follow_subscription: String,
|
||||||
hash: Hash,
|
hash: Hash,
|
||||||
) -> Result<MethodResponse, Error>;
|
) -> ResponsePayload<'static, MethodResponse>;
|
||||||
|
|
||||||
/// Retrieves the header of a pinned block.
|
/// Retrieves the header of a pinned block.
|
||||||
///
|
///
|
||||||
@@ -92,7 +92,7 @@ pub trait ChainHeadApi<Hash> {
|
|||||||
hash: Hash,
|
hash: Hash,
|
||||||
items: Vec<StorageQuery<String>>,
|
items: Vec<StorageQuery<String>>,
|
||||||
child_trie: Option<String>,
|
child_trie: Option<String>,
|
||||||
) -> Result<MethodResponse, Error>;
|
) -> ResponsePayload<'static, MethodResponse>;
|
||||||
|
|
||||||
/// Call into the Runtime API at a specified block's state.
|
/// Call into the Runtime API at a specified block's state.
|
||||||
///
|
///
|
||||||
@@ -106,7 +106,7 @@ pub trait ChainHeadApi<Hash> {
|
|||||||
hash: Hash,
|
hash: Hash,
|
||||||
function: String,
|
function: String,
|
||||||
call_parameters: String,
|
call_parameters: String,
|
||||||
) -> Result<MethodResponse, Error>;
|
) -> ResponsePayload<'static, MethodResponse>;
|
||||||
|
|
||||||
/// Unpin a block or multiple blocks reported by the `follow` method.
|
/// Unpin a block or multiple blocks reported by the `follow` method.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ use crate::{
|
|||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use futures::future::FutureExt;
|
use futures::future::FutureExt;
|
||||||
use jsonrpsee::{
|
use jsonrpsee::{
|
||||||
core::async_trait, types::SubscriptionId, PendingSubscriptionSink, SubscriptionSink,
|
core::async_trait, server::ResponsePayload, types::SubscriptionId, MethodResponseFuture,
|
||||||
|
PendingSubscriptionSink, SubscriptionSink,
|
||||||
};
|
};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use sc_client_api::{
|
use sc_client_api::{
|
||||||
@@ -218,16 +219,17 @@ where
|
|||||||
&self,
|
&self,
|
||||||
follow_subscription: String,
|
follow_subscription: String,
|
||||||
hash: Block::Hash,
|
hash: Block::Hash,
|
||||||
) -> Result<MethodResponse, ChainHeadRpcError> {
|
) -> ResponsePayload<'static, MethodResponse> {
|
||||||
let mut block_guard = match self.subscriptions.lock_block(&follow_subscription, hash, 1) {
|
let mut block_guard = match self.subscriptions.lock_block(&follow_subscription, hash, 1) {
|
||||||
Ok(block) => block,
|
Ok(block) => block,
|
||||||
Err(SubscriptionManagementError::SubscriptionAbsent) |
|
Err(SubscriptionManagementError::SubscriptionAbsent) |
|
||||||
Err(SubscriptionManagementError::ExceededLimits) => return Ok(MethodResponse::LimitReached),
|
Err(SubscriptionManagementError::ExceededLimits) =>
|
||||||
|
return ResponsePayload::success(MethodResponse::LimitReached),
|
||||||
Err(SubscriptionManagementError::BlockHashAbsent) => {
|
Err(SubscriptionManagementError::BlockHashAbsent) => {
|
||||||
// Block is not part of the subscription.
|
// Block is not part of the subscription.
|
||||||
return Err(ChainHeadRpcError::InvalidBlock.into())
|
return ResponsePayload::error(ChainHeadRpcError::InvalidBlock);
|
||||||
},
|
},
|
||||||
Err(_) => return Err(ChainHeadRpcError::InvalidBlock.into()),
|
Err(_) => return ResponsePayload::error(ChainHeadRpcError::InvalidBlock),
|
||||||
};
|
};
|
||||||
|
|
||||||
let operation_id = block_guard.operation().operation_id();
|
let operation_id = block_guard.operation().operation_id();
|
||||||
@@ -254,7 +256,7 @@ where
|
|||||||
hash
|
hash
|
||||||
);
|
);
|
||||||
self.subscriptions.remove_subscription(&follow_subscription);
|
self.subscriptions.remove_subscription(&follow_subscription);
|
||||||
return Err(ChainHeadRpcError::InvalidBlock.into())
|
return ResponsePayload::error(ChainHeadRpcError::InvalidBlock)
|
||||||
},
|
},
|
||||||
Err(error) => FollowEvent::<Block::Hash>::OperationError(OperationError {
|
Err(error) => FollowEvent::<Block::Hash>::OperationError(OperationError {
|
||||||
operation_id: operation_id.clone(),
|
operation_id: operation_id.clone(),
|
||||||
@@ -262,8 +264,20 @@ where
|
|||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
let _ = block_guard.response_sender().unbounded_send(event);
|
let (rp, rp_fut) = method_started_response(operation_id, None);
|
||||||
Ok(MethodResponse::Started(MethodResponseStarted { operation_id, discarded_items: None }))
|
|
||||||
|
let fut = async move {
|
||||||
|
// Events should only by generated
|
||||||
|
// if the response was successfully propagated.
|
||||||
|
if rp_fut.await.is_err() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let _ = block_guard.response_sender().unbounded_send(event);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.executor.spawn("substrate-rpc-subscription", Some("rpc"), fut.boxed());
|
||||||
|
|
||||||
|
rp
|
||||||
}
|
}
|
||||||
|
|
||||||
fn chain_head_unstable_header(
|
fn chain_head_unstable_header(
|
||||||
@@ -294,31 +308,40 @@ where
|
|||||||
hash: Block::Hash,
|
hash: Block::Hash,
|
||||||
items: Vec<StorageQuery<String>>,
|
items: Vec<StorageQuery<String>>,
|
||||||
child_trie: Option<String>,
|
child_trie: Option<String>,
|
||||||
) -> Result<MethodResponse, ChainHeadRpcError> {
|
) -> ResponsePayload<'static, MethodResponse> {
|
||||||
// Gain control over parameter parsing and returned error.
|
// Gain control over parameter parsing and returned error.
|
||||||
let items = items
|
let items = match items
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|query| {
|
.map(|query| {
|
||||||
let key = StorageKey(parse_hex_param(query.key)?);
|
let key = StorageKey(parse_hex_param(query.key)?);
|
||||||
Ok(StorageQuery { key, query_type: query.query_type })
|
Ok(StorageQuery { key, query_type: query.query_type })
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, ChainHeadRpcError>>()?;
|
.collect::<Result<Vec<_>, ChainHeadRpcError>>()
|
||||||
|
{
|
||||||
|
Ok(items) => items,
|
||||||
|
Err(err) => {
|
||||||
|
return ResponsePayload::error(err);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
let child_trie = child_trie
|
let child_trie = match child_trie.map(|child_trie| parse_hex_param(child_trie)).transpose()
|
||||||
.map(|child_trie| parse_hex_param(child_trie))
|
{
|
||||||
.transpose()?
|
Ok(c) => c.map(ChildInfo::new_default_from_vec),
|
||||||
.map(ChildInfo::new_default_from_vec);
|
Err(e) => return ResponsePayload::error(e),
|
||||||
|
};
|
||||||
|
|
||||||
let mut block_guard =
|
let mut block_guard =
|
||||||
match self.subscriptions.lock_block(&follow_subscription, hash, items.len()) {
|
match self.subscriptions.lock_block(&follow_subscription, hash, items.len()) {
|
||||||
Ok(block) => block,
|
Ok(block) => block,
|
||||||
Err(SubscriptionManagementError::SubscriptionAbsent) |
|
Err(SubscriptionManagementError::SubscriptionAbsent) |
|
||||||
Err(SubscriptionManagementError::ExceededLimits) => return Ok(MethodResponse::LimitReached),
|
Err(SubscriptionManagementError::ExceededLimits) => {
|
||||||
|
return ResponsePayload::success(MethodResponse::LimitReached);
|
||||||
|
},
|
||||||
Err(SubscriptionManagementError::BlockHashAbsent) => {
|
Err(SubscriptionManagementError::BlockHashAbsent) => {
|
||||||
// Block is not part of the subscription.
|
// Block is not part of the subscription.
|
||||||
return Err(ChainHeadRpcError::InvalidBlock.into())
|
return ResponsePayload::error(ChainHeadRpcError::InvalidBlock)
|
||||||
},
|
},
|
||||||
Err(_) => return Err(ChainHeadRpcError::InvalidBlock.into()),
|
Err(_) => return ResponsePayload::error(ChainHeadRpcError::InvalidBlock),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut storage_client = ChainHeadStorage::<Client, Block, BE>::new(
|
let mut storage_client = ChainHeadStorage::<Client, Block, BE>::new(
|
||||||
@@ -334,16 +357,21 @@ where
|
|||||||
let mut items = items;
|
let mut items = items;
|
||||||
items.truncate(num_operations);
|
items.truncate(num_operations);
|
||||||
|
|
||||||
|
let (rp, rp_is_success) = method_started_response(operation_id, Some(discarded));
|
||||||
|
|
||||||
let fut = async move {
|
let fut = async move {
|
||||||
|
// Events should only by generated
|
||||||
|
// if the response was successfully propagated.
|
||||||
|
if rp_is_success.await.is_err() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
storage_client.generate_events(block_guard, hash, items, child_trie).await;
|
storage_client.generate_events(block_guard, hash, items, child_trie).await;
|
||||||
};
|
};
|
||||||
|
|
||||||
self.executor
|
self.executor
|
||||||
.spawn_blocking("substrate-rpc-subscription", Some("rpc"), fut.boxed());
|
.spawn_blocking("substrate-rpc-subscription", Some("rpc"), fut.boxed());
|
||||||
Ok(MethodResponse::Started(MethodResponseStarted {
|
|
||||||
operation_id,
|
rp
|
||||||
discarded_items: Some(discarded),
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn chain_head_unstable_call(
|
fn chain_head_unstable_call(
|
||||||
@@ -352,29 +380,31 @@ where
|
|||||||
hash: Block::Hash,
|
hash: Block::Hash,
|
||||||
function: String,
|
function: String,
|
||||||
call_parameters: String,
|
call_parameters: String,
|
||||||
) -> Result<MethodResponse, ChainHeadRpcError> {
|
) -> ResponsePayload<'static, MethodResponse> {
|
||||||
let call_parameters = Bytes::from(parse_hex_param(call_parameters)?);
|
let call_parameters = match parse_hex_param(call_parameters) {
|
||||||
|
Ok(hex) => Bytes::from(hex),
|
||||||
|
Err(err) => return ResponsePayload::error(err),
|
||||||
|
};
|
||||||
|
|
||||||
let mut block_guard = match self.subscriptions.lock_block(&follow_subscription, hash, 1) {
|
let mut block_guard = match self.subscriptions.lock_block(&follow_subscription, hash, 1) {
|
||||||
Ok(block) => block,
|
Ok(block) => block,
|
||||||
Err(SubscriptionManagementError::SubscriptionAbsent) |
|
Err(SubscriptionManagementError::SubscriptionAbsent) |
|
||||||
Err(SubscriptionManagementError::ExceededLimits) => {
|
Err(SubscriptionManagementError::ExceededLimits) => {
|
||||||
// Invalid invalid subscription ID.
|
// Invalid invalid subscription ID.
|
||||||
return Ok(MethodResponse::LimitReached)
|
return ResponsePayload::success(MethodResponse::LimitReached)
|
||||||
},
|
},
|
||||||
Err(SubscriptionManagementError::BlockHashAbsent) => {
|
Err(SubscriptionManagementError::BlockHashAbsent) => {
|
||||||
// Block is not part of the subscription.
|
// Block is not part of the subscription.
|
||||||
return Err(ChainHeadRpcError::InvalidBlock.into())
|
return ResponsePayload::error(ChainHeadRpcError::InvalidBlock)
|
||||||
},
|
},
|
||||||
Err(_) => return Err(ChainHeadRpcError::InvalidBlock.into()),
|
Err(_) => return ResponsePayload::error(ChainHeadRpcError::InvalidBlock),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Reject subscription if with_runtime is false.
|
// Reject subscription if with_runtime is false.
|
||||||
if !block_guard.has_runtime() {
|
if !block_guard.has_runtime() {
|
||||||
return Err(ChainHeadRpcError::InvalidRuntimeCall(
|
return ResponsePayload::error(ChainHeadRpcError::InvalidRuntimeCall(
|
||||||
"The runtime updates flag must be set".to_string(),
|
"The runtime updates flag must be set".to_string(),
|
||||||
)
|
));
|
||||||
.into())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let operation_id = block_guard.operation().operation_id();
|
let operation_id = block_guard.operation().operation_id();
|
||||||
@@ -395,11 +425,20 @@ where
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let _ = block_guard.response_sender().unbounded_send(event);
|
let (rp, rp_fut) = method_started_response(operation_id, None);
|
||||||
Ok(MethodResponse::Started(MethodResponseStarted {
|
|
||||||
operation_id: operation_id.clone(),
|
let fut = async move {
|
||||||
discarded_items: None,
|
// Events should only by generated
|
||||||
}))
|
// if the response was successfully propagated.
|
||||||
|
if rp_fut.await.is_err() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let _ = block_guard.response_sender().unbounded_send(event);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.executor.spawn("substrate-rpc-subscription", Some("rpc"), fut.boxed());
|
||||||
|
|
||||||
|
rp
|
||||||
}
|
}
|
||||||
|
|
||||||
fn chain_head_unstable_unpin(
|
fn chain_head_unstable_unpin(
|
||||||
@@ -463,3 +502,11 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn method_started_response(
|
||||||
|
operation_id: String,
|
||||||
|
discarded_items: Option<usize>,
|
||||||
|
) -> (ResponsePayload<'static, MethodResponse>, MethodResponseFuture) {
|
||||||
|
let rp = MethodResponse::Started(MethodResponseStarted { operation_id, discarded_items });
|
||||||
|
ResponsePayload::success(rp).notify_on_completion()
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ use assert_matches::assert_matches;
|
|||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use jsonrpsee::{
|
use jsonrpsee::{
|
||||||
core::{error::Error, server::Subscription as RpcSubscription},
|
core::server::Subscription as RpcSubscription, rpc_params, MethodsError as Error, RpcModule,
|
||||||
rpc_params, RpcModule,
|
|
||||||
};
|
};
|
||||||
use sc_block_builder::BlockBuilderBuilder;
|
use sc_block_builder::BlockBuilderBuilder;
|
||||||
use sc_client_api::ChildInfo;
|
use sc_client_api::ChildInfo;
|
||||||
@@ -359,7 +358,7 @@ async fn get_header() {
|
|||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
Error::JsonRpc(ref err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Obtain the valid header.
|
// Obtain the valid header.
|
||||||
@@ -388,7 +387,7 @@ async fn get_body() {
|
|||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
Error::JsonRpc(ref err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Valid call.
|
// Valid call.
|
||||||
@@ -473,7 +472,7 @@ async fn call_runtime() {
|
|||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
Error::JsonRpc(ref err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Pass an invalid parameters that cannot be decode.
|
// Pass an invalid parameters that cannot be decode.
|
||||||
@@ -486,7 +485,7 @@ async fn call_runtime() {
|
|||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::json_rpc_spec::INVALID_PARAM_ERROR && err.message().contains("Invalid parameter")
|
Error::JsonRpc(err) if err.code() == super::error::json_rpc_spec::INVALID_PARAM_ERROR && err.message().contains("Invalid parameter")
|
||||||
);
|
);
|
||||||
|
|
||||||
// Valid call.
|
// Valid call.
|
||||||
@@ -589,7 +588,7 @@ async fn call_runtime_without_flag() {
|
|||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::rpc_spec_v2::INVALID_RUNTIME_CALL && err.message().contains("subscription was started with `withRuntime` set to `false`")
|
Error::JsonRpc(ref err) if err.code() == super::error::rpc_spec_v2::INVALID_RUNTIME_CALL && err.message().contains("subscription was started with `withRuntime` set to `false`")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -627,7 +626,7 @@ async fn get_storage_hash() {
|
|||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
Error::JsonRpc(ref err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Valid call without storage at the key.
|
// Valid call without storage at the key.
|
||||||
@@ -895,7 +894,7 @@ async fn get_storage_value() {
|
|||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
Error::JsonRpc(ref err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Valid call without storage at the key.
|
// Valid call without storage at the key.
|
||||||
@@ -1571,7 +1570,7 @@ async fn follow_with_unpin() {
|
|||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
Error::JsonRpc(ref err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
||||||
);
|
);
|
||||||
|
|
||||||
// To not exceed the number of pinned blocks, we need to unpin before the next import.
|
// To not exceed the number of pinned blocks, we need to unpin before the next import.
|
||||||
@@ -1674,7 +1673,7 @@ async fn unpin_duplicate_hashes() {
|
|||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::rpc_spec_v2::INVALID_DUPLICATE_HASHES && err.message() == "Received duplicate hashes for the `chainHead_unpin` method"
|
Error::JsonRpc(err) if err.code() == super::error::rpc_spec_v2::INVALID_DUPLICATE_HASHES && err.message() == "Received duplicate hashes for the `chainHead_unpin` method"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Block tree:
|
// Block tree:
|
||||||
@@ -1709,7 +1708,7 @@ async fn unpin_duplicate_hashes() {
|
|||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::rpc_spec_v2::INVALID_DUPLICATE_HASHES && err.message() == "Received duplicate hashes for the `chainHead_unpin` method"
|
Error::JsonRpc(err) if err.code() == super::error::rpc_spec_v2::INVALID_DUPLICATE_HASHES && err.message() == "Received duplicate hashes for the `chainHead_unpin` method"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Can unpin blocks.
|
// Can unpin blocks.
|
||||||
@@ -1822,7 +1821,7 @@ async fn follow_with_multiple_unpin_hashes() {
|
|||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
Error::JsonRpc(ref err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
||||||
);
|
);
|
||||||
|
|
||||||
let _res: () = api
|
let _res: () = api
|
||||||
@@ -1839,7 +1838,7 @@ async fn follow_with_multiple_unpin_hashes() {
|
|||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
Error::JsonRpc(ref err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Unpin multiple blocks.
|
// Unpin multiple blocks.
|
||||||
@@ -1857,7 +1856,7 @@ async fn follow_with_multiple_unpin_hashes() {
|
|||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
Error::JsonRpc(ref err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
||||||
);
|
);
|
||||||
|
|
||||||
let err = api
|
let err = api
|
||||||
@@ -1868,7 +1867,7 @@ async fn follow_with_multiple_unpin_hashes() {
|
|||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
Error::JsonRpc(ref err) if err.code() == super::error::rpc_spec_v2::INVALID_BLOCK_ERROR && err.message() == "Invalid block hash"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ use crate::{
|
|||||||
use assert_matches::assert_matches;
|
use assert_matches::assert_matches;
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use jsonrpsee::{core::error::Error, rpc_params, RpcModule};
|
use jsonrpsee::{rpc_params, MethodsError as Error, RpcModule};
|
||||||
use sc_transaction_pool::*;
|
use sc_transaction_pool::*;
|
||||||
use sc_transaction_pool_api::{ChainEvent, MaintainedTransactionPool, TransactionPool};
|
use sc_transaction_pool_api::{ChainEvent, MaintainedTransactionPool, TransactionPool};
|
||||||
use sp_core::{testing::TaskExecutor, traits::SpawnNamed};
|
use sp_core::{testing::TaskExecutor, traits::SpawnNamed};
|
||||||
@@ -194,7 +194,7 @@ async fn tx_broadcast_invalid_tx() {
|
|||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid params"
|
Error::JsonRpc(err) if err.code() == super::error::json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid params"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(0, pool.status().ready);
|
assert_eq!(0, pool.status().ready);
|
||||||
@@ -219,7 +219,7 @@ async fn tx_broadcast_invalid_tx() {
|
|||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid operation id"
|
Error::JsonRpc(err) if err.code() == super::error::json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid operation id"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,6 +233,6 @@ async fn tx_invalid_stop() {
|
|||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_matches!(err,
|
assert_matches!(err,
|
||||||
Error::Call(err) if err.code() == super::error::json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid operation id"
|
Error::JsonRpc(err) if err.code() == super::error::json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid operation id"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
||||||
futures = "0.3.21"
|
futures = "0.3.21"
|
||||||
jsonrpsee = { version = "0.20.3", features = ["server"] }
|
jsonrpsee = { version = "0.22", features = ["server"] }
|
||||||
log = { workspace = true, default-features = true }
|
log = { workspace = true, default-features = true }
|
||||||
parking_lot = "0.12.1"
|
parking_lot = "0.12.1"
|
||||||
serde_json = "1.0.111"
|
serde_json = "1.0.111"
|
||||||
|
|||||||
@@ -21,10 +21,7 @@ use super::*;
|
|||||||
use crate::testing::{test_executor, timeout_secs};
|
use crate::testing::{test_executor, timeout_secs};
|
||||||
use assert_matches::assert_matches;
|
use assert_matches::assert_matches;
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use jsonrpsee::{
|
use jsonrpsee::{core::EmptyServerParams as EmptyParams, MethodsError as RpcError, RpcModule};
|
||||||
core::{EmptyServerParams as EmptyParams, Error as RpcError},
|
|
||||||
RpcModule,
|
|
||||||
};
|
|
||||||
use sc_transaction_pool::{BasicPool, FullChainApi};
|
use sc_transaction_pool::{BasicPool, FullChainApi};
|
||||||
use sc_transaction_pool_api::TransactionStatus;
|
use sc_transaction_pool_api::TransactionStatus;
|
||||||
use sp_core::{
|
use sp_core::{
|
||||||
@@ -103,7 +100,7 @@ async fn author_submit_transaction_should_not_cause_error() {
|
|||||||
|
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
api.call::<_, H256>("author_submitExtrinsic", [xt]).await,
|
api.call::<_, H256>("author_submitExtrinsic", [xt]).await,
|
||||||
Err(RpcError::Call(err)) if err.message().contains("Already Imported") && err.code() == 1013
|
Err(RpcError::JsonRpc(err)) if err.message().contains("Already Imported") && err.code() == 1013
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +157,7 @@ async fn author_should_return_watch_validation_error() {
|
|||||||
|
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
failed_sub,
|
failed_sub,
|
||||||
Err(RpcError::Call(err)) if err.message().contains("Invalid Transaction") && err.code() == 1010
|
Err(RpcError::JsonRpc(err)) if err.message().contains("Invalid Transaction") && err.code() == 1010
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,7 +273,7 @@ async fn author_has_session_keys() {
|
|||||||
|
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
api.call::<_, bool>("author_hasSessionKeys", vec![Bytes::from(vec![1, 2, 3])]).await,
|
api.call::<_, bool>("author_hasSessionKeys", vec![Bytes::from(vec![1, 2, 3])]).await,
|
||||||
Err(RpcError::Call(err)) if err.message().contains("Session keys are not encoded correctly")
|
Err(RpcError::JsonRpc(err)) if err.message().contains("Session keys are not encoded correctly")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ async fn deny_unsafe_works() {
|
|||||||
let (resp, _) = api.raw_json_request(&request, 1).await.expect("Raw calls should succeed");
|
let (resp, _) = api.raw_json_request(&request, 1).await.expect("Raw calls should succeed");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resp.result,
|
resp,
|
||||||
r#"{"jsonrpc":"2.0","error":{"code":-32601,"message":"RPC call is unsafe to be called externally"},"id":1}"#
|
r#"{"jsonrpc":"2.0","error":{"code":-32601,"message":"RPC call is unsafe to be called externally"},"id":1}"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ use super::*;
|
|||||||
use crate::testing::{test_executor, timeout_secs};
|
use crate::testing::{test_executor, timeout_secs};
|
||||||
use assert_matches::assert_matches;
|
use assert_matches::assert_matches;
|
||||||
use futures::executor;
|
use futures::executor;
|
||||||
use jsonrpsee::core::{EmptyServerParams as EmptyParams, Error as RpcError};
|
use jsonrpsee::{core::EmptyServerParams as EmptyParams, MethodsError as RpcError};
|
||||||
use sc_block_builder::BlockBuilderBuilder;
|
use sc_block_builder::BlockBuilderBuilder;
|
||||||
use sc_rpc_api::DenyUnsafe;
|
use sc_rpc_api::DenyUnsafe;
|
||||||
use sp_consensus::BlockOrigin;
|
use sp_consensus::BlockOrigin;
|
||||||
@@ -525,7 +525,7 @@ async fn wildcard_storage_subscriptions_are_rpc_unsafe() {
|
|||||||
|
|
||||||
let api_rpc = api.into_rpc();
|
let api_rpc = api.into_rpc();
|
||||||
let err = api_rpc.subscribe_unbounded("state_subscribeStorage", EmptyParams::new()).await;
|
let err = api_rpc.subscribe_unbounded("state_subscribeStorage", EmptyParams::new()).await;
|
||||||
assert_matches!(err, Err(RpcError::Call(e)) if e.message() == "RPC call is unsafe to be called externally");
|
assert_matches!(err, Err(RpcError::JsonRpc(e)) if e.message() == "RPC call is unsafe to be called externally");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|||||||
@@ -19,10 +19,7 @@
|
|||||||
use super::{helpers::SyncState, *};
|
use super::{helpers::SyncState, *};
|
||||||
use assert_matches::assert_matches;
|
use assert_matches::assert_matches;
|
||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use jsonrpsee::{
|
use jsonrpsee::{core::EmptyServerParams as EmptyParams, MethodsError as RpcError, RpcModule};
|
||||||
core::{EmptyServerParams as EmptyParams, Error as RpcError},
|
|
||||||
RpcModule,
|
|
||||||
};
|
|
||||||
use sc_network::{self, config::Role, PeerId};
|
use sc_network::{self, config::Role, PeerId};
|
||||||
use sc_rpc_api::system::helpers::PeerInfo;
|
use sc_rpc_api::system::helpers::PeerInfo;
|
||||||
use sc_utils::mpsc::tracing_unbounded;
|
use sc_utils::mpsc::tracing_unbounded;
|
||||||
@@ -311,7 +308,7 @@ async fn system_network_add_reserved() {
|
|||||||
let bad_peer_id = ["/ip4/198.51.100.19/tcp/30333"];
|
let bad_peer_id = ["/ip4/198.51.100.19/tcp/30333"];
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
api(None).call::<_, ()>("system_addReservedPeer", bad_peer_id).await,
|
api(None).call::<_, ()>("system_addReservedPeer", bad_peer_id).await,
|
||||||
Err(RpcError::Call(err)) if err.message().contains("Peer id is missing from the address")
|
Err(RpcError::JsonRpc(err)) if err.message().contains("Peer id is missing from the address")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,7 +324,7 @@ async fn system_network_remove_reserved() {
|
|||||||
|
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
api(None).call::<_, String>("system_removeReservedPeer", bad_peer_id).await,
|
api(None).call::<_, String>("system_removeReservedPeer", bad_peer_id).await,
|
||||||
Err(RpcError::Call(err)) if err.message().contains("base-58 decode error: provided string contained invalid character '/' at byte 0")
|
Err(RpcError::JsonRpc(err)) if err.message().contains("base-58 decode error: provided string contained invalid character '/' at byte 0")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ where
|
|||||||
Either::Left((Ok(sink), _)) => break sink,
|
Either::Left((Ok(sink), _)) => break sink,
|
||||||
Either::Right((Some(msg), f)) => {
|
Either::Right((Some(msg), f)) => {
|
||||||
if buf.push_back(msg).is_err() {
|
if buf.push_back(msg).is_err() {
|
||||||
log::warn!(target: "rpc", "Subscription::accept failed buffer limit={} exceed; dropping subscription", buf.max_cap);
|
log::warn!(target: "rpc", "Subscription::accept failed buffer limit={} exceeded; dropping subscription", buf.max_cap);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
accept_fut = f;
|
accept_fut = f;
|
||||||
@@ -125,7 +125,13 @@ async fn inner_pipe_from_stream<S, T>(
|
|||||||
// New item from the stream
|
// New item from the stream
|
||||||
Either::Right((Either::Right((Some(v), n)), c)) => {
|
Either::Right((Either::Right((Some(v), n)), c)) => {
|
||||||
if buf.push_back(v).is_err() {
|
if buf.push_back(v).is_err() {
|
||||||
log::warn!(target: "rpc", "Subscription buffer limit={} exceed; dropping subscription", buf.max_cap);
|
log::warn!(
|
||||||
|
target: "rpc",
|
||||||
|
"Subscription buffer limit={} exceeded for subscription={} conn_id={}; dropping subscription",
|
||||||
|
buf.max_cap,
|
||||||
|
sink.method_name(),
|
||||||
|
sink.connection_id()
|
||||||
|
);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ runtime-benchmarks = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
jsonrpsee = { version = "0.20.3", features = ["server"] }
|
jsonrpsee = { version = "0.22", features = ["server"] }
|
||||||
thiserror = "1.0.48"
|
thiserror = "1.0.48"
|
||||||
futures = "0.3.21"
|
futures = "0.3.21"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ use std::{collections::HashMap, net::SocketAddr};
|
|||||||
|
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use futures::{pin_mut, FutureExt, StreamExt};
|
use futures::{pin_mut, FutureExt, StreamExt};
|
||||||
use jsonrpsee::{core::Error as JsonRpseeError, RpcModule};
|
use jsonrpsee::RpcModule;
|
||||||
use log::{debug, error, warn};
|
use log::{debug, error, warn};
|
||||||
use sc_client_api::{blockchain::HeaderBackend, BlockBackend, BlockchainEvents, ProofProvider};
|
use sc_client_api::{blockchain::HeaderBackend, BlockBackend, BlockchainEvents, ProofProvider};
|
||||||
use sc_network::{
|
use sc_network::{
|
||||||
@@ -109,17 +109,14 @@ impl RpcHandlers {
|
|||||||
pub async fn rpc_query(
|
pub async fn rpc_query(
|
||||||
&self,
|
&self,
|
||||||
json_query: &str,
|
json_query: &str,
|
||||||
) -> Result<(String, tokio::sync::mpsc::Receiver<String>), JsonRpseeError> {
|
) -> Result<(String, tokio::sync::mpsc::Receiver<String>), serde_json::Error> {
|
||||||
// Because `tokio::sync::mpsc::channel` is used under the hood
|
// Because `tokio::sync::mpsc::channel` is used under the hood
|
||||||
// it will panic if it's set to usize::MAX.
|
// it will panic if it's set to usize::MAX.
|
||||||
//
|
//
|
||||||
// This limit is used to prevent panics and is large enough.
|
// This limit is used to prevent panics and is large enough.
|
||||||
const TOKIO_MPSC_MAX_SIZE: usize = tokio::sync::Semaphore::MAX_PERMITS;
|
const TOKIO_MPSC_MAX_SIZE: usize = tokio::sync::Semaphore::MAX_PERMITS;
|
||||||
|
|
||||||
self.0
|
self.0.raw_json_request(json_query, TOKIO_MPSC_MAX_SIZE).await
|
||||||
.raw_json_request(json_query, TOKIO_MPSC_MAX_SIZE)
|
|
||||||
.await
|
|
||||||
.map(|(method_res, recv)| (method_res.result, recv))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provides access to the underlying `RpcModule`
|
/// Provides access to the underlying `RpcModule`
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
||||||
jsonrpsee = { version = "0.20.3", features = ["client-core", "macros", "server"] }
|
jsonrpsee = { version = "0.22", features = ["client-core", "macros", "server"] }
|
||||||
serde = { version = "1.0.195", features = ["derive"] }
|
serde = { version = "1.0.195", features = ["derive"] }
|
||||||
serde_json = "1.0.111"
|
serde_json = "1.0.111"
|
||||||
thiserror = "1.0.48"
|
thiserror = "1.0.48"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
||||||
jsonrpsee = { version = "0.20.3", features = ["client-core", "macros", "server"] }
|
jsonrpsee = { version = "0.22", features = ["client-core", "macros", "server"] }
|
||||||
pallet-transaction-payment-rpc-runtime-api = { path = "runtime-api" }
|
pallet-transaction-payment-rpc-runtime-api = { path = "runtime-api" }
|
||||||
sp-api = { path = "../../../primitives/api" }
|
sp-api = { path = "../../../primitives/api" }
|
||||||
sp-blockchain = { path = "../../../primitives/blockchain" }
|
sp-blockchain = { path = "../../../primitives/blockchain" }
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ workspace = true
|
|||||||
targets = ["x86_64-unknown-linux-gnu"]
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
jsonrpsee = { version = "0.20.3", features = ["http-client"] }
|
jsonrpsee = { version = "0.22", features = ["http-client"] }
|
||||||
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
||||||
log = { workspace = true, default-features = true }
|
log = { workspace = true, default-features = true }
|
||||||
serde = "1.0.195"
|
serde = "1.0.195"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ workspace = true
|
|||||||
targets = ["x86_64-unknown-linux-gnu"]
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
jsonrpsee = { version = "0.20.3", features = ["ws-client"] }
|
jsonrpsee = { version = "0.22", features = ["ws-client"] }
|
||||||
sc-rpc-api = { path = "../../../../client/rpc-api" }
|
sc-rpc-api = { path = "../../../../client/rpc-api" }
|
||||||
async-trait = "0.1.74"
|
async-trait = "0.1.74"
|
||||||
serde = "1"
|
serde = "1"
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ use std::collections::VecDeque;
|
|||||||
|
|
||||||
pub use jsonrpsee::{
|
pub use jsonrpsee::{
|
||||||
core::{
|
core::{
|
||||||
client::{ClientT, Subscription, SubscriptionClientT},
|
client::{ClientT, Error, Subscription, SubscriptionClientT},
|
||||||
params::BatchRequestBuilder,
|
params::BatchRequestBuilder,
|
||||||
Error, RpcResult,
|
RpcResult,
|
||||||
},
|
},
|
||||||
rpc_params,
|
rpc_params,
|
||||||
ws_client::{WsClient, WsClientBuilder},
|
ws_client::{WsClient, WsClientBuilder},
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ sp-core = { path = "../../../../primitives/core" }
|
|||||||
sp-state-machine = { path = "../../../../primitives/state-machine" }
|
sp-state-machine = { path = "../../../../primitives/state-machine" }
|
||||||
sp-trie = { path = "../../../../primitives/trie" }
|
sp-trie = { path = "../../../../primitives/trie" }
|
||||||
trie-db = "0.28.0"
|
trie-db = "0.28.0"
|
||||||
jsonrpsee = { version = "0.20.3", features = ["client-core", "macros", "server"] }
|
|
||||||
|
jsonrpsee = { version = "0.22", features = ["client-core", "macros", "server"] }
|
||||||
|
|
||||||
# Substrate Dependencies
|
# Substrate Dependencies
|
||||||
sc-client-api = { path = "../../../../client/api" }
|
sc-client-api = { path = "../../../../client/api" }
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
||||||
jsonrpsee = { version = "0.20.3", features = ["jsonrpsee-types"] }
|
jsonrpsee = { version = "0.22", features = ["jsonrpsee-types"] }
|
||||||
serde = "1"
|
serde = "1"
|
||||||
frame-support = { path = "../../../../frame/support" }
|
frame-support = { path = "../../../../frame/support" }
|
||||||
sc-rpc-api = { path = "../../../../client/rpc-api" }
|
sc-rpc-api = { path = "../../../../client/rpc-api" }
|
||||||
@@ -24,7 +24,7 @@ sp-storage = { path = "../../../../primitives/storage" }
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
scale-info = "2.10.0"
|
scale-info = "2.10.0"
|
||||||
jsonrpsee = { version = "0.20.3", features = ["jsonrpsee-types", "ws-client"] }
|
jsonrpsee = { version = "0.22", features = ["jsonrpsee-types", "ws-client"] }
|
||||||
tokio = "1.22.0"
|
tokio = "1.22.0"
|
||||||
sp-core = { path = "../../../../primitives/core" }
|
sp-core = { path = "../../../../primitives/core" }
|
||||||
sp-runtime = { path = "../../../../primitives/runtime" }
|
sp-runtime = { path = "../../../../primitives/runtime" }
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
use codec::{DecodeAll, FullCodec, FullEncode};
|
use codec::{DecodeAll, FullCodec, FullEncode};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use frame_support::storage::generator::{StorageDoubleMap, StorageMap, StorageValue};
|
use frame_support::storage::generator::{StorageDoubleMap, StorageMap, StorageValue};
|
||||||
use jsonrpsee::core::Error as RpcError;
|
use jsonrpsee::core::ClientError as RpcError;
|
||||||
use sc_rpc_api::state::StateApiClient;
|
use sc_rpc_api::state::StateApiClient;
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
use sp_storage::{StorageData, StorageKey};
|
use sp_storage::{StorageData, StorageKey};
|
||||||
@@ -31,7 +31,7 @@ use sp_storage::{StorageData, StorageKey};
|
|||||||
/// A typed query on chain state usable from an RPC client.
|
/// A typed query on chain state usable from an RPC client.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// # use jsonrpsee::core::Error as RpcError;
|
/// # use jsonrpsee::core::ClientError as RpcError;
|
||||||
/// # use jsonrpsee::ws_client::WsClientBuilder;
|
/// # use jsonrpsee::ws_client::WsClientBuilder;
|
||||||
/// # use codec::Encode;
|
/// # use codec::Encode;
|
||||||
/// # use frame_support::{construct_runtime, derive_impl, traits::ConstU32};
|
/// # use frame_support::{construct_runtime, derive_impl, traits::ConstU32};
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
||||||
jsonrpsee = { version = "0.20.3", features = ["client-core", "macros", "server"] }
|
jsonrpsee = { version = "0.22", features = ["client-core", "macros", "server"] }
|
||||||
futures = "0.3.21"
|
futures = "0.3.21"
|
||||||
log = { workspace = true, default-features = true }
|
log = { workspace = true, default-features = true }
|
||||||
frame-system-rpc-runtime-api = { path = "../../../../frame/system/rpc/runtime-api" }
|
frame-system-rpc-runtime-api = { path = "../../../../frame/system/rpc/runtime-api" }
|
||||||
|
|||||||
Reference in New Issue
Block a user