diff --git a/Cargo.lock b/Cargo.lock index 66af009..34b2b96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,7 +43,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ "crypto-common", - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -53,7 +53,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", - "cipher", + "cipher 0.4.4", "cpufeatures", ] @@ -65,10 +65,10 @@ checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ "aead", "aes", - "cipher", + "cipher 0.4.4", "ctr", "ghash", - "subtle", + "subtle 2.6.1", ] [[package]] @@ -99,6 +99,21 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstyle" version = "1.0.10" @@ -517,6 +532,27 @@ dependencies = [ "serde", ] +[[package]] +name = "bindgen" +version = "0.65.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 1.1.0", + "shlex", + "syn 2.0.99", +] + [[package]] name = "bitcoin-internals" version = "0.2.0" @@ -557,6 +593,18 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" +dependencies = [ + "byte-tools", + "crypto-mac 0.7.0", + "digest 0.8.1", + "opaque-debug 0.2.3", +] + [[package]] name = "blake2" version = "0.10.6" @@ -607,7 +655,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -616,7 +664,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -652,6 +700,12 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + [[package]] name = "bytemuck" version = "1.22.0" @@ -670,6 +724,26 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +[[package]] +name = "bzip2-sys" +version = "0.1.13+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" +dependencies = [ + "cc", + "pkg-config", +] + +[[package]] +name = "c2-chacha" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27dae93fe7b1e0424dc57179ac396908c26b035a87234809f5c4dfd1b47dc80" +dependencies = [ + "cipher 0.2.5", + "ppv-lite86", +] + [[package]] name = "cc" version = "1.2.16" @@ -687,6 +761,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-expr" version = "0.15.8" @@ -702,6 +785,28 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862" +dependencies = [ + "byteorder", + "keystream", +] + [[package]] name = "chacha20" version = "0.9.1" @@ -709,7 +814,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", - "cipher", + "cipher 0.4.4", "cpufeatures", ] @@ -721,11 +826,25 @@ checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ "aead", "chacha20", - "cipher", + "cipher 0.4.4", "poly1305", "zeroize", ] +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] + [[package]] name = "cid" version = "0.9.0" @@ -752,6 +871,15 @@ dependencies = [ "unsigned-varint 0.7.2", ] +[[package]] +name = "cipher" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" +dependencies = [ + "generic-array 0.14.7", +] + [[package]] name = "cipher" version = "0.4.4" @@ -763,6 +891,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "combine" version = "4.6.7" @@ -788,6 +927,19 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "console" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "unicode-width", + "windows-sys 0.59.0", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -1049,9 +1201,9 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ - "generic-array", + "generic-array 0.14.7", "rand_core 0.6.4", - "subtle", + "subtle 2.6.1", "zeroize", ] @@ -1061,19 +1213,29 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array", + "generic-array 0.14.7", "rand_core 0.6.4", "typenum", ] +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array 0.12.4", + "subtle 1.0.0", +] + [[package]] name = "crypto-mac" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ - "generic-array", - "subtle", + "generic-array 0.14.7", + "subtle 2.6.1", ] [[package]] @@ -1082,7 +1244,7 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cipher", + "cipher 0.4.4", ] [[package]] @@ -1097,7 +1259,7 @@ dependencies = [ "digest 0.10.7", "fiat-crypto", "rustc_version", - "subtle", + "subtle 2.6.1", "zeroize", ] @@ -1112,6 +1274,19 @@ dependencies = [ "syn 2.0.99", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core 0.9.10", +] + [[package]] name = "data-encoding" version = "2.8.0" @@ -1246,13 +1421,22 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + [[package]] name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -1264,7 +1448,16 @@ dependencies = [ "block-buffer 0.10.4", "const-oid", "crypto-common", - "subtle", + "subtle 2.6.1", +] + +[[package]] +name = "directories" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" +dependencies = [ + "dirs-sys", ] [[package]] @@ -1277,6 +1470,18 @@ dependencies = [ "dirs-sys-next", ] +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + [[package]] name = "dirs-sys-next" version = "0.1.2" @@ -1401,7 +1606,7 @@ dependencies = [ "rand_core 0.6.4", "serde", "sha2 0.10.8", - "subtle", + "subtle 2.6.1", "zeroize", ] @@ -1436,16 +1641,22 @@ dependencies = [ "crypto-bigint", "digest 0.10.7", "ff", - "generic-array", + "generic-array 0.14.7", "group", "pkcs8", "rand_core 0.6.4", "sec1", "serdect", - "subtle", + "subtle 2.6.1", "zeroize", ] +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "enum-as-inner" version = "0.5.1" @@ -1577,6 +1788,30 @@ dependencies = [ "staging-xcm-executor", ] +[[package]] +name = "epico-receipt-service" +version = "0.1.0" +dependencies = [ + "ep-account", + "frame-system", + "futures", + "pallet-balances", + "pallet-epico", + "pallet-epico-runtime-api", + "parity-scale-codec", + "sc-client-api", + "sc-network", + "sc-offchain", + "sc-service", + "serde", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-io", + "sp-runtime", + "tracing", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -1668,13 +1903,22 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "exit-future" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5" +dependencies = [ + "futures", +] + [[package]] name = "expander" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2c470c71d91ecbd179935b24170459e926382eaaa86b590b78814e180d8a8e2" dependencies = [ - "blake2", + "blake2 0.10.6", "file-guard", "fs-err", "prettyplease", @@ -1702,7 +1946,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", - "subtle", + "subtle 2.6.1", ] [[package]] @@ -1803,6 +2047,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "forwarded-header-value" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9" +dependencies = [ + "nonempty", + "thiserror 1.0.69", +] + [[package]] name = "fragile" version = "2.0.0" @@ -1959,6 +2213,16 @@ dependencies = [ "autocfg", ] +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "funty" version = "2.0.0" @@ -2074,7 +2338,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" dependencies = [ "gloo-timers", - "send_wrapper", + "send_wrapper 0.4.0", ] [[package]] @@ -2104,6 +2368,15 @@ dependencies = [ "byteorder", ] +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -2154,7 +2427,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ - "opaque-debug", + "opaque-debug 0.3.1", "polyval", ] @@ -2175,6 +2448,12 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + [[package]] name = "gloo-net" version = "0.6.0" @@ -2221,6 +2500,26 @@ dependencies = [ "web-sys", ] +[[package]] +name = "governor" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" +dependencies = [ + "cfg-if", + "dashmap", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot 0.12.3", + "portable-atomic", + "quanta", + "rand 0.8.5", + "smallvec", + "spinning_top", +] + [[package]] name = "group" version = "0.13.0" @@ -2229,7 +2528,7 @@ checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", - "subtle", + "subtle 2.6.1", ] [[package]] @@ -2321,6 +2620,15 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.5", +] + [[package]] name = "heck" version = "0.4.1" @@ -2429,7 +2737,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" dependencies = [ - "crypto-mac", + "crypto-mac 0.8.0", "digest 0.9.0", ] @@ -2449,7 +2757,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" dependencies = [ "digest 0.9.0", - "generic-array", + "generic-array 0.14.7", "hmac 0.8.1", ] @@ -2621,6 +2929,30 @@ dependencies = [ "tracing", ] +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.61.2", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "icu_collections" version = "1.5.0" @@ -2937,7 +3269,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -3279,6 +3611,12 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "keystream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" + [[package]] name = "kvdb" version = "0.13.0" @@ -3289,22 +3627,68 @@ dependencies = [ ] [[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.170" +name = "kvdb-memorydb" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" +checksum = "bf7a85fe66f9ff9cd74e169fdd2c94c6e1e74c412c99a73b4df3200b5d3760b2" +dependencies = [ + "kvdb", + "parking_lot 0.12.3", +] [[package]] -name = "libp2p" -version = "0.52.4" +name = "kvdb-rocksdb" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94495eb319a85b70a68b85e2389a95bb3555c71c49025b78c691a854a7e6464" +checksum = "b644c70b92285f66bfc2032922a79000ea30af7bc2ab31902992a5dcb9b434f6" +dependencies = [ + "kvdb", + "num_cpus", + "parking_lot 0.12.3", + "regex", + "rocksdb", + "smallvec", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.170" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" + +[[package]] +name = "libloading" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + +[[package]] +name = "libp2p" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94495eb319a85b70a68b85e2389a95bb3555c71c49025b78c691a854a7e6464" dependencies = [ "bytes", "either", @@ -3328,6 +3712,7 @@ dependencies = [ "libp2p-swarm", "libp2p-tcp", "libp2p-upnp", + "libp2p-wasm-ext", "libp2p-websocket", "libp2p-yamux", "multiaddr 0.18.2", @@ -3685,6 +4070,20 @@ dependencies = [ "void", ] +[[package]] +name = "libp2p-wasm-ext" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e5d8e3a9e07da0ef5b55a9f26c009c8fb3c725d492d8bb4b431715786eea79c" +dependencies = [ + "futures", + "js-sys", + "libp2p-core", + "send_wrapper 0.6.0", + "wasm-bindgen", + "wasm-bindgen-futures", +] + [[package]] name = "libp2p-websocket" version = "0.42.2" @@ -3729,6 +4128,21 @@ dependencies = [ "libc", ] +[[package]] +name = "librocksdb-sys" +version = "0.11.0+8.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" +dependencies = [ + "bindgen", + "bzip2-sys", + "cc", + "glob", + "libc", + "libz-sys", + "tikv-jemalloc-sys", +] + [[package]] name = "libsecp256k1" version = "0.7.1" @@ -3756,7 +4170,7 @@ checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" dependencies = [ "crunchy", "digest 0.9.0", - "subtle", + "subtle 2.6.1", ] [[package]] @@ -3777,6 +4191,17 @@ dependencies = [ "libsecp256k1-core", ] +[[package]] +name = "libz-sys" +version = "1.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linked-hash-map" version = "0.5.6" @@ -3819,6 +4244,18 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db9c683daf087dc577b7506e9695b3d556a9f3849903fa28186283afd6809e9" +[[package]] +name = "lioness" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9" +dependencies = [ + "arrayref", + "blake2 0.8.1", + "chacha", + "keystream", +] + [[package]] name = "litemap" version = "0.7.5" @@ -3910,6 +4347,25 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "lz4" +version = "1.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a20b523e860d03443e98350ceaac5e71c6ba89aea7d960769ec3ce37f4de5af4" +dependencies = [ + "lz4-sys", +] + +[[package]] +name = "lz4-sys" +version = "1.11.1+lz4-1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bd8c0d6c6ed0cd30b3652886bb8711dc4bb01d637a68105a3d5158039b418e6" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "mach" version = "0.3.2" @@ -4013,6 +4469,24 @@ dependencies = [ "rustix 0.38.44", ] +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memmap2" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7" +dependencies = [ + "libc", +] + [[package]] name = "memoffset" version = "0.8.0" @@ -4069,6 +4543,31 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "mixnet" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daa3eb39495d8e2e2947a1d862852c90cc6a4a8845f8b41c8829cb9fcc047f4a" +dependencies = [ + "arrayref", + "arrayvec", + "bitflags 1.3.2", + "blake2 0.10.6", + "c2-chacha", + "curve25519-dalek", + "either", + "hashlink", + "lioness", + "log", + "parking_lot 0.12.3", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_distr", + "subtle 2.6.1", + "thiserror 1.0.69", + "zeroize", +] + [[package]] name = "mockall" version = "0.11.4" @@ -4351,6 +4850,12 @@ dependencies = [ "libc", ] +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + [[package]] name = "nohash-hasher" version = "0.2.0" @@ -4367,6 +4872,18 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nonempty" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + [[package]] name = "normalize-line-endings" version = "0.3.0" @@ -4445,6 +4962,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -4502,6 +5020,12 @@ version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + [[package]] name = "opaque-debug" version = "0.3.1" @@ -4514,6 +5038,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "overload" version = "0.1.1" @@ -4615,6 +5145,27 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "parity-db" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "592a28a24b09c9dc20ac8afaa6839abc417c720afe42c12e1e4a9d6aa2508d2e" +dependencies = [ + "blake2 0.10.6", + "crc32fast", + "fs2", + "hex", + "libc", + "log", + "lz4", + "memmap2 0.5.10", + "parking_lot 0.12.3", + "rand 0.8.5", + "siphasher", + "snap", + "winapi", +] + [[package]] name = "parity-scale-codec" version = "3.7.4" @@ -4718,7 +5269,7 @@ checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ "base64ct", "rand_core 0.6.4", - "subtle", + "subtle 2.6.1", ] [[package]] @@ -4737,6 +5288,12 @@ dependencies = [ "password-hash", ] +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + [[package]] name = "pem" version = "1.1.1" @@ -4927,7 +5484,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ "cpufeatures", - "opaque-debug", + "opaque-debug 0.3.1", "universal-hash", ] @@ -4939,10 +5496,16 @@ checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", "cpufeatures", - "opaque-debug", + "opaque-debug 0.3.1", "universal-hash", ] +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + [[package]] name = "powerfmt" version = "0.2.0" @@ -5218,6 +5781,21 @@ dependencies = [ "cc", ] +[[package]] +name = "quanta" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -5369,6 +5947,34 @@ dependencies = [ "getrandom 0.3.1", ] +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "rand_pcg" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "raw-cpuid" +version = "11.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" +dependencies = [ + "bitflags 2.9.0", +] + [[package]] name = "rawpointer" version = "0.2.1" @@ -5529,7 +6135,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ "hmac 0.12.1", - "subtle", + "subtle 2.6.1", ] [[package]] @@ -5583,6 +6189,16 @@ dependencies = [ "syn 2.0.99", ] +[[package]] +name = "rocksdb" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" +dependencies = [ + "libc", + "librocksdb-sys", +] + [[package]] name = "route-recognizer" version = "0.3.1" @@ -5723,7 +6339,7 @@ dependencies = [ "ring 0.17.13", "rustls-pki-types", "rustls-webpki 0.102.8", - "subtle", + "subtle 2.6.1", "zeroize", ] @@ -5867,6 +6483,59 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "sc-block-builder" +version = "0.43.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "parity-scale-codec", + "sp-api", + "sp-block-builder", + "sp-blockchain", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-trie", +] + +[[package]] +name = "sc-chain-spec" +version = "41.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "array-bytes", + "docify", + "log", + "memmap2 0.9.8", + "parity-scale-codec", + "sc-chain-spec-derive", + "sc-client-api", + "sc-executor", + "sc-network", + "sc-telemetry", + "serde", + "serde_json", + "sp-blockchain", + "sp-core", + "sp-crypto-hashing", + "sp-genesis-builder", + "sp-io", + "sp-runtime", + "sp-state-machine", + "sp-tracing", +] + +[[package]] +name = "sc-chain-spec-derive" +version = "12.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.99", +] + [[package]] name = "sc-client-api" version = "38.0.0" @@ -5895,22 +6564,48 @@ dependencies = [ ] [[package]] -name = "sc-consensus" -version = "0.47.0" +name = "sc-client-db" +version = "0.45.0" source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" dependencies = [ - "async-trait", - "futures", + "hash-db", + "kvdb", + "kvdb-memorydb", + "kvdb-rocksdb", + "linked-hash-map", "log", - "mockall 0.11.4", + "parity-db", + "parity-scale-codec", "parking_lot 0.12.3", "sc-client-api", - "sc-network-types", - "sc-utils", - "serde", - "sp-api", + "sc-state-db", + "schnellru", + "sp-arithmetic", "sp-blockchain", - "sp-consensus", + "sp-core", + "sp-database", + "sp-runtime", + "sp-state-machine", + "sp-trie", +] + +[[package]] +name = "sc-consensus" +version = "0.47.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "async-trait", + "futures", + "log", + "mockall 0.11.4", + "parking_lot 0.12.3", + "sc-client-api", + "sc-network-types", + "sc-utils", + "serde", + "sp-api", + "sp-blockchain", + "sp-consensus", "sp-core", "sp-runtime", "sp-state-machine", @@ -5983,6 +6678,66 @@ dependencies = [ "wasmtime", ] +[[package]] +name = "sc-informant" +version = "0.47.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "console", + "futures", + "futures-timer", + "log", + "sc-client-api", + "sc-network", + "sc-network-common", + "sc-network-sync", + "sp-blockchain", + "sp-runtime", +] + +[[package]] +name = "sc-keystore" +version = "34.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "array-bytes", + "parking_lot 0.12.3", + "serde_json", + "sp-application-crypto", + "sp-core", + "sp-keystore", + "thiserror 1.0.69", +] + +[[package]] +name = "sc-mixnet" +version = "0.18.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "array-bytes", + "arrayvec", + "blake2 0.10.6", + "bytes", + "futures", + "futures-timer", + "log", + "mixnet", + "multiaddr 0.18.2", + "parity-scale-codec", + "parking_lot 0.12.3", + "sc-client-api", + "sc-network", + "sc-network-types", + "sc-transaction-pool-api", + "sp-api", + "sp-consensus", + "sp-core", + "sp-keystore", + "sp-mixnet", + "sp-runtime", + "thiserror 1.0.69", +] + [[package]] name = "sc-network" version = "0.48.2" @@ -6052,6 +6807,27 @@ dependencies = [ "sp-runtime", ] +[[package]] +name = "sc-network-light" +version = "0.47.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "array-bytes", + "async-channel", + "futures", + "log", + "parity-scale-codec", + "prost 0.12.6", + "prost-build", + "sc-client-api", + "sc-network", + "sc-network-types", + "sp-blockchain", + "sp-core", + "sp-runtime", + "thiserror 1.0.69", +] + [[package]] name = "sc-network-sync" version = "0.47.0" @@ -6069,77 +6845,390 @@ dependencies = [ "prost 0.12.6", "prost-build", "sc-client-api", - "sc-consensus", - "sc-network", - "sc-network-common", - "sc-network-types", - "sc-utils", - "schnellru", - "smallvec", - "sp-arithmetic", + "sc-consensus", + "sc-network", + "sc-network-common", + "sc-network-types", + "sc-utils", + "schnellru", + "smallvec", + "sp-arithmetic", + "sp-blockchain", + "sp-consensus", + "sp-consensus-grandpa", + "sp-core", + "sp-runtime", + "substrate-prometheus-endpoint", + "thiserror 1.0.69", + "tokio", + "tokio-stream", +] + +[[package]] +name = "sc-network-transactions" +version = "0.47.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "array-bytes", + "futures", + "log", + "parity-scale-codec", + "sc-network", + "sc-network-common", + "sc-network-sync", + "sc-network-types", + "sc-utils", + "sp-consensus", + "sp-runtime", + "substrate-prometheus-endpoint", +] + +[[package]] +name = "sc-network-types" +version = "0.15.1" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "bs58", + "ed25519-dalek", + "libp2p-identity", + "litep2p", + "log", + "multiaddr 0.18.2", + "multihash 0.19.3", + "rand 0.8.5", + "thiserror 1.0.69", + "zeroize", +] + +[[package]] +name = "sc-offchain" +version = "43.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "array-bytes", + "bytes", + "fnv", + "futures", + "futures-timer", + "http-body-util", + "hyper 1.6.0", + "hyper-rustls", + "hyper-util", + "log", + "num_cpus", + "once_cell", + "parity-scale-codec", + "parking_lot 0.12.3", + "rand 0.8.5", + "rustls 0.23.23", + "sc-client-api", + "sc-network", + "sc-network-common", + "sc-network-types", + "sc-transaction-pool-api", + "sc-utils", + "sp-api", + "sp-core", + "sp-externalities", + "sp-keystore", + "sp-offchain", + "sp-runtime", + "threadpool", + "tracing", +] + +[[package]] +name = "sc-rpc" +version = "43.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "futures", + "jsonrpsee", + "log", + "parity-scale-codec", + "parking_lot 0.12.3", + "sc-block-builder", + "sc-chain-spec", + "sc-client-api", + "sc-mixnet", + "sc-rpc-api", + "sc-tracing", + "sc-transaction-pool-api", + "sc-utils", + "serde_json", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-keystore", + "sp-offchain", + "sp-rpc", + "sp-runtime", + "sp-session", + "sp-statement-store", + "sp-version", + "tokio", +] + +[[package]] +name = "sc-rpc-api" +version = "0.47.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "jsonrpsee", + "parity-scale-codec", + "sc-chain-spec", + "sc-mixnet", + "sc-transaction-pool-api", + "scale-info", + "serde", + "serde_json", + "sp-core", + "sp-rpc", + "sp-runtime", + "sp-version", + "thiserror 1.0.69", +] + +[[package]] +name = "sc-rpc-server" +version = "20.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "dyn-clone", + "forwarded-header-value", + "futures", + "governor", + "http 1.2.0", + "http-body-util", + "hyper 1.6.0", + "ip_network", + "jsonrpsee", + "log", + "sc-rpc-api", + "serde", + "serde_json", + "substrate-prometheus-endpoint", + "tokio", + "tower", + "tower-http", +] + +[[package]] +name = "sc-rpc-spec-v2" +version = "0.48.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "array-bytes", + "futures", + "futures-util", + "hex", + "itertools 0.11.0", + "jsonrpsee", + "log", + "parity-scale-codec", + "parking_lot 0.12.3", + "rand 0.8.5", + "sc-chain-spec", + "sc-client-api", + "sc-rpc", + "sc-transaction-pool-api", + "schnellru", + "serde", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-rpc", + "sp-runtime", + "sp-version", + "thiserror 1.0.69", + "tokio", + "tokio-stream", +] + +[[package]] +name = "sc-service" +version = "0.49.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "async-trait", + "directories", + "exit-future", + "futures", + "futures-timer", + "jsonrpsee", + "log", + "parity-scale-codec", + "parking_lot 0.12.3", + "pin-project", + "rand 0.8.5", + "sc-chain-spec", + "sc-client-api", + "sc-client-db", + "sc-consensus", + "sc-executor", + "sc-informant", + "sc-keystore", + "sc-network", + "sc-network-common", + "sc-network-light", + "sc-network-sync", + "sc-network-transactions", + "sc-network-types", + "sc-rpc", + "sc-rpc-server", + "sc-rpc-spec-v2", + "sc-sysinfo", + "sc-telemetry", + "sc-tracing", + "sc-transaction-pool", + "sc-transaction-pool-api", + "sc-utils", + "schnellru", + "serde", + "serde_json", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-externalities", + "sp-keystore", + "sp-runtime", + "sp-session", + "sp-state-machine", + "sp-storage", + "sp-transaction-pool", + "sp-transaction-storage-proof", + "sp-trie", + "sp-version", + "static_init", + "substrate-prometheus-endpoint", + "tempfile", + "thiserror 1.0.69", + "tokio", + "tracing", + "tracing-futures", +] + +[[package]] +name = "sc-state-db" +version = "0.37.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "log", + "parity-scale-codec", + "parking_lot 0.12.3", + "sp-core", +] + +[[package]] +name = "sc-sysinfo" +version = "41.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "derive_more 0.99.19", + "futures", + "libc", + "log", + "rand 0.8.5", + "rand_pcg", + "regex", + "sc-telemetry", + "serde", + "serde_json", + "sp-core", + "sp-crypto-hashing", + "sp-io", + "sp-std", +] + +[[package]] +name = "sc-telemetry" +version = "28.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "chrono", + "futures", + "libp2p", + "log", + "parking_lot 0.12.3", + "pin-project", + "rand 0.8.5", + "sc-network", + "sc-utils", + "serde", + "serde_json", + "thiserror 1.0.69", + "wasm-timer", +] + +[[package]] +name = "sc-tracing" +version = "38.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "chrono", + "console", + "is-terminal", + "libc", + "log", + "parity-scale-codec", + "parking_lot 0.12.3", + "rustc-hash 1.1.0", + "sc-client-api", + "sc-tracing-proc-macro", + "serde", + "sp-api", "sp-blockchain", - "sp-consensus", - "sp-consensus-grandpa", "sp-core", + "sp-rpc", "sp-runtime", - "substrate-prometheus-endpoint", + "sp-tracing", "thiserror 1.0.69", - "tokio", - "tokio-stream", + "tracing", + "tracing-log", + "tracing-subscriber", ] [[package]] -name = "sc-network-types" -version = "0.15.1" +name = "sc-tracing-proc-macro" +version = "11.0.0" source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" dependencies = [ - "bs58", - "ed25519-dalek", - "libp2p-identity", - "litep2p", - "log", - "multiaddr 0.18.2", - "multihash 0.19.3", - "rand 0.8.5", - "thiserror 1.0.69", - "zeroize", + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.99", ] [[package]] -name = "sc-offchain" -version = "43.0.0" +name = "sc-transaction-pool" +version = "38.1.0" source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" dependencies = [ - "array-bytes", - "bytes", - "fnv", + "async-trait", "futures", "futures-timer", - "http-body-util", - "hyper 1.6.0", - "hyper-rustls", - "hyper-util", + "indexmap 2.7.1", + "itertools 0.11.0", + "linked-hash-map", "log", - "num_cpus", - "once_cell", "parity-scale-codec", "parking_lot 0.12.3", - "rand 0.8.5", - "rustls 0.23.23", "sc-client-api", - "sc-network", - "sc-network-common", - "sc-network-types", "sc-transaction-pool-api", "sc-utils", + "serde", "sp-api", + "sp-blockchain", "sp-core", - "sp-externalities", - "sp-keystore", - "sp-offchain", + "sp-crypto-hashing", "sp-runtime", - "threadpool", - "tracing", + "sp-tracing", + "sp-transaction-pool", + "substrate-prometheus-endpoint", + "thiserror 1.0.69", + "tokio", + "tokio-stream", ] [[package]] @@ -6233,7 +7322,7 @@ dependencies = [ "rand_core 0.6.4", "serde_bytes", "sha2 0.10.8", - "subtle", + "subtle 2.6.1", "zeroize", ] @@ -6261,10 +7350,10 @@ checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", - "generic-array", + "generic-array 0.14.7", "pkcs8", "serdect", - "subtle", + "subtle 2.6.1", "zeroize", ] @@ -6344,6 +7433,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + [[package]] name = "serde" version = "1.0.218" @@ -6425,7 +7520,7 @@ dependencies = [ "cfg-if", "cpufeatures", "digest 0.9.0", - "opaque-debug", + "opaque-debug 0.3.1", ] [[package]] @@ -6502,6 +7597,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "620a1d43d70e142b1d46a929af51d44f383db9c7a2ec122de2cd992ccfcf3c18" +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" @@ -6523,6 +7624,12 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +[[package]] +name = "snap" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" + [[package]] name = "snow" version = "0.9.6" @@ -6530,14 +7637,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "850948bee068e713b8ab860fe1adc4d109676ab4c3b621fd8147f06b261f2f85" dependencies = [ "aes-gcm", - "blake2", + "blake2 0.10.6", "chacha20poly1305", "curve25519-dalek", "rand_core 0.6.4", "ring 0.17.13", "rustc_version", "sha2 0.10.8", - "subtle", + "subtle 2.6.1", ] [[package]] @@ -6604,7 +7711,7 @@ version = "21.0.0" source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" dependencies = [ "Inflector", - "blake2", + "blake2 0.10.6", "expander", "proc-macro-crate 3.3.0", "proc-macro2", @@ -6638,6 +7745,16 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "sp-block-builder" +version = "35.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "sp-api", + "sp-inherents", + "sp-runtime", +] + [[package]] name = "sp-blockchain" version = "38.0.0" @@ -6696,7 +7813,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412 dependencies = [ "array-bytes", "bitflags 1.3.2", - "blake2", + "blake2 0.10.6", "bounded-collections", "bs58", "dyn-clonable", @@ -6868,6 +7985,17 @@ dependencies = [ "scale-info", ] +[[package]] +name = "sp-mixnet" +version = "0.13.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-application-crypto", +] + [[package]] name = "sp-offchain" version = "35.0.0" @@ -6887,6 +8015,16 @@ dependencies = [ "regex", ] +[[package]] +name = "sp-rpc" +version = "33.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "rustc-hash 1.1.0", + "serde", + "sp-core", +] + [[package]] name = "sp-runtime" version = "40.1.0" @@ -6948,6 +8086,20 @@ dependencies = [ "syn 2.0.99", ] +[[package]] +name = "sp-session" +version = "37.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-core", + "sp-keystore", + "sp-runtime", + "sp-staking", +] + [[package]] name = "sp-staking" version = "37.0.0" @@ -7033,6 +8185,29 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "sp-transaction-pool" +version = "35.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "sp-api", + "sp-runtime", +] + +[[package]] +name = "sp-transaction-storage-proof" +version = "35.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-2#863f353d20749caccfd1ccd548cc0cd85291f3a8" +dependencies = [ + "async-trait", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-trie", +] + [[package]] name = "sp-trie" version = "38.0.0" @@ -7116,6 +8291,15 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spinning_top" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" version = "0.7.3" @@ -7216,6 +8400,34 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "static_init" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bae1df58c5fea7502e8e352ec26b5579f6178e1fdb311e088580c980dee25ed" +dependencies = [ + "bitflags 1.3.2", + "cfg_aliases 0.2.1", + "libc", + "parking_lot 0.12.3", + "parking_lot_core 0.9.10", + "static_init_macro", + "winapi", +] + +[[package]] +name = "static_init_macro" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1389c88ddd739ec6d3f8f83343764a0e944cd23cfbf126a9796a714b0b6edd6f" +dependencies = [ + "cfg_aliases 0.1.1", + "memchr", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "substrate-bip39" version = "0.6.0" @@ -7242,6 +8454,12 @@ dependencies = [ "tokio", ] +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + [[package]] name = "subtle" version = "2.6.1" @@ -7414,6 +8632,16 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "tikv-jemalloc-sys" +version = "0.5.4+5.3.0-patched" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9402443cb8fd499b6f327e40565234ff34dbda27460c5b47db0db77443dd85d1" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "time" version = "0.3.39" @@ -7617,6 +8845,22 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower-http" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" +dependencies = [ + "bitflags 2.9.0", + "bytes", + "http 1.2.0", + "http-body 1.0.1", + "http-body-util", + "pin-project-lite", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -7662,6 +8906,16 @@ dependencies = [ "valuable", ] +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + [[package]] name = "tracing-log" version = "0.2.0" @@ -7682,6 +8936,7 @@ dependencies = [ "matchers", "nu-ansi-term", "once_cell", + "parking_lot 0.12.3", "regex", "sharded-slab", "smallvec", @@ -7886,6 +9141,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-width" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" + [[package]] name = "unicode-xid" version = "0.2.6" @@ -7899,7 +9160,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ "crypto-common", - "subtle", + "subtle 2.6.1", ] [[package]] @@ -7971,6 +9232,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" @@ -8439,7 +9706,7 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efc5cf48f83140dcaab716eeaea345f9e93d0018fb81162753a3f76c3397b538" dependencies = [ - "windows-core", + "windows-core 0.53.0", "windows-targets 0.52.6", ] @@ -8449,10 +9716,51 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dcc5b895a6377f1ab9fa55acedab1fd5ac0db66ad1e6c7f47e28a22e446a5dd" dependencies = [ - "windows-result", + "windows-result 0.1.2", "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result 0.3.4", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.99", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.99", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + [[package]] name = "windows-result" version = "0.1.2" @@ -8462,6 +9770,24 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.45.0" diff --git a/Cargo.toml b/Cargo.toml index 34bce8c..d113f1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ "rpc", "pallet-epico", "primitives/*", + "receipt-service" ] resolver = "2" @@ -22,6 +23,7 @@ frame-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk", tag = futures = { version = "0.3.30" } jsonrpsee = { version = "0.24.3" } log = { version = "0.4.21", default-features = false } +tracing = { version = "0.1.41", default-features = false } sc-network = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-2", default-features = false } sc-network-sync = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-2", default-features = false } sc-transaction-pool = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-2", default-features = false } @@ -34,6 +36,7 @@ libsecp256k1 = { version = "0.7.1", default-features = false } sc-client-api = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-2", default-features = false } sp-consensus = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-2", default-features = false } sc-offchain = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-2", default-features = false } +sc-service = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-2", default-features = false } sp-api = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-2", default-features = false } sp-blockchain = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-2", default-features = false } sp-core = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-2", default-features = false } diff --git a/README.md b/README.md index 0b391c1..45d4ceb 100644 --- a/README.md +++ b/README.md @@ -58,22 +58,23 @@ epico/ │ ├── self-contained/ # Self-contained logic and primitives │ ├── xcm/ # Cross-Consensus Messaging (XCM) primitives ├── rpc/ # Remote Procedure Call implementations +├── receipt-service/ # Offchain worker for managing receipts ``` --- ## Advantages of Native Execution -1. **Improved Performance and Throughput** +1. **Improved Performance and Throughput** By bypassing EVM emulation, Ethereum transactions are processed directly by the Substrate runtime, leading to faster and more efficient operations. -2. **Customizability** +2. **Customizability** Substrate runtimes are known for their flexibility. With native execution, developers can tailor execution logic to their specific projects, something that’s not easily achievable in a strict EVM environment. -3. **Lower Gas Costs** +3. **Lower Gas Costs** Native execution leverages Substrate’s optimized gas metering. This often results in cheaper fees compared to Ethereum’s traditional gas model. -4. **Enhanced Security** +4. **Enhanced Security** By avoiding known EVM vulnerabilities (like certain reentrancy attacks or gas-limit exploits), Epico creates a more secure environment for transaction processing. --- @@ -92,18 +93,21 @@ As a result, tools like **MetaMask**, **Hardhat**, and other Ethereum-compatible ## How Epico Works: Architecture Overview -Epico’s compatibility layer is built on three main components: +Epico's compatibility layer is built on four main components: -1. **Epico RPC** +1. **Epico RPC** This module, embedded within the client, exposes Ethereum JSON-RPC methods. It acts as a “mask,” presenting a Substrate node as a standard Ethereum node to external clients and tools. ![Substrate Node](./docs/substrate-node.png) -2. **Epico Pallet** +2. **Epico Pallet** The core logic that validates, decodes, and executes Ethereum transactions within the Substrate environment. It handles storage of execution results so that transaction receipts and execution outcomes can be queried later. -3. **Epico Pallet Runtime APIs** +3. **Epico Pallet Runtime APIs** These APIs provide an interface between the runtime and the Epico RPC client, retrieving the necessary data (balance, nonce, block info, etc.) for Ethereum-compatible RPC responses. +4. **Epico Receipt Service** + An offchain service that manages transaction receipts in persistent storage. It runs two workers: one stores receipts as "untrusted" on block import, another promotes them to "finalized" on finality events. Features automatic garbage collection that follows the node's state pruning configuration and gap-filling for missed events. Essential for Ethereum RPC compatibility. + In addition, Epico leverages a custom `UncheckedExtrinsic` and `CheckedExtrinsic` flow (inspired by Frontier) to handle validation, pre-dispatch, dispatch, and post-dispatch logic for transactions submitted through the Epico RPC. --- @@ -112,10 +116,10 @@ In addition, Epico leverages a custom `UncheckedExtrinsic` and `CheckedExtrinsic Because Ethereum addresses are **20 bytes** long, any Substrate runtime that leverages Epico must accommodate Ethereum-style accounts. There are two main ways to do this: -1. **Native Ethereum Accounts** +1. **Native Ethereum Accounts** Adopt a **unified** 20-byte account model as your chain’s default (similar to Moonbeam). This simplifies interoperability because Ethereum and Substrate addresses are the same format. -2. **Account Conversion Mechanism** +2. **Account Conversion Mechanism** Implement a way to **map** Substrate’s default 32-byte addresses to a 20-byte address. This keeps your node’s default account structure intact while still allowing Ethereum-based tools to connect and interact. --- diff --git a/docs/INTEGRATION.md b/docs/INTEGRATION.md index fad8526..d03f591 100644 --- a/docs/INTEGRATION.md +++ b/docs/INTEGRATION.md @@ -15,6 +15,7 @@ From your project setup, "Epico" consists of various components located under th - [`ep-rpc`](./rpc) - [`pallet-epico-runtime-api`](./pallet-epico/runtime-api) - [`pallet-epico`](./pallet-epico) + - [`epico-receipt-service`](./receipt-service) Each of these serves a specific purpose (e.g., primitives for fundamental types or logic, RPC components for Ethereum compatibility). @@ -34,6 +35,7 @@ ep-ethereum = { path = "../epico/primitives/ethereum", default-features = false ep-rpc = { path = "../epico/rpc" } pallet-epico-runtime-api = { path = "../epico/pallet-epico/runtime-api", default-features = false } pallet-epico = { path = "../epico/pallet-epico", default-features = false } +epico-receipt-service = { path = "../epico/receipt-service" } ``` --- @@ -213,14 +215,16 @@ The `pallet-epico` module enables Ethereum compatibility features. U256::from(adjusted_fee_per_gas) } - fn safe_finality_depth() -> u8 { - ::SafeFinalityDepth::get() - } - fn block_timestamp() -> U256 { Timestamp::get().into() } + fn build_receipt_at(block_number: u32) -> Vec> { + pallet_epico::ExecutedTransaction::::iter_prefix(block_number).map(|(hash, transaction_info)| + pallet_epico::Pallet::::get_transaction_receipt(hash, transaction_info, block_number) + ).collect() + } + fn dry_run_eth_transaction(call: TransactionCall) -> Result<(), Vec> { Epico::dry_run(call).map_err(|e| format!("{:?}", e).encode())?; Ok(()) @@ -518,10 +522,47 @@ The RPC module provides Ethereum JSON-RPC compatibility for interacting with Eth --- +## Step 7: Add Receipt Service for Transaction Receipt Storage + +The `epico-receipt-service` is an offchain service that manages transaction receipts in persistent storage. It runs two workers: one stores receipts as "untrusted" on block import, another promotes them to "finalized" on finality events. + +1. Add the `epico-receipt-service` dependency in your **node's** `Cargo.toml` file: + + ```toml + [dependencies] + epico-receipt-service = { workspace = true } + ``` + +2. Initialize and spawn the receipt service in your node's service setup (e.g., `node/src/service.rs`): + + ```rust + use epico_receipt_service::ReceiptService; + + // In your service setup function + let receipt_service = ReceiptService::<_, Block, solochain_template_runtime::Runtime, _>::new( + &config, + client.clone(), + backend + .offchain_storage() + .ok_or_else(|| "Offchain storage not available")?, + ); + + task_manager.spawn_handle().spawn( + "receipt-service-offchain-workers-runner", + "receipt-service-offchain-worker", + receipt_service.run(task_manager.spawn_handle()).boxed(), + ); + ``` + +**Note**: The `build_receipt_at` runtime API method required by this service has already been added to the runtime API implementation in Step 4. + +--- + ## Summary checklist 1. Add `Epico` dependencies to `Cargo.toml`. 2. Integrate AccountId20 into your runtime. 3. Add the `pallet-epico` implementation to the runtime. 4. Integrate the `ep-self-contained` package into your runtime. -5. Set up the RPC for Ethereum compatibility +5. Set up the RPC for Ethereum compatibility. +6. Add Receipt Service for transaction receipt storage. diff --git a/pallet-epico/runtime-api/src/lib.rs b/pallet-epico/runtime-api/src/lib.rs index 4c7c8f8..9b35b92 100644 --- a/pallet-epico/runtime-api/src/lib.rs +++ b/pallet-epico/runtime-api/src/lib.rs @@ -5,7 +5,7 @@ use ep_ethereum::{ common::TransactionV2, ethereum_types::{Address, H160, U256}, }; -use pallet_epico::types::TransactionCall; +use pallet_epico::types::{TransactionCall, TransactionReceipt}; use parity_scale_codec::{Decode, Encode}; use sp_runtime::traits::Block as BlockT; use sp_runtime::Vec; @@ -39,12 +39,13 @@ sp_api::decl_runtime_apis! { /// Get best effort estimation for a gas price. fn gas_price() -> U256; - /// Returns pallet-epico's configured safe finality depth. - fn safe_finality_depth() -> u8; - /// Retrieves the timestamp for the current block. fn block_timestamp() -> U256; + /// Runtime api for returning transaction receipts of all `pallet_epico::ExecutedTransaction` + /// in a given block. + fn build_receipt_at(block_number: u32) -> Vec>; + /// Performs a dry-run of the given Ethereum-style transaction without modifying state. /// /// Returns `Ok(())` if the transaction would succeed, or an `Err` containing the diff --git a/pallet-epico/src/lib.rs b/pallet-epico/src/lib.rs index 0ccdc55..ef8d9c9 100644 --- a/pallet-epico/src/lib.rs +++ b/pallet-epico/src/lib.rs @@ -34,7 +34,6 @@ pub mod pallet { use scale_info::prelude::boxed::Box; use sp_runtime::{ - offchain::storage::StorageValueRef, traits::{Dispatchable, Saturating, StaticLookup, UniqueSaturatedInto}, DispatchError, FixedPointNumber, FixedU128, Perbill, SaturatedConversion, Vec, Weight, }; @@ -42,8 +41,8 @@ pub mod pallet { use weights::WeightInfo; use crate::types::{ - default_transaction_from_tx_call, get_block_transaction_offchain_key, get_tx_offchain_key, - BalanceOf, ExecutedTransactionInfo, ExecutedTransactionInfoOf, OffchainStatus, + default_transaction_from_tx_call, BalanceOf, ExecutedTransactionInfo, + ExecutedTransactionInfoOf, }; use frame_system::WeightInfo as SystemWeightInfo; @@ -65,13 +64,6 @@ pub mod pallet { /// Coefficient to overestimate gas estimation /// by a factor of N. type GasEstimationCoefficient: Get; - - /// The number of block ancestors to consider as safely finalized. - /// - /// This represents a depth from the current best block, below which - /// blocks are presumed to be finalized, even if finality has not - /// been explicitly confirmed via the consensus mechanism. - type SafeFinalityDepth: Get; } /// Reference Gas consumtion for a set of operations in the EVM. @@ -186,26 +178,8 @@ pub mod pallet { NextTransactionIndex::::set(0); } - /// The offchain worker stores transaction data for the current block and - /// handles promoting previously untrusted data to finalized status - /// once it’s deemed safe based on `SafeFinalityDepth`. - fn offchain_worker(block_number: BlockNumberFor) { - // Store transactions from the latest block in the offchain DB. - // - // Since the block is not finalized, it is subject to reorgs, - // so the data is stored under the "Untrusted" prefix. - Self::store_newest_data_offchain(block_number); - - // Promote older transactions to "Finalized" status if they are - // sufficiently deep in the chain (based on SafeFinalityDepth). - // - // This involves moving the data to the "Finalized" prefix - // and cleaning up its untrusted counterpart. - Self::store_finalized_data_offchain(block_number); - } - fn on_initialize(n: BlockNumberFor) -> Weight { - let safe_to_clear_block = Self::safe_finalized_block(n).saturating_sub(1u8.into()); + let safe_to_clear_block = n.saturating_sub(1u8.into()); // Wipe ExecutedTransactions Map and return number of removed transactions let keys_removed = @@ -441,20 +415,20 @@ pub mod pallet { /// Substrate weight units into gas units, taking into account various transaction factors. /// /// ### Process: - /// 1. **Extract Runtime Call**: - /// - If transaction `data` exists, decode it into a runtime call. + /// 1. **Extract Runtime Call**: + /// - If transaction `data` exists, decode it into a runtime call. /// - If no data is provided, fallback to a default `transfer_keep_alive` call. /// - /// 2. **Weight Calculation**: - /// - Retrieve the call weight via `get_dispatch_info()`. - /// - Add the base extrinsic weight for a normal transaction class. - /// - Add length-derived weight based on the encoded transaction length. - /// - Add weight for storing executed transactions. + /// 2. **Weight Calculation**: + /// - Retrieve the call weight via `get_dispatch_info()`. + /// - Add the base extrinsic weight for a normal transaction class. + /// - Add length-derived weight based on the encoded transaction length. + /// - Add weight for storing executed transactions. /// - /// 3. **Gas Adjustment**: + /// 3. **Gas Adjustment**: /// - Apply a configurable `GasEstimationCoefficient` multiplier to adjust the weight for conservative gas estimates. /// - /// 4. **Weight-to-Gas Conversion**: + /// 4. **Weight-to-Gas Conversion**: /// - Convert the final weight into an approximate gas value using a predefined reference ratio between Substrate weight and EVM gas. /// - The conversion factors in both `ref_time` and `proof_size` components of the weight. pub fn extract_gas_from_transaction_call(request: TransactionCall) -> Option { @@ -593,115 +567,6 @@ pub mod pallet { .len() as u64 } - /// Stores all epico executed transactions for the current block in offchain - /// persistent storage under the `Untrusted` prefix. - /// - /// This data is considered "untrusted" because the block may still be - /// reorged out of the canonical chain. - fn store_newest_data_offchain(current_block: BlockNumberFor) { - let mut block_transactions: Vec = Vec::new(); - - // Iterate over all transactions executed in the block. - for (transaction_hash, transaction_info) in - ExecutedTransaction::::iter_prefix(current_block) - { - block_transactions.push(transaction_hash); - - // Persist the transaction receipt under the "Untrusted" offchain key. - StorageValueRef::persistent(&get_tx_offchain_key( - OffchainStatus::Untrusted, - transaction_hash, - )) - .set( - &Self::get_transaction_receipt( - transaction_hash, - transaction_info, - current_block, - ) - .encode(), - ); - } - - if block_transactions.is_empty() { - return; - } - - // Store a mapping of transaction hashes for this block. - StorageValueRef::persistent(&get_block_transaction_offchain_key( - OffchainStatus::Untrusted, - current_block.encode(), - )) - .set(&block_transactions.encode()); - } - - /// Promotes transactions from a sufficiently old block to "Finalized" status - /// in the offchain DB. - /// - /// This assumes that blocks older than `SafeFinalityDepth` are finalized - /// and no longer subject to forks. - pub fn store_finalized_data_offchain(current_block: BlockNumberFor) { - let safe_finalized_block = Self::safe_finalized_block(current_block); - - let mut block_transactions: Vec = Vec::new(); - - // Iterate over all transactions in the finalized block. - for (transaction_hash, transaction_info) in - ExecutedTransaction::::iter_prefix(safe_finalized_block) - { - block_transactions.push(transaction_hash); - - // Move receipts to "Finalized" namespace. - StorageValueRef::persistent(&get_tx_offchain_key( - OffchainStatus::Finalized, - transaction_hash, - )) - .set( - &Self::get_transaction_receipt( - transaction_hash, - transaction_info, - safe_finalized_block, - ) - .encode(), - ); - - // Remove the untrusted version of this receipt. - StorageValueRef::persistent(&get_tx_offchain_key( - OffchainStatus::Untrusted, - transaction_hash, - )) - .clear(); - } - - if block_transactions.is_empty() { - return; - } - - // Store finalized transaction hash list and remove the untrusted copy. - StorageValueRef::persistent(&get_block_transaction_offchain_key( - OffchainStatus::Finalized, - safe_finalized_block.encode(), - )) - .set(&block_transactions.encode()); - - StorageValueRef::persistent(&get_block_transaction_offchain_key( - OffchainStatus::Untrusted, - safe_finalized_block.encode(), - )) - .clear(); - } - - /// Calculates the oldest block that can be assumed finalized based on - /// the provided `block_number` and the configured `SafeFinalityDepth`. - /// - /// This is used to compensate for the lack of finalized - /// block information within the runtime. - fn safe_finalized_block(block_number: BlockNumberFor) -> BlockNumberFor { - let safe_finality_depth: BlockNumberFor = - BlockNumberFor::::saturated_from(T::SafeFinalityDepth::get()); - - block_number.saturating_sub(safe_finality_depth) - } - /// Dry-runs a given transaction. /// /// This function is intended **only** for use within a runtime API context, diff --git a/pallet-epico/src/mock.rs b/pallet-epico/src/mock.rs index ca6b87a..ccca89f 100644 --- a/pallet-epico/src/mock.rs +++ b/pallet-epico/src/mock.rs @@ -83,7 +83,6 @@ impl crate::Config for Test { type WeightInfo = (); type Call = RuntimeCall; type GasEstimationCoefficient = GasEstimationCoefficient; - type SafeFinalityDepth = ConstU8<10>; } parameter_types! { diff --git a/pallet-epico/src/tests.rs b/pallet-epico/src/tests.rs index 5d933d3..bf82ebd 100644 --- a/pallet-epico/src/tests.rs +++ b/pallet-epico/src/tests.rs @@ -1,7 +1,7 @@ use crate::{ mock::*, types::{ExecutedTransactionInfoOf, TransactionCall}, - Config, Error, ExecutedTransaction, NextTransactionIndex, ReentrancyGuard, + Error, ExecutedTransaction, NextTransactionIndex, ReentrancyGuard, }; use ep_ethereum::common::{ LegacyTransaction, TransactionAction, TransactionSignature, TransactionV2 as Transaction, @@ -10,7 +10,6 @@ use frame_support::traits::OnFinalize; use frame_support::{assert_noop, assert_ok, traits::fungible::Mutate}; use hex_literal::hex; use parity_scale_codec::Encode; -use sp_core::Get; use sp_core::U256; use sp_runtime::{ArithmeticError, Vec, Weight}; @@ -434,8 +433,7 @@ fn clean_transactions_after_safe_finalization_depth() { ExecutedTransaction::::get(initial_block_number, transaction.hash()).is_some() ); - let safe_finality_depth: u8 = ::SafeFinalityDepth::get(); - initialize_to_block(initial_block_number.saturating_add((safe_finality_depth + 1).into())); + initialize_to_block(initial_block_number.saturating_add((2_u64).into())); assert!( ExecutedTransaction::::get(initial_block_number, transaction.hash()).is_none() diff --git a/pallet-epico/src/types.rs b/pallet-epico/src/types.rs index e0818d3..c90ad3f 100644 --- a/pallet-epico/src/types.rs +++ b/pallet-epico/src/types.rs @@ -163,7 +163,7 @@ pub fn default_transaction_from_tx_call(call: TransactionCall) -> Transaction { Transaction::Legacy(transaction) } -#[derive(Clone, Eq, PartialEq)] +#[derive(Clone, Eq, PartialEq, Debug)] pub enum OffchainStatus { Untrusted, Finalized, diff --git a/receipt-service/Cargo.toml b/receipt-service/Cargo.toml new file mode 100644 index 0000000..59d9dd4 --- /dev/null +++ b/receipt-service/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "epico-receipt-service" +version = "0.1.0" +description = "Ethereum RPC" +authors = { workspace = true } +edition = { workspace = true } +repository = { workspace = true } + +[dependencies] +serde = { workspace = true, default-features = true } +parity-scale-codec = { workspace = true, default-features = true } +tracing = { workspace = true, default-features = true } +futures = { workspace = true, default-features = true } +frame-system = { workspace = true, default-features = true } +sc-service = { workspace = true, default-features = true } +sc-client-api = { workspace = true, default-features = true } +sc-offchain = { workspace = true, default-features = true } +sp-api = { workspace = true, default-features = true } +sp-blockchain = { workspace = true, default-features = true } +sp-core = { workspace = true, default-features = true } +sp-runtime = { workspace = true, default-features = true } +sp-io = { workspace = true, default-features = true } +sc-network = { workspace = true, default-features = true } +pallet-balances = { workspace = true, default-features = true } +pallet-epico-runtime-api = { workspace = true, default-features = true } +pallet-epico = { workspace = true, default-features = true } +ep-account = { workspace = true, default-features = true } + +[features] +default = ["std"] +std = [] diff --git a/receipt-service/src/lib.rs b/receipt-service/src/lib.rs new file mode 100644 index 0000000..e23a591 --- /dev/null +++ b/receipt-service/src/lib.rs @@ -0,0 +1,574 @@ +use std::sync::Arc; + +use frame_system::pallet_prelude::BlockNumberFor; +use futures::StreamExt; +use parity_scale_codec::{Decode, Encode}; +use sc_client_api::AuxStore; +use sc_network::peer_store::LOG_TARGET; +use sc_offchain::OffchainDb; +use sc_service::Configuration; +use sp_api::ApiExt; +use sp_core::{ + offchain, + offchain::{DbExternalities, StorageKind}, + traits::SpawnNamed, + H160, H256, +}; +use sp_runtime::{ + traits::{Block as BlockT, Header, Header as HeaderT, PhantomData, UniqueSaturatedInto}, + SaturatedConversion, +}; + +use ep_account::AccountId20; +use pallet_epico::types::{ + get_block_transaction_offchain_key, get_tx_offchain_key, OffchainStatus, TransactionReceipt, +}; +use pallet_epico_runtime_api::EpicoRuntimeApi; + +const AUX_WM_KEY: &[u8] = b"receipt_service.finalized_watermark"; +const AUX_FIN_KEPT_FROM: &[u8] = b"receipt_service.finalized_kept_from"; +const AUX_UNT_KEPT_FROM: &[u8] = b"receipt_service.untrusted_kept_from"; + +/// Last block number that we processed receipts for. +#[derive(Encode, Decode, Clone, Default, Debug)] +struct FinalizedWatermark { + up_to: u64, +} + +/// Oldest block number that we have kept receipts for. +#[derive(Encode, Decode, Clone, Default, Debug)] +struct ReceiptsKeptFrom { + block_number: u64, +} + +impl From for ReceiptsKeptFrom { + fn from(block_number: u64) -> Self { + ReceiptsKeptFrom { block_number } + } +} + +/// Pruning policy for receipts, the configuration is derived from the node's +/// state pruning settings via [`Configuration`]. +#[derive(Clone, Debug, Encode, Decode)] +pub struct ReceiptGcPolicy { + /// None means keep all finalized receipts. + pub keep_blocks: Option, + /// Amount of blocks to prune per execution cycle. + pub gc_step: u64, +} + +impl From<&Configuration> for ReceiptGcPolicy { + fn from(cfg: &Configuration) -> Self { + let keep_finalized_blocks = { + match cfg.state_pruning.clone() { + Some(sc_service::PruningMode::Constrained(blocks)) + if blocks.max_blocks.is_some() => + { + // max_blocks should default to 0 when unspecified + // as per `sc_state_db::Constraints` documentation. + Some(blocks.max_blocks.unwrap_or(0).into()) + } + _ => None, + } + }; + ReceiptGcPolicy { + keep_blocks: keep_finalized_blocks, + gc_step: 1_000, + } + } +} + +/// Epico offchain receipt service. +#[derive(Encode, Decode, Debug)] +pub struct ReceiptService { + pub client: Arc, + pub storage: OffchainDb, + pub gc_policy: ReceiptGcPolicy, + pub _phantom: PhantomData<(Client, Block, Runtime)>, +} + +impl ReceiptService +where + Block: BlockT, + Client: sp_api::ProvideRuntimeApi + + sc_client_api::BlockBackend + + sc_client_api::blockchain::HeaderBackend + + sp_runtime::traits::BlockIdTo + + sc_client_api::ExecutorProvider + + sc_client_api::UsageProvider + + sp_blockchain::HeaderMetadata + + sc_client_api::BlockchainEvents + + AuxStore + + Send + + Sync + + 'static, + Client::Api: + pallet_epico_runtime_api::EpicoRuntimeApi, + ::Hash: std::marker::Unpin, + Runtime: pallet_epico::Config + Send + Sync, + ::AccountId: From + From, + Storage: sp_runtime::offchain::OffchainStorage + 'static, +{ + pub fn new(cfg: &Configuration, client: Arc, storage: Storage) -> Self { + Self { + client, + storage: OffchainDb::new(storage), + gc_policy: cfg.into(), + _phantom: Default::default(), + } + } + + /// Loads the oldest block number from which we have unfinalized receipts. + fn load_untrusted_kept_from(&self) -> ReceiptsKeptFrom { + self.client + .get_aux(AUX_UNT_KEPT_FROM) + .ok() + .flatten() + .and_then(|v| ReceiptsKeptFrom::decode(&mut &v[..]).ok()) + .unwrap_or_default() + } + + /// Stores the new oldest block number from which we have unfinalized receipts. + fn persist_untrusted_kept_from(&self, kept_from: &ReceiptsKeptFrom) { + let _ = self + .client + .insert_aux(&[(AUX_UNT_KEPT_FROM, kept_from.encode().as_slice())], &[]); + } + + /// Loads the oldest block number from which we have finalized receipts. + fn load_finalized_kept_from(&self) -> ReceiptsKeptFrom { + self.client + .get_aux(AUX_FIN_KEPT_FROM) + .ok() + .flatten() + .and_then(|v| ReceiptsKeptFrom::decode(&mut &v[..]).ok()) + .unwrap_or_default() + } + + /// Stores the new oldest block number from which we have finalized receipts. + fn persist_finalized_kept_from(&self, kept_from: &ReceiptsKeptFrom) { + let _ = self + .client + .insert_aux(&[(AUX_FIN_KEPT_FROM, kept_from.encode().as_slice())], &[]); + } + + fn do_prune_block( + storage: &mut OffchainDb, + offchain_status: OffchainStatus, + runtime_block: BlockNumberFor, + ) { + let block_transactions_key = + get_block_transaction_offchain_key(offchain_status.clone(), runtime_block.encode()); + let block_transactions: Vec = storage + .local_storage_get(StorageKind::PERSISTENT, &block_transactions_key) + .and_then(|v| Vec::::decode(&mut &v[..]).ok()) + .unwrap_or_default(); + + for tx_hash in block_transactions { + let tx_key = get_tx_offchain_key(offchain_status.clone(), tx_hash); + storage.local_storage_clear(StorageKind::PERSISTENT, &tx_key); + } + + storage.local_storage_clear(StorageKind::PERSISTENT, &block_transactions_key); + tracing::debug!( + target: LOG_TARGET, + "Pruned {:?} receipts from block_number: {}", offchain_status, runtime_block, + ); + } + + fn prune_receipts( + &self, + mut storage: OffchainDb, + offchain_status: OffchainStatus, + kept_from: u64, + last_to_keep: u64, + ) { + for block in kept_from..last_to_keep { + Self::do_prune_block( + &mut storage, + offchain_status.clone(), + block.unique_saturated_into(), + ); + tracing::info!( + target: LOG_TARGET, + "Pruned {:?} receipts from block_number: {}", offchain_status, block, + ); + } + } + + fn maybe_prune( + &self, + storage: OffchainDb, + offchain_status: OffchainStatus, + current_block: u64, + ) { + let blocks_to_keep = { + if let Some(keep_blocks) = self.gc_policy.keep_blocks { + keep_blocks + } else { + return; + } + }; + + let kept_from = { + match offchain_status { + OffchainStatus::Finalized => self.load_finalized_kept_from(), + OffchainStatus::Untrusted => self.load_untrusted_kept_from(), + } + }; + + let last_block_to_keep = { + let last = current_block.saturating_sub(blocks_to_keep); + if last.saturating_sub(kept_from.block_number) <= self.gc_policy.gc_step { + last + } else { + kept_from + .block_number + .saturating_add(self.gc_policy.gc_step) + } + }; + + if kept_from.block_number >= last_block_to_keep { + return; + } + + self.prune_receipts( + storage, + offchain_status.clone(), + kept_from.block_number, + last_block_to_keep, + ); + + tracing::debug!( + target: LOG_TARGET, + "Pruning receipts completed, pruned from block: {}, to block: {}", + kept_from.block_number, + last_block_to_keep, + ); + + match offchain_status { + OffchainStatus::Finalized => { + self.persist_finalized_kept_from(&last_block_to_keep.into()); + } + OffchainStatus::Untrusted => { + self.persist_untrusted_kept_from(&last_block_to_keep.into()); + } + } + } + + /// Loads the information of the last finalized block that we have processed. + fn load_finalized_watermark(&self) -> FinalizedWatermark { + self.client + .get_aux(AUX_WM_KEY) + .ok() + .flatten() + .and_then(|v| FinalizedWatermark::decode(&mut &v[..]).ok()) + .unwrap_or_default() + } + + /// Stores the new finalized block number that was processed. + fn persist_finalized_watermark(&self, wm: &FinalizedWatermark) { + let _ = self + .client + .insert_aux(&[(AUX_WM_KEY, wm.encode().as_slice())], &[]); + } + + /// Backfills the receipts based on the newest finalized block notification + /// and the last block number that we have in the database. + /// + /// This allows us to catch up with the finalized blocks that we have missed. + fn backfill_finalized_gap(&self, target_finalized: u64) { + let mut wm = self.load_finalized_watermark(); + + let mut block_num = { + if let Some(keep_blocks) = self.gc_policy.keep_blocks { + target_finalized.saturating_sub(keep_blocks) + } else { + wm.up_to + } + }; + let finalized_from_block_n = block_num; + while block_num < target_finalized { + let hash = { + if let Ok(Some(hash)) = self.client.block_hash(block_num.unique_saturated_into()) { + hash + } else { + tracing::error!( + target: LOG_TARGET, + "Failed to backfill finalized gap for block: {}. from {} to block: {}", + block_num, finalized_from_block_n, target_finalized + ); + // In case we don't have access to the state of older blocks + // wipe any existing receipts for this block. + Self::do_prune_block( + &mut self.storage.clone(), + OffchainStatus::Untrusted, + block_num.unique_saturated_into(), + ); + block_num += 1; + // Ignore any possible errors because we can't be certain that we have access + // to the state of older blocks. + continue; + } + }; + let receipts = self + .client + .runtime_api() + .build_receipt_at(hash, block_num.unique_saturated_into()) + .unwrap_or_default(); + Self::store_finalized_data_offchain( + self.storage.clone(), + block_num.saturated_into(), + receipts, + ); + wm.up_to = block_num; + self.persist_finalized_watermark(&wm); + self.persist_finalized_kept_from(&finalized_from_block_n.into()); + block_num += 1; + } + tracing::info!( + target: LOG_TARGET, + "ReceiptService worker `backfill_finalized_gap`, finalized_from_block_n: {:?} to target_finalized: {:?}", + finalized_from_block_n, target_finalized + ); + } + + /// Stores all epico executed transactions for the current block in offchain + /// persistent storage under the `Untrusted` prefix. + /// + /// This data is considered "untrusted" because the block may still be + /// reorged out of the canonical chain. + pub fn store_newest_data_offchain( + mut storage: OffchainDb, + current_block: BlockNumberFor, + receipts: Vec>, + ) { + // To avoid potential data leaks in reorgs, we ensure that no data is stored for this block + // prior to writing new data. + Self::do_prune_block(&mut storage, OffchainStatus::Untrusted, current_block); + let mut block_transactions: Vec = Vec::new(); + + // Iterate over all transactions executed in the block. + for r in receipts { + let transaction_hash = r.transaction_hash; + block_transactions.push(transaction_hash); + + let storage_key = get_tx_offchain_key(OffchainStatus::Untrusted, transaction_hash); + // Persist the transaction receipt under the "Untrusted" offchain key. + storage.local_storage_set(StorageKind::PERSISTENT, &storage_key, &r.encode()); + tracing::debug!( + target: LOG_TARGET, + "Untrusted offchain storage key {:?}", + &storage_key, + ); + } + + if block_transactions.is_empty() { + return; + } + + // Store a mapping of transaction hashes for this block. + storage.local_storage_set( + StorageKind::PERSISTENT, + &pallet_epico::types::get_block_transaction_offchain_key( + OffchainStatus::Untrusted, + current_block.encode(), + ), + &block_transactions.encode(), + ); + } + + /// Promotes transactions from a sufficiently old block to "Finalized" status + /// in the offchain DB. + pub fn store_finalized_data_offchain( + mut storage: OffchainDb, + safe_finalized_block: BlockNumberFor, + receipts: Vec>, + ) { + Self::do_prune_block( + &mut storage, + OffchainStatus::Untrusted, + safe_finalized_block, + ); + + let mut block_transactions: Vec = Vec::new(); + + // Iterate over all transactions in the finalized block. + for r in receipts { + let transaction_hash = r.transaction_hash; + block_transactions.push(transaction_hash); + + let storage_key = get_tx_offchain_key(OffchainStatus::Finalized, transaction_hash); + + // Move receipts to "Finalized" namespace. + storage.local_storage_set(StorageKind::PERSISTENT, &storage_key, &r.encode()); + + tracing::debug!( + target: LOG_TARGET, + "Finalized offchain storage key {:?}", + &storage_key, + ); + } + + if block_transactions.is_empty() { + return; + } + + // Store finalized transaction hash list and remove the untrusted copy. + storage.local_storage_set( + StorageKind::PERSISTENT, + &pallet_epico::types::get_block_transaction_offchain_key( + OffchainStatus::Finalized, + safe_finalized_block.encode(), + ), + &block_transactions.encode(), + ); + } + + pub async fn run(self, spawner: impl SpawnNamed) + where + <<::Block as BlockT>::Header as HeaderT>::Number: + From<<::Header as HeaderT>::Number>, + { + // live import stream + let import_stream = self.client.every_import_notification_stream(); + + self.client + .runtime_api() + .register_extension(offchain::OffchainDbExt::new( + offchain::LimitedExternalities::new( + offchain::Capabilities::all(), + self.storage.clone(), + ), + )); + + let cloned_self = self.clone_spawned(); + + spawner.spawn( + "receipt-service-offchain-on-block", + Some("ReceiptService offchain-worker"), + Box::pin(async move { + futures::pin_mut!(import_stream); + + while let Some(imported_block) = import_stream.next().await { + let block_num = *imported_block.header.number(); + let mut runtime = cloned_self.client.runtime_api(); + + runtime.register_extension(offchain::OffchainDbExt::new( + offchain::LimitedExternalities::new( + offchain::Capabilities::all(), + cloned_self.storage.clone(), + ), + )); + + tracing::debug!( + target: LOG_TARGET, + "ReceiptService worker pre `store_offchain_at`, block_num: {:?}", + block_num + ); + + let receipts = &runtime + .build_receipt_at( + imported_block.header.hash(), + block_num.unique_saturated_into(), + ) + .unwrap_or_default(); + + Self::store_newest_data_offchain( + cloned_self.storage.clone(), + block_num.unique_saturated_into(), + receipts.clone(), + ); + + cloned_self.maybe_prune( + cloned_self.storage.clone(), + OffchainStatus::Untrusted, + block_num.unique_saturated_into(), + ); + + tracing::info!( + target: LOG_TARGET, + "ReceiptService worker result `store_offchain_at`, Block {:?}\n Recipts: {:?}", + block_num, + receipts, + ); + } + }), + ); + + let cloned_self = self.clone_spawned(); + let finalized_stream = self.client.finality_notification_stream(); + + spawner.spawn( + "receipt-service-offchain-on-block-finalized", + Some("FinalizedReceiptService offchain-worker"), + Box::pin(async move { + + futures::pin_mut!(finalized_stream); + let mut wm = cloned_self.load_finalized_watermark(); + while let Some(finalized_block) = finalized_stream.next().await { + let block_num = *finalized_block.header.number(); + let mut runtime = cloned_self.client.runtime_api(); + + runtime.register_extension(offchain::OffchainDbExt::new( + offchain::LimitedExternalities::new( + offchain::Capabilities::all(), + cloned_self.storage.clone(), + ), + )); + + // fill the gap strictly below the event, if any + if block_num > wm.up_to.saturating_add(1).unique_saturated_into() { + cloned_self.backfill_finalized_gap(block_num.unique_saturated_into()); + wm = cloned_self.load_finalized_watermark(); + } + + tracing::debug!( + target: LOG_TARGET, + "ReceiptService worker pre `store_finalized_data_offchain`, finalized_block: {:?}", + finalized_block.header.number() + ); + let receipts = runtime + .build_receipt_at( + finalized_block.header.hash(), + block_num.unique_saturated_into() + ) + .unwrap_or_default(); + + + Self::store_finalized_data_offchain( + cloned_self.storage.clone(), + block_num.unique_saturated_into(), + receipts.clone() + ); + + if block_num >= wm.up_to.unique_saturated_into() { + wm.up_to = block_num.saturated_into(); + cloned_self.persist_finalized_watermark(&wm); + } + + cloned_self.maybe_prune( + cloned_self.storage.clone(), + OffchainStatus::Finalized, + block_num.unique_saturated_into() + ); + + tracing::info!( + target: LOG_TARGET, + "ReceiptService worker result `store_finalized_data_offchain`, Block: {:?}\n Receipts: {:?}", + block_num, + receipts, + ); + } + })); + } + + fn clone_spawned(&self) -> Self { + Self { + client: self.client.clone(), + storage: self.storage.clone(), + gc_policy: self.gc_policy.clone(), + _phantom: Default::default(), + } + } +} diff --git a/rpc/src/eth.rs b/rpc/src/eth.rs index 56c6bf9..09f943c 100644 --- a/rpc/src/eth.rs +++ b/rpc/src/eth.rs @@ -557,7 +557,7 @@ where &get_tx_offchain_key(OffchainStatus::Finalized, transaction_hash), ); - let (raw_receipt, offchain_status) = if let Some(raw_receipt) = maybe_trusted_raw_receipt { + let (raw_receipt, _) = if let Some(raw_receipt) = maybe_trusted_raw_receipt { (raw_receipt, OffchainStatus::Finalized) } else { let maybe_untrusted_raw_receipt = self.offchain_db.clone().local_storage_get( @@ -573,24 +573,9 @@ where }; let transaction_receipt = - TransactionReceipt::::decode(&mut &raw_receipt[2..]) + TransactionReceipt::::decode(&mut &raw_receipt[..]) .map_err(eth_rpc_err)?; - if offchain_status == OffchainStatus::Untrusted { - let block_info = self.client.info(); - let safe_finality_depth = self - .client - .runtime_api() - .safe_finality_depth(block_info.best_hash) - .map_err(runtime_error_into_rpc_err)?; - - if (block_info.best_number - safe_finality_depth.into()) - > transaction_receipt.block_number.saturated_into() - { - return Ok(None); - } - }; - let mut receipt: Receipt = transaction_receipt.into(); if receipt.block_hash == H256::zero() { receipt.block_hash = self @@ -607,13 +592,6 @@ where &self, block_number: <::Header as sp_runtime::traits::Header>::Number, ) -> RpcResult> { - let block_info = self.client.info(); - let safe_finality_depth = self - .client - .runtime_api() - .safe_finality_depth(block_info.best_hash) - .map_err(runtime_error_into_rpc_err)?; - let raw_block_transactions = self .offchain_db .clone() @@ -625,17 +603,13 @@ where ), ) .or_else(|| { - if (block_info.best_number - safe_finality_depth.into()) <= block_number { - self.offchain_db.clone().local_storage_get( - StorageKind::PERSISTENT, - &get_block_transaction_offchain_key( - OffchainStatus::Untrusted, - block_number.encode(), - ), - ); - } - - None + self.offchain_db.clone().local_storage_get( + StorageKind::PERSISTENT, + &get_block_transaction_offchain_key( + OffchainStatus::Untrusted, + block_number.encode(), + ), + ) }); let block_transactions = match raw_block_transactions {