From ed8b3833df54df62b813c08a958b4850a192c68b Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Mon, 5 Feb 2024 16:13:21 -0300 Subject: [PATCH 01/36] eth: new --- Cargo.lock | 687 +++++++++++++++-------------------------------------- Cargo.toml | 9 +- src/eth.rs | 385 +++++++++++++++--------------- src/lib.rs | 1 - 4 files changed, 393 insertions(+), 689 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4c508b4..6f86d3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,19 +3,36 @@ version = 3 [[package]] -name = "aho-corasick" -version = "1.1.2" +name = "addr2line" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "memchr", + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "alloy-json-rpc" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#2d23d57d78844e04c9ea09cf9e5aea2dccc1c639" +dependencies = [ + "alloy-primitives", + "serde", + "serde_json", + "thiserror", ] [[package]] name = "alloy-primitives" -version = "0.5.4" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c234f92024707f224510ff82419b2be0e1d8e1fd911defcac5a085cd7f83898" +checksum = "f4b6fb2b432ff223d513db7f908937f63c252bee0af9b82bfd25b0a5dd1eb0d8" dependencies = [ "alloy-rlp", "bytes", @@ -24,6 +41,7 @@ dependencies = [ "derive_more", "hex-literal", "itoa", + "k256", "keccak-asm", "proptest", "rand", @@ -57,31 +75,30 @@ dependencies = [ [[package]] name = "alloy-rpc-types" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git?rev=3b1c310#3b1c3108ccd33c78abd7da8191e3744b4ae9a735" +source = "git+https://github.com/alloy-rs/alloy.git#6d457a507dffc773bc6af6401f8566def02a89d5" dependencies = [ "alloy-primitives", "alloy-rlp", "itertools 0.12.0", - "jsonrpsee-types", "serde", "serde_json", - "serde_with", "thiserror", ] [[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" +name = "alloy-transport" +version = "0.1.0" +source = "git+https://github.com/alloy-rs/alloy.git#2d23d57d78844e04c9ea09cf9e5aea2dccc1c639" dependencies = [ - "libc", + "alloy-json-rpc", + "base64", + "serde", + "serde_json", + "thiserror", + "tokio", + "tower", + "url", + "wasm-bindgen-futures", ] [[package]] @@ -238,6 +255,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base16ct" version = "0.2.0" @@ -256,15 +288,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "beef" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" -dependencies = [ - "serde", -] - [[package]] name = "bincode" version = "1.3.3" @@ -364,19 +387,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chrono" -version = "0.4.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "num-traits", - "serde", - "windows-targets 0.48.5", -] - [[package]] name = "const-hex" version = "1.10.0" @@ -402,12 +412,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - [[package]] name = "cpufeatures" version = "0.2.11" @@ -445,41 +449,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "darling" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.38", -] - -[[package]] -name = "darling_macro" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.38", -] - [[package]] name = "der" version = "0.7.8" @@ -490,16 +459,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", - "serde", -] - [[package]] name = "derivative" version = "2.2.0" @@ -600,81 +559,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "ethabi" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" -dependencies = [ - "ethereum-types", - "hex", - "once_cell", - "regex", - "serde", - "serde_json", - "sha3", - "thiserror", - "uint", -] - -[[package]] -name = "ethbloom" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" -dependencies = [ - "crunchy", - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "scale-info", - "tiny-keccak", -] - -[[package]] -name = "ethereum-types" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "primitive-types", - "scale-info", - "uint", -] - -[[package]] -name = "ethers-core" -version = "2.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f03e0bdc216eeb9e355b90cf610ef6c5bb8aca631f97b5ae9980ce34ea7878d" -dependencies = [ - "arrayvec", - "bytes", - "chrono", - "const-hex", - "elliptic-curve", - "ethabi", - "generic-array", - "k256", - "num_enum", - "open-fastrlp", - "rand", - "rlp", - "serde", - "serde_json", - "strum", - "tempfile", - "thiserror", - "tiny-keccak", - "unicode-xid", -] - [[package]] name = "fastrand" version = "2.0.1" @@ -735,6 +619,30 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -757,6 +665,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + [[package]] name = "group" version = "0.13.0" @@ -768,12 +682,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "hashbrown" version = "0.14.2" @@ -824,41 +732,12 @@ dependencies = [ "itoa", ] -[[package]] -name = "iana-time-zone" -version = "0.1.59" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[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 = "id-arena" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.4.0" @@ -878,24 +757,6 @@ dependencies = [ "parity-scale-codec", ] -[[package]] -name = "impl-rlp" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" -dependencies = [ - "rlp", -] - -[[package]] -name = "impl-serde" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" -dependencies = [ - "serde", -] - [[package]] name = "impl-trait-for-tuples" version = "0.2.2" @@ -907,17 +768,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - [[package]] name = "indexmap" version = "2.1.0" @@ -925,7 +775,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.2", + "hashbrown", "serde", ] @@ -962,20 +812,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "jsonrpsee-types" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be0be325642e850ed0bdff426674d2e66b2b7117c9be23a7caef68a2902b7d9" -dependencies = [ - "anyhow", - "beef", - "serde", - "serde_json", - "thiserror", - "tracing", -] - [[package]] name = "k256" version = "0.13.2" @@ -987,15 +823,7 @@ dependencies = [ "elliptic-curve", "once_cell", "sha2", -] - -[[package]] -name = "keccak" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" -dependencies = [ - "cpufeatures", + "signature", ] [[package]] @@ -1012,10 +840,12 @@ dependencies = [ name = "kinode_process_lib" version = "0.5.7" dependencies = [ + "alloy-json-rpc", + "alloy-primitives", "alloy-rpc-types", + "alloy-transport", "anyhow", "bincode", - "ethers-core", "http", "mime_guess", "rand", @@ -1084,6 +914,15 @@ dependencies = [ "unicase", ] +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + [[package]] name = "num-bigint" version = "0.4.4" @@ -1116,24 +955,12 @@ dependencies = [ ] [[package]] -name = "num_enum" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683751d591e6d81200c39fb0d1032608b77724f34114db54f571ff1317b337c0" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.1" +name = "object" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ - "proc-macro-crate 2.0.1", - "proc-macro2", - "quote", - "syn 2.0.38", + "memchr", ] [[package]] @@ -1142,31 +969,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "open-fastrlp" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" -dependencies = [ - "arrayvec", - "auto_impl", - "bytes", - "ethereum-types", - "open-fastrlp-derive", -] - -[[package]] -name = "open-fastrlp-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" -dependencies = [ - "bytes", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "parity-scale-codec" version = "3.6.5" @@ -1187,7 +989,7 @@ version = "3.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -1216,12 +1018,38 @@ dependencies = [ "ucd-trie", ] +[[package]] +name = "pin-project" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "pin-project-lite" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkcs8" version = "0.10.2" @@ -1232,12 +1060,6 @@ dependencies = [ "spki", ] -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1252,9 +1074,6 @@ checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ "fixed-hash", "impl-codec", - "impl-rlp", - "impl-serde", - "scale-info", "uint", ] @@ -1265,17 +1084,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit 0.19.15", -] - -[[package]] -name = "proc-macro-crate" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" -dependencies = [ - "toml_datetime", - "toml_edit 0.20.2", + "toml_edit", ] [[package]] @@ -1400,29 +1209,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "regex" -version = "1.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - [[package]] name = "regex-syntax" version = "0.8.2" @@ -1446,21 +1232,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" dependencies = [ "bytes", - "rlp-derive", "rustc-hex", ] -[[package]] -name = "rlp-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "ruint" version = "1.11.1" @@ -1491,6 +1265,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustc-hex" version = "2.1.0" @@ -1528,12 +1308,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustversion" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" - [[package]] name = "rusty-fork" version = "0.3.0" @@ -1552,30 +1326,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" -[[package]] -name = "scale-info" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7d66a1128282b7ef025a8ead62a4a9fcf017382ec53b8ffbf4d7bf77bd3c60" -dependencies = [ - "cfg-if", - "derive_more", - "parity-scale-codec", - "scale-info-derive", -] - -[[package]] -name = "scale-info-derive" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "sec1" version = "0.7.3" @@ -1645,35 +1395,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_with" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" -dependencies = [ - "base64", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.1.0", - "serde", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.38", -] - [[package]] name = "sha2" version = "0.10.8" @@ -1685,16 +1406,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.7", - "keccak", -] - [[package]] name = "sha3-asm" version = "0.1.0" @@ -1746,34 +1457,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.38", -] - [[package]] name = "subtle" version = "2.5.0" @@ -1841,35 +1524,6 @@ dependencies = [ "syn 2.0.38", ] -[[package]] -name = "time" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" -dependencies = [ - "deranged", - "itoa", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - -[[package]] -name = "time-macros" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" -dependencies = [ - "time-core", -] - [[package]] name = "tiny-keccak" version = "2.0.2" @@ -1894,6 +1548,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +dependencies = [ + "backtrace", + "pin-project-lite", +] + [[package]] name = "toml_datetime" version = "0.6.3" @@ -1906,28 +1570,45 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.1.0", + "indexmap", "toml_datetime", "winnow", ] [[package]] -name = "toml_edit" -version = "0.20.2" +name = "tower" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ - "indexmap 2.1.0", - "toml_datetime", - "winnow", + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tower-layer", + "tower-service", + "tracing", ] +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + [[package]] name = "tracing" version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ + "log", "pin-project-lite", "tracing-core", ] @@ -1937,6 +1618,9 @@ name = "tracing-core" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] [[package]] name = "typenum" @@ -2073,6 +1757,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.90" @@ -2118,7 +1814,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d835d67708f6374937c550ad8dd1d17c616ae009e3f00d7a0ac9f7825e78c36a" dependencies = [ "anyhow", - "indexmap 2.1.0", + "indexmap", "serde", "serde_derive", "serde_json", @@ -2133,17 +1829,18 @@ version = "0.118.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" dependencies = [ - "indexmap 2.1.0", + "indexmap", "semver 1.0.20", ] [[package]] -name = "windows-core" -version = "0.52.0" +name = "web-sys" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" dependencies = [ - "windows-targets 0.52.0", + "js-sys", + "wasm-bindgen", ] [[package]] @@ -2340,7 +2037,7 @@ checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2" dependencies = [ "anyhow", "bitflags 2.4.1", - "indexmap 2.1.0", + "indexmap", "log", "serde", "serde_derive", @@ -2359,7 +2056,7 @@ checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3" dependencies = [ "anyhow", "id-arena", - "indexmap 2.1.0", + "indexmap", "log", "semver 1.0.20", "serde", diff --git a/Cargo.toml b/Cargo.toml index 3949f17..f4309a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,14 +3,13 @@ name = "kinode_process_lib" version = "0.5.7" edition = "2021" -[features] -eth = [ "ethers-core", "alloy-rpc-types" ] - [dependencies] -alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy.git", rev = "3b1c310", optional = true } +alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy" } +alloy-primitives = "0.6.2" +alloy-transport = { git = "https://github.com/alloy-rs/alloy.git" } +alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy.git" } anyhow = "1.0" bincode = "1.3.3" -ethers-core = { version = "2.0.11", optional = true } http = "1.0.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/src/eth.rs b/src/eth.rs index 9b2426d..3a38fd5 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -1,8 +1,9 @@ -use crate::*; -use crate::{Address as KiAddress, Request as KiRequest}; -use alloy_rpc_types::Log; -pub use ethers_core::types::{ - Address as EthAddress, BlockNumber, Filter, FilterBlockOption, Topic, ValueOrArray, H256, U64, +use crate::{print_to_terminal, Message, Request as KiRequest}; +use alloy_primitives::{Address, BlockHash, Bytes, ChainId, TxHash, B256, U256, U64}; +use alloy_rpc_types::pubsub::{Params, SubscriptionKind, SubscriptionResult}; +use alloy_rpc_types::{ + Block, BlockId, BlockNumberOrTag, CallRequest, FeeHistory, Filter, Log, Transaction, + TransactionReceipt, }; use serde::{Deserialize, Serialize}; @@ -13,9 +14,32 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] pub enum EthAction { /// Subscribe to logs with a custom filter. ID is to be used to unsubscribe. - SubscribeLogs { sub_id: u64, filter: Filter }, + /// Logs come in as alloy_rpc_types::pubsub::SubscriptionResults + SubscribeLogs { + sub_id: u64, + kind: SubscriptionKind, + params: Params, + }, /// Kill a SubscribeLogs subscription of a given ID, to stop getting updates. UnsubscribeLogs(u64), + /// Raw Json_RPC request, + Request { + method: String, + params: serde_json::Value, + }, +} + +/// Potential EthResponse type. +/// Can encapsulate all methods in their own response type, +/// or return generic result which can be parsed later.. +#[derive(Debug, Serialize, Deserialize)] +pub enum EthResponse { + // another possible strat, just return RpcResult, + // then try deserializing on the process_lib side. + Ok, + Request(serde_json::Value), + Err(EthError), + Sub { id: u64, result: SubscriptionResult }, } /// The Response type which a process will get from requesting with an [`EthAction`] will be @@ -23,8 +47,6 @@ pub enum EthAction { /// and `serde_json::from_slice`. #[derive(Debug, Serialize, Deserialize)] pub enum EthError { - /// The subscription ID already existed - SubscriptionIdCollision, /// The ethers provider threw an error when trying to subscribe /// (contains ProviderError serialized to debug string) ProviderError(String), @@ -33,203 +55,190 @@ pub enum EthError { SubscriptionNotFound, } -/// The Request type which a process will get from using SubscribeLogs to subscribe -/// to a log. -/// -/// Will be serialized and deserialized using `serde_json::to_vec` and `serde_json::from_slice`. -#[derive(Debug, Serialize, Deserialize)] -pub enum EthSubEvent { - Log(Log), +fn send_request_and_parse_response( + action: EthAction, +) -> anyhow::Result { + let resp = KiRequest::new() + .target(("our", "eth", "distro", "sys")) + .body(serde_json::to_vec(&action)?) + .send_and_await_response(5)??; + + match resp { + Message::Response { body, .. } => { + let response = serde_json::from_slice::(&body)?; + match response { + EthResponse::Request(raw) => serde_json::from_value::(raw) + .map_err(|e| anyhow::anyhow!("failed to parse response: {}", e)), + _ => Err(anyhow::anyhow!("unexpected response: {:?}", response)), + } + } + _ => Err(anyhow::anyhow!("unexpected message type: {:?}", resp)), + } } -#[derive(Debug)] -pub struct SubscribeLogsRequest { - pub request: KiRequest, - pub id: u64, - pub filter: Filter, +pub fn get_block_number() -> anyhow::Result { + let action = EthAction::Request { + method: "eth_blockNumber".to_string(), + params: ().into(), + }; + + let res = send_request_and_parse_response::(action)?; + Ok(res.to::()) } -impl SubscribeLogsRequest { - /// Start building a new `SubscribeLogsRequest`. - pub fn new(id: u64) -> Self { - let request = KiRequest::new().target(KiAddress::new( - "our", - ProcessId::new(Some("eth"), "distro", "sys"), - )); +pub fn get_balance(address: Address, tag: Option) -> anyhow::Result { + let params = serde_json::to_value(( + address, + tag.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest)), + ))?; + let action = EthAction::Request { + method: "eth_getBalance".to_string(), + params, + }; + + send_request_and_parse_response::(action) +} - SubscribeLogsRequest { - request, - id, - filter: Filter::new(), - } - } +pub fn get_logs(filter: Filter) -> anyhow::Result> { + let action = EthAction::Request { + method: "eth_getLogs".to_string(), + params: serde_json::to_value((filter,))?, + }; - /// Attempt to send the request. - pub fn send(self) -> anyhow::Result<()> { - self.request - .body(serde_json::to_vec(&EthAction::SubscribeLogs { - sub_id: self.id, - filter: self.filter, - })?) - .send() - } + send_request_and_parse_response::>(action) +} - /// Sets the inner filter object - /// - /// *NOTE:* ranges are always inclusive - /// - /// # Examples - /// - /// Match only a specific block - /// - /// ```rust - /// # use process_lib::eth::SubscribeLogsRequest; - /// # fn main() { - /// let request = SubscribeLogsRequest::new().select(69u64); - /// # } - /// ``` - /// This is the same as `SubscribeLogsRequest::new().from_block(1337u64).to_block(1337u64)` - /// - /// Match the latest block only - /// - /// ```rust - /// # use process_lib::eth::{SubscribeLogsRequest, BlockNumber}; - /// # fn main() { - /// let request = SubscribeLogsRequest::new().select(BlockNumber::Latest); - /// # } - /// ``` - /// - /// Match a block by its hash - /// - /// ```rust - /// # use process_lib::eth::{SubscribeLogsRequest, H256}; - /// # fn main() { - /// let request = SubscribeLogsRequest::new().select(H256::zero()); - /// # } - /// ``` - /// This is the same as `at_block_hash` - /// - /// Match a range of blocks - /// - /// ```rust - /// # use process_lib::eth::{SubscribeLogsRequest, H256}; - /// # fn main() { - /// let request = SubscribeLogsRequest::new().select(0u64..100u64); - /// # } - /// ``` - /// - /// Match all blocks in range `(1337..BlockNumber::Latest)` - /// - /// ```rust - /// # use process_lib::eth::{SubscribeLogsRequest, H256}; - /// # fn main() { - /// let request = SubscribeLogsRequest::new().select(1337u64..); - /// # } - /// ``` - /// - /// Match all blocks in range `(BlockNumber::Earliest..1337)` - /// - /// ```rust - /// # use process_lib::eth::{SubscribeLogsRequest, H256}; - /// # fn main() { - /// let request = SubscribeLogsRequest::new().select(..1337u64); - /// # } - /// ``` - pub fn select(mut self, filter: impl Into) -> Self { - self.filter = self.filter.select(filter); - self - } +pub fn get_gas_price() -> anyhow::Result { + let action = EthAction::Request { + method: "eth_gasPrice".to_string(), + params: ().into(), + }; - /// Matches starting from a specific block - pub fn from_block>(mut self, block: T) -> Self { - self.filter = self.filter.from_block(block); - self - } + send_request_and_parse_response::(action) +} - /// Matches up until a specific block - pub fn to_block>(mut self, block: T) -> Self { - self.filter = self.filter.to_block(block); - self - } +pub fn get_chain_id() -> anyhow::Result { + let action = EthAction::Request { + method: "eth_chainId".to_string(), + params: ().into(), + }; - /// Matches a for a specific block hash - pub fn at_block_hash>(mut self, hash: T) -> Self { - self.filter = self.filter.at_block_hash(hash); - self - } + send_request_and_parse_response::(action) +} - /// Sets the SubscribeLogs filter object - /// - /// *NOTE:* ranges are always inclusive - /// - /// # Examples - /// - /// Match only a specific address `("0xAc4b3DacB91461209Ae9d41EC517c2B9Cb1B7DAF")` - /// - /// ```rust - /// # use process_lib::eth::{SubscribeLogsRequest, Address}; - /// # fn main() { - /// let filter = SubscribeLogsRequest::new().address("0xAc4b3DacB91461209Ae9d41EC517c2B9Cb1B7DAF".parse::().unwrap()); - /// # } - /// ``` - /// - /// Match all addresses in array `(vec!["0xAc4b3DacB91461209Ae9d41EC517c2B9Cb1B7DAF", - /// "0x8ad599c3A0ff1De082011EFDDc58f1908eb6e6D8"])` - /// - /// ```rust - /// # use process_lib::eth::{SubscribeLogsRequest, EthAddress, ValueOrArray}; - /// # fn main() { - /// let addresses = vec!["0xAc4b3DacB91461209Ae9d41EC517c2B9Cb1B7DAF".parse::().unwrap(),"0x8ad599c3A0ff1De082011EFDDc58f1908eb6e6D8".parse::().unwrap()]; - /// let filter = SubscribeLogsRequest::new().address(addresses); - /// # } - /// ``` - pub fn address>>(mut self, address: T) -> Self { - self.filter = self.filter.address(address); - self - } +pub fn get_transaction_count(address: Address, tag: Option) -> anyhow::Result { + let params = serde_json::to_value((address, tag.unwrap_or_default()))?; + let action = EthAction::Request { + method: "eth_getTransactionCount".to_string(), + params, + }; - /// Given the event signature in string form, it hashes it and adds it to the topics to monitor - pub fn event(mut self, event_name: &str) -> Self { - self.filter = self.filter.event(event_name); - self - } + send_request_and_parse_response::(action) +} - /// Hashes all event signatures and sets them as array to topic0 - pub fn events(mut self, events: impl IntoIterator>) -> Self { - self.filter = self.filter.events(events); - self - } +pub fn get_block_by_hash(hash: BlockHash, full_tx: bool) -> anyhow::Result> { + let params = serde_json::to_value((hash, full_tx))?; + let action = EthAction::Request { + method: "eth_getBlockByHash".to_string(), + params, + }; - /// Sets topic0 (the event name for non-anonymous events) - pub fn topic0>(mut self, topic: T) -> Self { - self.filter = self.filter.topic0(topic); - self - } + send_request_and_parse_response::>(action) +} - /// Sets the 1st indexed topic - pub fn topic1>(mut self, topic: T) -> Self { - self.filter = self.filter.topic1(topic); - self - } +pub fn get_block_by_number( + number: BlockNumberOrTag, + full_tx: bool, +) -> anyhow::Result> { + let params = serde_json::to_value((number, full_tx))?; + let action = EthAction::Request { + method: "eth_getBlockByNumber".to_string(), + params, + }; + + send_request_and_parse_response::>(action) +} - /// Sets the 2nd indexed topic - pub fn topic2>(mut self, topic: T) -> Self { - self.filter = self.filter.topic2(topic); - self - } +pub fn get_storage_at(address: Address, key: U256, tag: Option) -> anyhow::Result { + let params = serde_json::to_value((address, key, tag.unwrap_or_default()))?; + let action = EthAction::Request { + method: "eth_getStorageAt".to_string(), + params, + }; - /// Sets the 3rd indexed topic - pub fn topic3>(mut self, topic: T) -> Self { - self.filter = self.filter.topic3(topic); - self - } + send_request_and_parse_response::(action) +} - pub fn is_paginatable(&self) -> bool { - self.filter.is_paginatable() - } +pub fn get_code_at(address: Address, tag: BlockId) -> anyhow::Result { + let params = serde_json::to_value((address, tag))?; + let action = EthAction::Request { + method: "eth_getCode".to_string(), + params, + }; - /// Returns the numeric value of the `toBlock` field - pub fn get_to_block(&self) -> Option { - self.filter.get_to_block() - } + send_request_and_parse_response::(action) +} + +pub fn get_transaction_by_hash(hash: TxHash) -> anyhow::Result> { + let params = serde_json::to_value((hash,))?; + let action = EthAction::Request { + method: "eth_getTransactionByHash".to_string(), + params, + }; + + send_request_and_parse_response::>(action) +} + +pub fn get_transaction_receipt(hash: TxHash) -> anyhow::Result> { + let params = serde_json::to_value((hash,))?; + let action = EthAction::Request { + method: "eth_getTransactionReceipt".to_string(), + params, + }; + + send_request_and_parse_response::>(action) +} + +pub fn estimate_gas(tx: CallRequest, block: Option) -> anyhow::Result { + let params = serde_json::to_value((tx, block.unwrap_or_default()))?; + let action = EthAction::Request { + method: "eth_estimateGas".to_string(), + params, + }; + + send_request_and_parse_response::(action) +} + +// note will and should return empty I think... +pub fn get_accounts() -> anyhow::Result> { + let action = EthAction::Request { + method: "eth_accounts".to_string(), + params: serde_json::Value::Array(vec![]), + }; + + send_request_and_parse_response::>(action) +} + +pub fn get_fee_history( + block_count: U256, + last_block: BlockNumberOrTag, + reward_percentiles: Vec, +) -> anyhow::Result { + let params = serde_json::to_value((block_count, last_block, reward_percentiles))?; + let action = EthAction::Request { + method: "eth_feeHistory".to_string(), + params, + }; + + send_request_and_parse_response::(action) +} + +pub fn call(tx: CallRequest, block: Option) -> anyhow::Result { + let params = serde_json::to_value((tx, block.unwrap_or_default()))?; + let action = EthAction::Request { + method: "eth_call".to_string(), + params, + }; + + send_request_and_parse_response::(action) } diff --git a/src/lib.rs b/src/lib.rs index b6afa3a..c2ad41c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,7 +23,6 @@ wit_bindgen::generate!({ }); /// Interact with the eth provider module. -#[cfg(feature = "eth")] pub mod eth; /// Interact with the HTTP server and client modules. /// Contains types from the `http` crate to use as well. From 032bd437a6765a2735a3e93b96f1e26e91ce8af0 Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Mon, 5 Feb 2024 18:02:41 -0300 Subject: [PATCH 02/36] cargo update, fix alloy-core deps --- Cargo.lock | 363 ++++++++++++++++++++--------------------------------- 1 file changed, 138 insertions(+), 225 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f86d3a..e956e33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,7 +20,7 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "alloy-json-rpc" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#2d23d57d78844e04c9ea09cf9e5aea2dccc1c639" +source = "git+https://github.com/alloy-rs/alloy.git#32618e9243a761858a0843e7e55575e48fdbf500" dependencies = [ "alloy-primitives", "serde", @@ -69,17 +69,17 @@ checksum = "1a047897373be4bbb0224c1afdabca92648dc57a9c9ef6e7b0be3aff7a859c83" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", ] [[package]] name = "alloy-rpc-types" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#6d457a507dffc773bc6af6401f8566def02a89d5" +source = "git+https://github.com/alloy-rs/alloy.git#32618e9243a761858a0843e7e55575e48fdbf500" dependencies = [ "alloy-primitives", "alloy-rlp", - "itertools 0.12.0", + "itertools 0.12.1", "serde", "serde_json", "thiserror", @@ -88,7 +88,7 @@ dependencies = [ [[package]] name = "alloy-transport" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#2d23d57d78844e04c9ea09cf9e5aea2dccc1c639" +source = "git+https://github.com/alloy-rs/alloy.git#32618e9243a761858a0843e7e55575e48fdbf500" dependencies = [ "alloy-json-rpc", "base64", @@ -103,9 +103,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "ark-ff" @@ -239,14 +239,13 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "auto_impl" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +checksum = "823b8bb275161044e2ac7a25879cb3e2480cb403e3943022c7c769c599b756aa" dependencies = [ - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -314,15 +313,9 @@ checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "bitvec" @@ -414,9 +407,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -556,7 +549,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -606,9 +599,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -656,9 +649,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", @@ -684,9 +677,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "heck" @@ -740,9 +733,9 @@ checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -770,9 +763,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" dependencies = [ "equivalent", "hashbrown", @@ -790,18 +783,18 @@ dependencies = [ [[package]] name = "itertools" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" @@ -814,9 +807,9 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f01b677d82ef7a676aa37e099defd83a28e15687112cafdd112d60236b6115b" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" dependencies = [ "cfg-if", "ecdsa", @@ -870,9 +863,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libm" @@ -882,9 +875,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "log" @@ -894,9 +887,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "mime" @@ -916,9 +909,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] @@ -971,9 +964,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "parity-scale-codec" -version = "3.6.5" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" dependencies = [ "arrayvec", "bitvec", @@ -985,9 +978,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.5" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1003,15 +996,15 @@ checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" dependencies = [ "memchr", "thiserror", @@ -1035,7 +1028,7 @@ checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", ] [[package]] @@ -1079,43 +1072,19 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" dependencies = [ - "once_cell", + "toml_datetime", "toml_edit", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -1128,7 +1097,7 @@ checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.4.1", + "bitflags", "lazy_static", "num-traits", "rand", @@ -1148,9 +1117,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1200,15 +1169,6 @@ dependencies = [ "rand_core", ] -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "regex-syntax" version = "0.8.2" @@ -1292,20 +1252,20 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.20", + "semver 1.0.21", ] [[package]] name = "rustix" -version = "0.38.28" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ - "bitflags 2.4.1", + "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -1322,9 +1282,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "sec1" @@ -1351,9 +1311,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" [[package]] name = "semver-parser" @@ -1366,29 +1326,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.190" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.190" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", ] [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ "itoa", "ryu", @@ -1428,15 +1388,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "spdx" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b19b32ed6d899ab23174302ff105c1577e45a06b08d4fe0a9dd13ce804bbbf71" +checksum = "62bde1398b09b9f93fc2fc9b9da86e362693e999d3a54a8ac47a99a5a73f638b" dependencies = [ "smallvec", ] @@ -1476,9 +1436,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -1493,35 +1453,34 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.8.1" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", "rustix", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", ] [[package]] @@ -1566,9 +1525,9 @@ checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" dependencies = [ "indexmap", "toml_datetime", @@ -1663,9 +1622,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -1696,9 +1655,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -1753,7 +1712,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", "wasm-bindgen-shared", ] @@ -1787,7 +1746,7 @@ checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1807,11 +1766,20 @@ dependencies = [ "leb128", ] +[[package]] +name = "wasm-encoder" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e09bca7d6388637d27fb5edbeab11f56bfabcef8743c55ae34370e1e5030a071" +dependencies = [ + "leb128", +] + [[package]] name = "wasm-metadata" -version = "0.10.14" +version = "0.10.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d835d67708f6374937c550ad8dd1d17c616ae009e3f00d7a0ac9f7825e78c36a" +checksum = "c853d3809fc9fccf3bc0ad63f4f51d8eefad0bacf88f957aa991c1d9b88b016e" dependencies = [ "anyhow", "indexmap", @@ -1819,8 +1787,8 @@ dependencies = [ "serde_derive", "serde_json", "spdx", - "wasm-encoder", - "wasmparser", + "wasm-encoder 0.41.0", + "wasmparser 0.121.0", ] [[package]] @@ -1830,26 +1798,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" dependencies = [ "indexmap", - "semver 1.0.20", + "semver 1.0.21", ] [[package]] -name = "web-sys" -version = "0.3.67" +name = "wasmparser" +version = "0.121.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "953cf6a7606ab31382cb1caa5ae403e77ba70c7f8e12eeda167e7040d42bfda8" dependencies = [ - "js-sys", - "wasm-bindgen", + "bitflags", + "indexmap", + "semver 1.0.21", ] [[package]] -name = "windows-sys" -version = "0.48.0" +name = "web-sys" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" dependencies = [ - "windows-targets 0.48.5", + "js-sys", + "wasm-bindgen", ] [[package]] @@ -1858,22 +1828,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -1882,93 +1837,51 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.0" @@ -1977,9 +1890,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.31" +version = "0.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a4882e6b134d6c28953a387571f1acdd3496830d5e36c5e3a1075580ea641c" +checksum = "a7cad8365489051ae9f054164e459304af2e7e9bb407c958076c8bf4aef52da5" dependencies = [ "memchr", ] @@ -1989,7 +1902,7 @@ name = "wit-bindgen" version = "0.16.0" source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ - "bitflags 2.4.1", + "bitflags", "wit-bindgen-rust-macro", ] @@ -2023,7 +1936,7 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", "wit-bindgen-core", "wit-bindgen-rust", "wit-component", @@ -2036,29 +1949,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2" dependencies = [ "anyhow", - "bitflags 2.4.1", + "bitflags", "indexmap", "log", "serde", "serde_derive", "serde_json", - "wasm-encoder", + "wasm-encoder 0.38.1", "wasm-metadata", - "wasmparser", + "wasmparser 0.118.1", "wit-parser", ] [[package]] name = "wit-parser" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3" +checksum = "df4913a2219096373fd6512adead1fb77ecdaa59d7fc517972a7d30b12f625be" dependencies = [ "anyhow", "id-arena", "indexmap", "log", - "semver 1.0.20", + "semver 1.0.21", "serde", "serde_derive", "serde_json", @@ -2091,5 +2004,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", ] From baad9cc103ec4d4f0cfdb3a82673b2e15354e203 Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Tue, 6 Feb 2024 18:23:00 -0300 Subject: [PATCH 03/36] eth: add send_raw_transaction --- src/eth.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/eth.rs b/src/eth.rs index 3a38fd5..c529169 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -1,5 +1,5 @@ -use crate::{print_to_terminal, Message, Request as KiRequest}; -use alloy_primitives::{Address, BlockHash, Bytes, ChainId, TxHash, B256, U256, U64}; +use crate::{Message, Request as KiRequest}; +use alloy_primitives::{Address, BlockHash, Bytes, TxHash, U256, U64}; use alloy_rpc_types::pubsub::{Params, SubscriptionKind, SubscriptionResult}; use alloy_rpc_types::{ Block, BlockId, BlockNumberOrTag, CallRequest, FeeHistory, Filter, Log, Transaction, @@ -242,3 +242,12 @@ pub fn call(tx: CallRequest, block: Option) -> anyhow::Result { send_request_and_parse_response::(action) } + +pub fn send_raw_transaction(tx: Bytes) -> anyhow::Result { + let action = EthAction::Request { + method: "eth_sendRawTransaction".to_string(), + params: serde_json::to_value((tx,))?, + }; + + send_request_and_parse_response::(action) +} From 0821c4a9cf9735e96007490bcf292f758bc836b4 Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Fri, 9 Feb 2024 16:10:34 -0300 Subject: [PATCH 04/36] eth: update alloy and set hash --- Cargo.lock | 6 +++--- Cargo.toml | 6 +++--- src/eth.rs | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e956e33..ccf56b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,7 +20,7 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "alloy-json-rpc" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#32618e9243a761858a0843e7e55575e48fdbf500" +source = "git+https://github.com/alloy-rs/alloy.git?rev=098ad56#098ad5657d55bbc5fe9469ede2a9ca79def738f2" dependencies = [ "alloy-primitives", "serde", @@ -75,7 +75,7 @@ dependencies = [ [[package]] name = "alloy-rpc-types" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#32618e9243a761858a0843e7e55575e48fdbf500" +source = "git+https://github.com/alloy-rs/alloy.git?rev=098ad56#098ad5657d55bbc5fe9469ede2a9ca79def738f2" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -88,7 +88,7 @@ dependencies = [ [[package]] name = "alloy-transport" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git#32618e9243a761858a0843e7e55575e48fdbf500" +source = "git+https://github.com/alloy-rs/alloy.git?rev=098ad56#098ad5657d55bbc5fe9469ede2a9ca79def738f2" dependencies = [ "alloy-json-rpc", "base64", diff --git a/Cargo.toml b/Cargo.toml index f4309a0..3df626e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,10 +4,10 @@ version = "0.5.7" edition = "2021" [dependencies] -alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy" } +alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "098ad56" } alloy-primitives = "0.6.2" -alloy-transport = { git = "https://github.com/alloy-rs/alloy.git" } -alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy.git" } +alloy-transport = { git = "https://github.com/alloy-rs/alloy.git", rev = "098ad56" } +alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy.git", rev = "098ad56" } anyhow = "1.0" bincode = "1.3.3" http = "1.0.0" diff --git a/src/eth.rs b/src/eth.rs index c529169..5a4d8d2 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -2,8 +2,8 @@ use crate::{Message, Request as KiRequest}; use alloy_primitives::{Address, BlockHash, Bytes, TxHash, U256, U64}; use alloy_rpc_types::pubsub::{Params, SubscriptionKind, SubscriptionResult}; use alloy_rpc_types::{ - Block, BlockId, BlockNumberOrTag, CallRequest, FeeHistory, Filter, Log, Transaction, - TransactionReceipt, + request::TransactionRequest, Block, BlockId, BlockNumberOrTag, FeeHistory, Filter, Log, + Transaction, TransactionReceipt, }; use serde::{Deserialize, Serialize}; @@ -199,7 +199,7 @@ pub fn get_transaction_receipt(hash: TxHash) -> anyhow::Result>(action) } -pub fn estimate_gas(tx: CallRequest, block: Option) -> anyhow::Result { +pub fn estimate_gas(tx: TransactionRequest, block: Option) -> anyhow::Result { let params = serde_json::to_value((tx, block.unwrap_or_default()))?; let action = EthAction::Request { method: "eth_estimateGas".to_string(), @@ -233,7 +233,7 @@ pub fn get_fee_history( send_request_and_parse_response::(action) } -pub fn call(tx: CallRequest, block: Option) -> anyhow::Result { +pub fn call(tx: TransactionRequest, block: Option) -> anyhow::Result { let params = serde_json::to_value((tx, block.unwrap_or_default()))?; let action = EthAction::Request { method: "eth_call".to_string(), From 1e14a03e3e274f0bc7f16a08d81c7583589b12be Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Mon, 12 Feb 2024 15:51:52 -0300 Subject: [PATCH 05/36] eth: better types and errors --- src/eth.rs | 63 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/src/eth.rs b/src/eth.rs index 5a4d8d2..4bf3844 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -1,14 +1,23 @@ use crate::{Message, Request as KiRequest}; -use alloy_primitives::{Address, BlockHash, Bytes, TxHash, U256, U64}; -use alloy_rpc_types::pubsub::{Params, SubscriptionKind, SubscriptionResult}; -use alloy_rpc_types::{ - request::TransactionRequest, Block, BlockId, BlockNumberOrTag, FeeHistory, Filter, Log, - Transaction, TransactionReceipt, +pub use alloy_primitives::{Address, BlockHash, Bytes, TxHash, U128, U256, U64, U8}; +pub use alloy_rpc_types::pubsub::{Params, SubscriptionKind, SubscriptionResult}; +pub use alloy_rpc_types::{ + request::{TransactionInput, TransactionRequest}, + Block, BlockId, BlockNumberOrTag, FeeHistory, Filter, Log, Transaction, TransactionReceipt, }; use serde::{Deserialize, Serialize}; -/// The Request type that can be made to eth:distro:sys. Currently primitive, this -/// enum will expand to support more actions in the future. +/// The Message type that can be made to eth:distro:sys. The id is used to match the response, +/// if you're not doing send_and_await. +/// +/// Will be serialized and deserialized using `serde_json::to_vec` and `serde_json::from_slice`. +#[derive(Debug, Serialize, Deserialize)] +pub struct EthMessage { + pub id: u64, + pub action: EthAction, +} + +/// The Action and Request type that can be made to eth:distro:sys. /// /// Will be serialized and deserialized using `serde_json::to_vec` and `serde_json::from_slice`. #[derive(Debug, Serialize, Deserialize)] @@ -16,58 +25,64 @@ pub enum EthAction { /// Subscribe to logs with a custom filter. ID is to be used to unsubscribe. /// Logs come in as alloy_rpc_types::pubsub::SubscriptionResults SubscribeLogs { - sub_id: u64, kind: SubscriptionKind, params: Params, }, /// Kill a SubscribeLogs subscription of a given ID, to stop getting updates. - UnsubscribeLogs(u64), - /// Raw Json_RPC request, + UnsubscribeLogs, + /// Raw request. Used by kinode_process_lib. Request { method: String, params: serde_json::Value, }, + /// Incoming subscription update. + Sub { result: SubscriptionResult }, } -/// Potential EthResponse type. -/// Can encapsulate all methods in their own response type, -/// or return generic result which can be parsed later.. #[derive(Debug, Serialize, Deserialize)] pub enum EthResponse { - // another possible strat, just return RpcResult, - // then try deserializing on the process_lib side. Ok, - Request(serde_json::Value), + Response { value: serde_json::Value }, Err(EthError), - Sub { id: u64, result: SubscriptionResult }, } -/// The Response type which a process will get from requesting with an [`EthAction`] will be +/// The Response type which a process will get from requesting with an [`EthMessage`] will be /// of the form `Result<(), EthError>`, serialized and deserialized using `serde_json::to_vec` /// and `serde_json::from_slice`. #[derive(Debug, Serialize, Deserialize)] pub enum EthError { - /// The ethers provider threw an error when trying to subscribe - /// (contains ProviderError serialized to debug string) - ProviderError(String), - SubscriptionClosed, + /// Underlying transport error + TransportError(String), + /// Subscription closed + SubscriptionClosed(u64), /// The subscription ID was not found, so we couldn't unsubscribe. SubscriptionNotFound, + /// Invalid method + InvalidMethod(String), + /// Permission denied + PermissionDenied(String), + /// Internal RPC error + RpcError(String), } fn send_request_and_parse_response( action: EthAction, ) -> anyhow::Result { + let msg = EthMessage { + id: rand::random(), + action, + }; + let resp = KiRequest::new() .target(("our", "eth", "distro", "sys")) - .body(serde_json::to_vec(&action)?) + .body(serde_json::to_vec(&msg)?) .send_and_await_response(5)??; match resp { Message::Response { body, .. } => { let response = serde_json::from_slice::(&body)?; match response { - EthResponse::Request(raw) => serde_json::from_value::(raw) + EthResponse::Response { value } => serde_json::from_value::(value) .map_err(|e| anyhow::anyhow!("failed to parse response: {}", e)), _ => Err(anyhow::anyhow!("unexpected response: {:?}", response)), } From acd102db79533893c3bf0575c1d1f9c30cb254c4 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Mon, 12 Feb 2024 16:44:48 -0500 Subject: [PATCH 06/36] ERC721Metadata added to kernel_types --- src/kernel_types.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/kernel_types.rs b/src/kernel_types.rs index 1d73be8..b3a6212 100644 --- a/src/kernel_types.rs +++ b/src/kernel_types.rs @@ -1,7 +1,7 @@ use crate::kinode::process::standard as wit; use crate::{Address, ProcessId}; use serde::{Deserialize, Serialize}; -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; // // process-facing kernel types, used for process @@ -201,14 +201,24 @@ impl StateError { pub type PackageVersion = (u32, u32, u32); /// the type that gets deserialized from `metadata.json` in a package -#[derive(Debug, Serialize, Deserialize)] -pub struct PackageMetadata { - pub package: String, +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Erc721Metadata { + pub name: Option, + pub description: Option, + pub image: Option, + pub external_url: Option, + pub animation_url: Option, + pub properties: Option, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Erc721Properties { + pub package_name: String, pub publisher: String, - pub version: PackageVersion, + pub current_version: String, + pub mirrors: Vec, + pub code_hashes: HashMap, pub wit_version: Option<(u32, u32, u32)>, - pub description: Option, - pub website: Option, } /// the type that gets deserialized from each entry in the array in `manifest.json` From 12bf9eefeb9237db5e5165647fa91b437b05e169 Mon Sep 17 00:00:00 2001 From: hosted-fornet Date: Mon, 12 Feb 2024 20:39:31 -0800 Subject: [PATCH 07/36] bump wit-bindgen --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index d72bafb..3545c3b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,4 +22,4 @@ rand = "0.8" thiserror = "1.0" url = "2.4.1" mime_guess = "2.0" -wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "efcc759" } +wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "21a46c7" } From 1d6099573b08e775a5166875cb4d79b70daf042a Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Tue, 13 Feb 2024 11:56:00 -0300 Subject: [PATCH 08/36] eth: more helpers --- src/eth.rs | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/src/eth.rs b/src/eth.rs index 4bf3844..0399036 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -1,9 +1,10 @@ use crate::{Message, Request as KiRequest}; -pub use alloy_primitives::{Address, BlockHash, Bytes, TxHash, U128, U256, U64, U8}; +pub use alloy_primitives::{Address, BlockHash, BlockNumber, Bytes, TxHash, U128, U256, U64, U8}; pub use alloy_rpc_types::pubsub::{Params, SubscriptionKind, SubscriptionResult}; pub use alloy_rpc_types::{ request::{TransactionInput, TransactionRequest}, - Block, BlockId, BlockNumberOrTag, FeeHistory, Filter, Log, Transaction, TransactionReceipt, + Block, BlockId, BlockNumberOrTag, FeeHistory, Filter, FilterBlockOption, Log, Transaction, + TransactionReceipt, }; use serde::{Deserialize, Serialize}; @@ -114,7 +115,7 @@ pub fn get_balance(address: Address, tag: Option) -> anyhow::Result(action) } -pub fn get_logs(filter: Filter) -> anyhow::Result> { +pub fn get_logs(filter: &Filter) -> anyhow::Result> { let action = EthAction::Request { method: "eth_getLogs".to_string(), params: serde_json::to_value((filter,))?, @@ -266,3 +267,43 @@ pub fn send_raw_transaction(tx: Bytes) -> anyhow::Result { send_request_and_parse_response::(action) } + +/// sends requests eth_getLogs and eth_subscribe, +/// doesn't await, handle them as incoming EthMessage::Sub, and EthResponse::Response +pub fn getlogs_and_subscribe(sub_id: u64, filter: Filter) -> anyhow::Result<()> { + let action = EthAction::SubscribeLogs { + kind: SubscriptionKind::Logs, + params: Params::Logs(Box::new(filter)), + }; + let msg = EthMessage { id: sub_id, action }; + + KiRequest::new() + .target(("our", "eth", "distro", "sys")) + .body(serde_json::to_vec(&msg)?) + .send() +} + +/// sends a request to eth_subscribe, doesn't wait for ok.. +pub fn subscribe(sub_id: u64, filter: Filter) -> anyhow::Result<()> { + let action = EthAction::SubscribeLogs { + kind: SubscriptionKind::Logs, + params: Params::Logs(Box::new(filter)), + }; + + let msg = EthMessage { id: sub_id, action }; + + KiRequest::new() + .target(("our", "eth", "distro", "sys")) + .body(serde_json::to_vec(&msg)?) + .send() +} + +pub fn unsubscribe(sub_id: u64) -> anyhow::Result<()> { + let action = EthAction::UnsubscribeLogs; + let msg = EthMessage { id: sub_id, action }; + + KiRequest::new() + .target(("our", "eth", "distro", "sys")) + .body(serde_json::to_vec(&msg)?) + .send() +} From 923188194cf2007e7d7ea08abbeda0a78fb04833 Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Tue, 13 Feb 2024 15:10:29 -0300 Subject: [PATCH 09/36] eth: break out subevent type --- src/eth.rs | 49 ++++++++++++++++++------------------------------- 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/src/eth.rs b/src/eth.rs index 0399036..83532f2 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -8,38 +8,35 @@ pub use alloy_rpc_types::{ }; use serde::{Deserialize, Serialize}; -/// The Message type that can be made to eth:distro:sys. The id is used to match the response, -/// if you're not doing send_and_await. -/// -/// Will be serialized and deserialized using `serde_json::to_vec` and `serde_json::from_slice`. -#[derive(Debug, Serialize, Deserialize)] -pub struct EthMessage { - pub id: u64, - pub action: EthAction, -} - /// The Action and Request type that can be made to eth:distro:sys. -/// /// Will be serialized and deserialized using `serde_json::to_vec` and `serde_json::from_slice`. #[derive(Debug, Serialize, Deserialize)] pub enum EthAction { /// Subscribe to logs with a custom filter. ID is to be used to unsubscribe. /// Logs come in as alloy_rpc_types::pubsub::SubscriptionResults SubscribeLogs { + sub_id: u64, kind: SubscriptionKind, params: Params, }, /// Kill a SubscribeLogs subscription of a given ID, to stop getting updates. - UnsubscribeLogs, + UnsubscribeLogs(u64), /// Raw request. Used by kinode_process_lib. Request { method: String, params: serde_json::Value, }, - /// Incoming subscription update. - Sub { result: SubscriptionResult }, +} +/// Incoming subscription update. +#[derive(Debug, Serialize, Deserialize)] +pub struct EthSub { + pub id: u64, + pub result: SubscriptionResult, } +/// The Response type which a process will get from requesting with an [`EthAction`] will be +/// of the form `Result<(), EthError>`, serialized and deserialized using `serde_json::to_vec` +/// and `serde_json::from_slice`. #[derive(Debug, Serialize, Deserialize)] pub enum EthResponse { Ok, @@ -47,9 +44,6 @@ pub enum EthResponse { Err(EthError), } -/// The Response type which a process will get from requesting with an [`EthMessage`] will be -/// of the form `Result<(), EthError>`, serialized and deserialized using `serde_json::to_vec` -/// and `serde_json::from_slice`. #[derive(Debug, Serialize, Deserialize)] pub enum EthError { /// Underlying transport error @@ -69,14 +63,9 @@ pub enum EthError { fn send_request_and_parse_response( action: EthAction, ) -> anyhow::Result { - let msg = EthMessage { - id: rand::random(), - action, - }; - let resp = KiRequest::new() .target(("our", "eth", "distro", "sys")) - .body(serde_json::to_vec(&msg)?) + .body(serde_json::to_vec(&action)?) .send_and_await_response(5)??; match resp { @@ -272,38 +261,36 @@ pub fn send_raw_transaction(tx: Bytes) -> anyhow::Result { /// doesn't await, handle them as incoming EthMessage::Sub, and EthResponse::Response pub fn getlogs_and_subscribe(sub_id: u64, filter: Filter) -> anyhow::Result<()> { let action = EthAction::SubscribeLogs { + sub_id, kind: SubscriptionKind::Logs, params: Params::Logs(Box::new(filter)), }; - let msg = EthMessage { id: sub_id, action }; KiRequest::new() .target(("our", "eth", "distro", "sys")) - .body(serde_json::to_vec(&msg)?) + .body(serde_json::to_vec(&action)?) .send() } /// sends a request to eth_subscribe, doesn't wait for ok.. pub fn subscribe(sub_id: u64, filter: Filter) -> anyhow::Result<()> { let action = EthAction::SubscribeLogs { + sub_id, kind: SubscriptionKind::Logs, params: Params::Logs(Box::new(filter)), }; - let msg = EthMessage { id: sub_id, action }; - KiRequest::new() .target(("our", "eth", "distro", "sys")) - .body(serde_json::to_vec(&msg)?) + .body(serde_json::to_vec(&action)?) .send() } pub fn unsubscribe(sub_id: u64) -> anyhow::Result<()> { - let action = EthAction::UnsubscribeLogs; - let msg = EthMessage { id: sub_id, action }; + let action = EthAction::UnsubscribeLogs(sub_id); KiRequest::new() .target(("our", "eth", "distro", "sys")) - .body(serde_json::to_vec(&msg)?) + .body(serde_json::to_vec(&action)?) .send() } From 7f0c999f2645191ba7f83d164ba0103f12d4cf57 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Tue, 13 Feb 2024 14:56:26 -0500 Subject: [PATCH 10/36] Properties not optional --- src/kernel_types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel_types.rs b/src/kernel_types.rs index b3a6212..75aea58 100644 --- a/src/kernel_types.rs +++ b/src/kernel_types.rs @@ -208,7 +208,7 @@ pub struct Erc721Metadata { pub image: Option, pub external_url: Option, pub animation_url: Option, - pub properties: Option, + pub properties: Erc721Properties, } #[derive(Clone, Debug, Serialize, Deserialize)] From f6478996182d734fb320d35fa43357917aa4ee5e Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Tue, 13 Feb 2024 15:39:25 -0500 Subject: [PATCH 11/36] properties udpated --- src/kernel_types.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/kernel_types.rs b/src/kernel_types.rs index 75aea58..be2928e 100644 --- a/src/kernel_types.rs +++ b/src/kernel_types.rs @@ -218,6 +218,8 @@ pub struct Erc721Properties { pub current_version: String, pub mirrors: Vec, pub code_hashes: HashMap, + pub license: Option, + pub screenshots: Option>, pub wit_version: Option<(u32, u32, u32)>, } From 60514386f9a19fb3609948440fa65fae82a74c3a Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Tue, 13 Feb 2024 16:28:31 -0500 Subject: [PATCH 12/36] 0.6.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 56253cd..eac4aab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1010,7 +1010,7 @@ dependencies = [ [[package]] name = "kinode_process_lib" -version = "0.6.0" +version = "0.6.1" dependencies = [ "alloy-rpc-types", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index d72bafb..9221901 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kinode_process_lib" description = "A library for writing Kinode processes in Rust." -version = "0.6.0" +version = "0.6.1" edition = "2021" license-file = "LICENSE" homepage = "https://kinode.org" From e45e91602f5b5033be44832c064b59f9b320685b Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Tue, 13 Feb 2024 16:38:59 -0500 Subject: [PATCH 13/36] 0.6.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eac4aab..56253cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1010,7 +1010,7 @@ dependencies = [ [[package]] name = "kinode_process_lib" -version = "0.6.1" +version = "0.6.0" dependencies = [ "alloy-rpc-types", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index 9221901..d72bafb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kinode_process_lib" description = "A library for writing Kinode processes in Rust." -version = "0.6.1" +version = "0.6.0" edition = "2021" license-file = "LICENSE" homepage = "https://kinode.org" From 34cf6bda982ce2b93d8213f121fd479982f058e6 Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Wed, 14 Feb 2024 12:25:40 -0300 Subject: [PATCH 14/36] eth: add docstrings --- src/eth.rs | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 150 insertions(+), 7 deletions(-) diff --git a/src/eth.rs b/src/eth.rs index 83532f2..ead4731 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -60,7 +60,14 @@ pub enum EthError { RpcError(String), } -fn send_request_and_parse_response( +/// Sends a request based on the specified `EthAction` and parses the response. +/// +/// This function constructs a request targeting the Ethereum distribution system, serializes the provided `EthAction`, +/// and sends it. It awaits a response with a specified timeout, then attempts to parse the response into the expected +/// type `T`. This method is generic and can be used for various Ethereum actions by specifying the appropriate `EthAction` +/// and return type `T`. +/// Note the timeout of 5s. +pub fn send_request_and_parse_response( action: EthAction, ) -> anyhow::Result { let resp = KiRequest::new() @@ -81,6 +88,10 @@ fn send_request_and_parse_response( } } +/// Retrieves the current block number. +/// +/// # Returns +/// An `anyhow::Result` representing the current block number. pub fn get_block_number() -> anyhow::Result { let action = EthAction::Request { method: "eth_blockNumber".to_string(), @@ -91,6 +102,14 @@ pub fn get_block_number() -> anyhow::Result { Ok(res.to::()) } +/// Retrieves the balance of the given address at the specified block. +/// +/// # Parameters +/// - `address`: The address to query the balance for. +/// - `tag`: Optional block ID to specify the block at which the balance is queried. +/// +/// # Returns +/// An `anyhow::Result` representing the balance of the address. pub fn get_balance(address: Address, tag: Option) -> anyhow::Result { let params = serde_json::to_value(( address, @@ -104,6 +123,13 @@ pub fn get_balance(address: Address, tag: Option) -> anyhow::Result(action) } +/// Retrieves logs based on a filter. +/// +/// # Parameters +/// - `filter`: The filter criteria for the logs. +/// +/// # Returns +/// An `anyhow::Result>` containing the logs that match the filter. pub fn get_logs(filter: &Filter) -> anyhow::Result> { let action = EthAction::Request { method: "eth_getLogs".to_string(), @@ -113,6 +139,10 @@ pub fn get_logs(filter: &Filter) -> anyhow::Result> { send_request_and_parse_response::>(action) } +/// Retrieves the current gas price. +/// +/// # Returns +/// An `anyhow::Result` representing the current gas price. pub fn get_gas_price() -> anyhow::Result { let action = EthAction::Request { method: "eth_gasPrice".to_string(), @@ -122,6 +152,10 @@ pub fn get_gas_price() -> anyhow::Result { send_request_and_parse_response::(action) } +/// Retrieves the chain ID. +/// +/// # Returns +/// An `anyhow::Result` representing the chain ID. pub fn get_chain_id() -> anyhow::Result { let action = EthAction::Request { method: "eth_chainId".to_string(), @@ -131,6 +165,14 @@ pub fn get_chain_id() -> anyhow::Result { send_request_and_parse_response::(action) } +/// Retrieves the number of transactions sent from the given address. +/// +/// # Parameters +/// - `address`: The address to query the transaction count for. +/// - `tag`: Optional block ID to specify the block at which the count is queried. +/// +/// # Returns +/// An `anyhow::Result` representing the number of transactions sent from the address. pub fn get_transaction_count(address: Address, tag: Option) -> anyhow::Result { let params = serde_json::to_value((address, tag.unwrap_or_default()))?; let action = EthAction::Request { @@ -141,6 +183,14 @@ pub fn get_transaction_count(address: Address, tag: Option) -> anyhow:: send_request_and_parse_response::(action) } +/// Retrieves a block by its hash. +/// +/// # Parameters +/// - `hash`: The hash of the block to retrieve. +/// - `full_tx`: Whether to return full transaction objects or just their hashes. +/// +/// # Returns +/// An `anyhow::Result>` representing the block, if found. pub fn get_block_by_hash(hash: BlockHash, full_tx: bool) -> anyhow::Result> { let params = serde_json::to_value((hash, full_tx))?; let action = EthAction::Request { @@ -150,7 +200,14 @@ pub fn get_block_by_hash(hash: BlockHash, full_tx: bool) -> anyhow::Result>(action) } - +/// Retrieves a block by its number or tag. +/// +/// # Parameters +/// - `number`: The number or tag of the block to retrieve. +/// - `full_tx`: Whether to return full transaction objects or just their hashes. +/// +/// # Returns +/// An `anyhow::Result>` representing the block, if found. pub fn get_block_by_number( number: BlockNumberOrTag, full_tx: bool, @@ -164,6 +221,15 @@ pub fn get_block_by_number( send_request_and_parse_response::>(action) } +/// Retrieves the storage at a given address and key. +/// +/// # Parameters +/// - `address`: The address of the storage to query. +/// - `key`: The key of the storage slot to retrieve. +/// - `tag`: Optional block ID to specify the block at which the storage is queried. +/// +/// # Returns +/// An `anyhow::Result` representing the data stored at the given address and key. pub fn get_storage_at(address: Address, key: U256, tag: Option) -> anyhow::Result { let params = serde_json::to_value((address, key, tag.unwrap_or_default()))?; let action = EthAction::Request { @@ -174,6 +240,14 @@ pub fn get_storage_at(address: Address, key: U256, tag: Option) -> anyh send_request_and_parse_response::(action) } +/// Retrieves the code at a given address. +/// +/// # Parameters +/// - `address`: The address of the code to query. +/// - `tag`: The block ID to specify the block at which the code is queried. +/// +/// # Returns +/// An `anyhow::Result` representing the code stored at the given address. pub fn get_code_at(address: Address, tag: BlockId) -> anyhow::Result { let params = serde_json::to_value((address, tag))?; let action = EthAction::Request { @@ -184,6 +258,13 @@ pub fn get_code_at(address: Address, tag: BlockId) -> anyhow::Result { send_request_and_parse_response::(action) } +/// Retrieves a transaction by its hash. +/// +/// # Parameters +/// - `hash`: The hash of the transaction to retrieve. +/// +/// # Returns +/// An `anyhow::Result>` representing the transaction, if found. pub fn get_transaction_by_hash(hash: TxHash) -> anyhow::Result> { let params = serde_json::to_value((hash,))?; let action = EthAction::Request { @@ -194,6 +275,13 @@ pub fn get_transaction_by_hash(hash: TxHash) -> anyhow::Result>(action) } +/// Retrieves the receipt of a transaction by its hash. +/// +/// # Parameters +/// - `hash`: The hash of the transaction for which the receipt is requested. +/// +/// # Returns +/// An `anyhow::Result>` representing the transaction receipt, if found. pub fn get_transaction_receipt(hash: TxHash) -> anyhow::Result> { let params = serde_json::to_value((hash,))?; let action = EthAction::Request { @@ -204,6 +292,14 @@ pub fn get_transaction_receipt(hash: TxHash) -> anyhow::Result>(action) } +/// Estimates the amount of gas that a transaction will consume. +/// +/// # Parameters +/// - `tx`: The transaction request object containing the details of the transaction to estimate gas for. +/// - `block`: Optional block ID to specify the block at which the gas estimate should be made. +/// +/// # Returns +/// An `anyhow::Result` representing the estimated gas amount. pub fn estimate_gas(tx: TransactionRequest, block: Option) -> anyhow::Result { let params = serde_json::to_value((tx, block.unwrap_or_default()))?; let action = EthAction::Request { @@ -214,7 +310,11 @@ pub fn estimate_gas(tx: TransactionRequest, block: Option) -> anyhow::R send_request_and_parse_response::(action) } -// note will and should return empty I think... +/// Retrieves the list of accounts controlled by the node. +/// +/// # Returns +/// An `anyhow::Result>` representing the list of accounts. +/// Note: This function may return an empty list depending on the node's configuration and capabilities. pub fn get_accounts() -> anyhow::Result> { let action = EthAction::Request { method: "eth_accounts".to_string(), @@ -224,6 +324,15 @@ pub fn get_accounts() -> anyhow::Result> { send_request_and_parse_response::>(action) } +/// Retrieves the fee history for a given range of blocks. +/// +/// # Parameters +/// - `block_count`: The number of blocks to include in the history. +/// - `last_block`: The ending block number or tag for the history range. +/// - `reward_percentiles`: A list of percentiles to report fee rewards for. +/// +/// # Returns +/// An `anyhow::Result` representing the fee history for the specified range. pub fn get_fee_history( block_count: U256, last_block: BlockNumberOrTag, @@ -238,6 +347,14 @@ pub fn get_fee_history( send_request_and_parse_response::(action) } +/// Executes a call transaction, which is directly executed in the VM of the node, but never mined into the blockchain. +/// +/// # Parameters +/// - `tx`: The transaction request object containing the details of the call. +/// - `block`: Optional block ID to specify the block at which the call should be made. +/// +/// # Returns +/// An `anyhow::Result` representing the result of the call. pub fn call(tx: TransactionRequest, block: Option) -> anyhow::Result { let params = serde_json::to_value((tx, block.unwrap_or_default()))?; let action = EthAction::Request { @@ -248,6 +365,13 @@ pub fn call(tx: TransactionRequest, block: Option) -> anyhow::Result(action) } +/// Sends a raw transaction to the network. +/// +/// # Parameters +/// - `tx`: The raw transaction data. +/// +/// # Returns +/// An `anyhow::Result` representing the hash of the transaction once it has been sent. pub fn send_raw_transaction(tx: Bytes) -> anyhow::Result { let action = EthAction::Request { method: "eth_sendRawTransaction".to_string(), @@ -257,8 +381,14 @@ pub fn send_raw_transaction(tx: Bytes) -> anyhow::Result { send_request_and_parse_response::(action) } -/// sends requests eth_getLogs and eth_subscribe, -/// doesn't await, handle them as incoming EthMessage::Sub, and EthResponse::Response +/// Sends requests for `eth_getLogs` and `eth_subscribe` without waiting for a response, handling them as incoming `EthMessage::Sub` and `EthResponse::Response`. +/// +/// # Parameters +/// - `sub_id`: The subscription ID to be used for these operations. +/// - `filter`: The filter criteria for the logs. +/// +/// # Returns +/// An `anyhow::Result<()>` indicating the operation was dispatched. pub fn getlogs_and_subscribe(sub_id: u64, filter: Filter) -> anyhow::Result<()> { let action = EthAction::SubscribeLogs { sub_id, @@ -272,7 +402,14 @@ pub fn getlogs_and_subscribe(sub_id: u64, filter: Filter) -> anyhow::Result<()> .send() } -/// sends a request to eth_subscribe, doesn't wait for ok.. +/// Subscribes to logs without waiting for a confirmation. +/// +/// # Parameters +/// - `sub_id`: The subscription ID to be used for unsubscribing. +/// - `filter`: The filter criteria for the logs. +/// +/// # Returns +/// An `anyhow::Result<()>` indicating the operation was dispatched. pub fn subscribe(sub_id: u64, filter: Filter) -> anyhow::Result<()> { let action = EthAction::SubscribeLogs { sub_id, @@ -285,7 +422,13 @@ pub fn subscribe(sub_id: u64, filter: Filter) -> anyhow::Result<()> { .body(serde_json::to_vec(&action)?) .send() } - +/// Unsubscribes from a previously created subscription. +/// +/// # Parameters +/// - `sub_id`: The subscription ID to unsubscribe from. +/// +/// # Returns +/// An `anyhow::Result<()>` indicating the success or failure of the unsubscription request. pub fn unsubscribe(sub_id: u64) -> anyhow::Result<()> { let action = EthAction::UnsubscribeLogs(sub_id); From 95afcf9dbe902302c6a0a672864009712bdf01c9 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Wed, 14 Feb 2024 11:11:54 -0500 Subject: [PATCH 15/36] docstring added --- src/kernel_types.rs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/kernel_types.rs b/src/kernel_types.rs index be2928e..e79aef6 100644 --- a/src/kernel_types.rs +++ b/src/kernel_types.rs @@ -198,9 +198,15 @@ impl StateError { // package types // -pub type PackageVersion = (u32, u32, u32); - -/// the type that gets deserialized from `metadata.json` in a package +/// Represents the metadata associated with a kinode package, which is an ERC721 compatible token. +/// This is deserialized from the `metadata.json` file in a package. +/// Fields: +/// - `name`: An optional field representing the display name of the package. This does not have to be unique, and is not used for identification purposes. +/// - `description`: An optional field providing a description of the package. +/// - `image`: An optional field containing a URL to an image representing the package. +/// - `external_url`: An optional field containing a URL for more information about the package. For example, a link to the github repository. +/// - `animation_url`: An optional field containing a URL to an animation or video representing the package. +/// - `properties`: A requried field containing important information about the package. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Erc721Metadata { pub name: Option, @@ -211,6 +217,18 @@ pub struct Erc721Metadata { pub properties: Erc721Properties, } +/// Represents critical fields of a kinode package in an ERC721 compatible format. +/// This follows the [ERC1155](https://github.com/ethereum/ercs/blob/master/ERCS/erc-1155.md#erc-1155-metadata-uri-json-schema) metadata standard. +/// +/// Fields: +/// - `package_name`: The unique name of the package, used in the `PackageId`, e.g. `package_name:publisher`. +/// - `publisher`: The KNS identity of the package publisher used in the `PackageId`, e.g. `package_name:publisher` +/// - `current_version`: A string representing the current version of the package, e.g. `1.0.0`. +/// - `mirrors`: A list of NodeIds where the package can be found, providing redundancy. +/// - `code_hashes`: A map from version names to their respective SHA-256 hashes. +/// - `license`: An optional field containing the license of the package. +/// - `screenshots`: An optional field containing a list of URLs to screenshots of the package. +/// - `wit_version`: An optional field containing the version of the WIT standard that the package adheres to. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Erc721Properties { pub package_name: String, From 70cadf974d7fd5c17f7190902d07238758f522ae Mon Sep 17 00:00:00 2001 From: OdinsBadEye Date: Thu, 15 Feb 2024 18:38:37 +0000 Subject: [PATCH 16/36] Updates to IncomingHttpRequest (#60) --- pull_request_template.md | 15 +++++++++++++++ src/http.rs | 18 ++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 pull_request_template.md diff --git a/pull_request_template.md b/pull_request_template.md new file mode 100644 index 0000000..fff18e8 --- /dev/null +++ b/pull_request_template.md @@ -0,0 +1,15 @@ +## Problem + +{A brief description of the problem, along with necessary context.} + +## Solution + +{A brief description of how you solved the problem.} + +## Docs Update + +[Corresponding docs PR](https://github.com/kinode-dao/kinode-book/pull/my-pr-number) + +## Notes + +{Any other information useful for reviewers.} diff --git a/src/http.rs b/src/http.rs index d557d06..885cb52 100644 --- a/src/http.rs +++ b/src/http.rs @@ -44,7 +44,9 @@ pub struct IncomingHttpRequest { source_socket_addr: Option, // will parse to SocketAddr method: String, // will parse to http::Method url: String, // will parse to url::Url + bound_path: String, // the matching path that was bound headers: HashMap, // will parse to http::HeaderMap + url_params: HashMap, query_params: HashMap, // BODY is stored in the lazy_load_blob, as bytes } @@ -233,6 +235,18 @@ impl IncomingHttpRequest { } } + /// Returns the path that was originally bound, with an optional prefix stripped. + /// The prefix would normally be the process ID as a &str, but it could be anything. + pub fn bound_path(&self, process_id_to_strip: Option<&str>) -> &str { + match process_id_to_strip { + Some(process_id) => self + .bound_path + .strip_prefix(&format!("/{}", process_id)) + .unwrap_or(&self.bound_path), + None => &self.bound_path, + } + } + pub fn path(&self) -> anyhow::Result { let url = url::Url::parse(&self.url)?; // skip the first path segment, which is the process ID. @@ -260,6 +274,10 @@ impl IncomingHttpRequest { header_map } + pub fn url_params(&self) -> &HashMap { + &self.url_params + } + pub fn query_params(&self) -> &HashMap { &self.query_params } From 935929afab615625558b57677e56a6bb1d75f39d Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Thu, 15 Feb 2024 16:42:58 -0300 Subject: [PATCH 17/36] eth: docstring fix --- src/eth.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/eth.rs b/src/eth.rs index ead4731..86f8cfc 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -27,7 +27,8 @@ pub enum EthAction { params: serde_json::Value, }, } -/// Incoming subscription update. + +/// Incoming Request for subscription updates that processes will receive. #[derive(Debug, Serialize, Deserialize)] pub struct EthSub { pub id: u64, From cacc49c9757d66fcfd1a1fdf02efdaf78343ba02 Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Thu, 15 Feb 2024 17:17:38 -0300 Subject: [PATCH 18/36] eth: sub error request and result type --- src/eth.rs | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/eth.rs b/src/eth.rs index 86f8cfc..95d7d6f 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -28,13 +28,23 @@ pub enum EthAction { }, } -/// Incoming Request for subscription updates that processes will receive. +/// Incoming Result type for subscription updates or errors that processes will receive. +pub type EthSubResult = Result; + +/// Incoming Request type for subscription updates. #[derive(Debug, Serialize, Deserialize)] pub struct EthSub { pub id: u64, pub result: SubscriptionResult, } +/// Incoming Request for subscription errors that processes will receive. +/// If your subscription is closed unexpectedly, you will receive this. +pub struct EthSubError { + pub id: u64, + pub error: String, +} + /// The Response type which a process will get from requesting with an [`EthAction`] will be /// of the form `Result<(), EthError>`, serialized and deserialized using `serde_json::to_vec` /// and `serde_json::from_slice`. @@ -382,27 +392,6 @@ pub fn send_raw_transaction(tx: Bytes) -> anyhow::Result { send_request_and_parse_response::(action) } -/// Sends requests for `eth_getLogs` and `eth_subscribe` without waiting for a response, handling them as incoming `EthMessage::Sub` and `EthResponse::Response`. -/// -/// # Parameters -/// - `sub_id`: The subscription ID to be used for these operations. -/// - `filter`: The filter criteria for the logs. -/// -/// # Returns -/// An `anyhow::Result<()>` indicating the operation was dispatched. -pub fn getlogs_and_subscribe(sub_id: u64, filter: Filter) -> anyhow::Result<()> { - let action = EthAction::SubscribeLogs { - sub_id, - kind: SubscriptionKind::Logs, - params: Params::Logs(Box::new(filter)), - }; - - KiRequest::new() - .target(("our", "eth", "distro", "sys")) - .body(serde_json::to_vec(&action)?) - .send() -} - /// Subscribes to logs without waiting for a confirmation. /// /// # Parameters From c70014519fc3eef315bb486d178058faff4390e1 Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Thu, 15 Feb 2024 17:32:39 -0300 Subject: [PATCH 19/36] ethsuberror serialize hotfix --- src/eth.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/eth.rs b/src/eth.rs index 95d7d6f..644a235 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -40,6 +40,7 @@ pub struct EthSub { /// Incoming Request for subscription errors that processes will receive. /// If your subscription is closed unexpectedly, you will receive this. +#[derive(Debug, Serialize, Deserialize)] pub struct EthSubError { pub id: u64, pub error: String, From ad17eaaa6230d33f98fba5370529931b634e17d8 Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Thu, 15 Feb 2024 17:51:55 -0300 Subject: [PATCH 20/36] eth: temp timeout 10 --- src/eth.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eth.rs b/src/eth.rs index 644a235..7fb89db 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -85,7 +85,7 @@ pub fn send_request_and_parse_response( let resp = KiRequest::new() .target(("our", "eth", "distro", "sys")) .body(serde_json::to_vec(&action)?) - .send_and_await_response(5)??; + .send_and_await_response(10)??; match resp { Message::Response { body, .. } => { From 7b6fd6ee160299514fee30b315a2a53fbfb434d7 Mon Sep 17 00:00:00 2001 From: dr-frmr Date: Thu, 22 Feb 2024 17:37:32 -0300 Subject: [PATCH 21/36] eth: add chain id to types --- Cargo.lock | 47 ++++--------- src/eth.rs | 160 +++++++++++++++++++++++++++++++++++--------- src/kernel_types.rs | 11 +++ 3 files changed, 153 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a3dfb4..60c0706 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1757,15 +1757,6 @@ version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" -[[package]] -name = "wasm-encoder" -version = "0.38.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f" -dependencies = [ - "leb128", -] - [[package]] name = "wasm-encoder" version = "0.41.0" @@ -1787,18 +1778,8 @@ dependencies = [ "serde_derive", "serde_json", "spdx", - "wasm-encoder 0.41.0", - "wasmparser 0.121.0", -] - -[[package]] -name = "wasmparser" -version = "0.118.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" -dependencies = [ - "indexmap", - "semver 1.0.21", + "wasm-encoder", + "wasmparser", ] [[package]] @@ -1899,8 +1880,8 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.16.0" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" +version = "0.17.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=21a46c7#21a46c774532da99384f7a1877c1fcfb7a4c72d3" dependencies = [ "bitflags", "wit-bindgen-rust-macro", @@ -1908,8 +1889,8 @@ dependencies = [ [[package]] name = "wit-bindgen-core" -version = "0.16.0" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" +version = "0.17.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=21a46c7#21a46c774532da99384f7a1877c1fcfb7a4c72d3" dependencies = [ "anyhow", "wit-component", @@ -1918,8 +1899,8 @@ dependencies = [ [[package]] name = "wit-bindgen-rust" -version = "0.16.0" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" +version = "0.17.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=21a46c7#21a46c774532da99384f7a1877c1fcfb7a4c72d3" dependencies = [ "anyhow", "heck", @@ -1930,8 +1911,8 @@ dependencies = [ [[package]] name = "wit-bindgen-rust-macro" -version = "0.16.0" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" +version = "0.17.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=21a46c7#21a46c774532da99384f7a1877c1fcfb7a4c72d3" dependencies = [ "anyhow", "proc-macro2", @@ -1944,9 +1925,9 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.18.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2" +checksum = "331de496d439010797c17637d8002712b9b69110f1669164c09dfa226ad277bb" dependencies = [ "anyhow", "bitflags", @@ -1955,9 +1936,9 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "wasm-encoder 0.38.1", + "wasm-encoder", "wasm-metadata", - "wasmparser 0.118.1", + "wasmparser", "wit-parser", ] diff --git a/src/eth.rs b/src/eth.rs index 7fb89db..2c0c6cb 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -8,7 +8,9 @@ pub use alloy_rpc_types::{ }; use serde::{Deserialize, Serialize}; -/// The Action and Request type that can be made to eth:distro:sys. +/// The Action and Request type that can be made to eth:distro:sys. Any process with messaging +/// capabilities can send this action to the eth provider. +/// /// Will be serialized and deserialized using `serde_json::to_vec` and `serde_json::from_slice`. #[derive(Debug, Serialize, Deserialize)] pub enum EthAction { @@ -16,6 +18,7 @@ pub enum EthAction { /// Logs come in as alloy_rpc_types::pubsub::SubscriptionResults SubscribeLogs { sub_id: u64, + chain_id: u64, kind: SubscriptionKind, params: Params, }, @@ -23,22 +26,25 @@ pub enum EthAction { UnsubscribeLogs(u64), /// Raw request. Used by kinode_process_lib. Request { + chain_id: u64, method: String, params: serde_json::Value, }, } /// Incoming Result type for subscription updates or errors that processes will receive. +/// Can deserialize all incoming requests from eth:distro:sys to this type. +/// +/// Will be serialized and deserialized using `serde_json::to_vec` and `serde_json::from_slice`. pub type EthSubResult = Result; -/// Incoming Request type for subscription updates. +/// Incoming Request type for successful subscription updates. #[derive(Debug, Serialize, Deserialize)] pub struct EthSub { pub id: u64, pub result: SubscriptionResult, } -/// Incoming Request for subscription errors that processes will receive. /// If your subscription is closed unexpectedly, you will receive this. #[derive(Debug, Serialize, Deserialize)] pub struct EthSubError { @@ -58,6 +64,8 @@ pub enum EthResponse { #[derive(Debug, Serialize, Deserialize)] pub enum EthError { + /// No RPC provider for the chain + NoRpcForChain, /// Underlying transport error TransportError(String), /// Subscription closed @@ -67,11 +75,68 @@ pub enum EthError { /// Invalid method InvalidMethod(String), /// Permission denied - PermissionDenied(String), + PermissionDenied, /// Internal RPC error RpcError(String), } +/// The action type used for configuring eth:distro:sys. Only processes which have the "root" +/// capability from eth:distro:sys can successfully send this action. +/// +/// NOTE: changes to config will not be persisted between boots, they must be saved in .env +/// to be reflected between boots. TODO: can change this +#[derive(Debug, Serialize, Deserialize)] +pub enum EthConfigAction { + /// Add a new provider to the list of providers. + AddProvider(ProviderConfig), + /// Remove a provider from the list of providers. + /// The tuple is (chain_id, node_id/rpc_url). + RemoveProvider((u64, String)), + /// make our provider public + SetPublic, + /// make our provider not-public + SetPrivate, + /// add node to whitelist on a provider + AllowNode(String), + /// remove node from whitelist on a provider + UnallowNode(String), + /// add node to blacklist on a provider + DenyNode(String), + /// remove node from blacklist on a provider + UndenyNode(String), + /// Set the list of providers to a new list. + /// Replaces all existing saved provider configs. + SetProviders(SavedConfigs), + /// Get the list of as a [`SavedConfigs`] object. + GetProviders, +} + +/// Response type from an [`EthConfigAction`] request. +#[derive(Debug, Serialize, Deserialize)] +pub enum EthConfigResponse { + Ok, + /// Response from a GetProviders request. + Providers(SavedConfigs), + /// Permission denied due to missing capability + PermissionDenied, +} + +pub type SavedConfigs = Vec; + +/// Provider config. Can currently be a node or a ws provider instance. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct ProviderConfig { + pub chain_id: u64, + pub trusted: bool, + pub provider: NodeOrRpcUrl, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub enum NodeOrRpcUrl { + Node(crate::kernel_types::KnsUpdate), + RpcUrl(String), +} + /// Sends a request based on the specified `EthAction` and parses the response. /// /// This function constructs a request targeting the Ethereum distribution system, serializes the provided `EthAction`, @@ -104,8 +169,9 @@ pub fn send_request_and_parse_response( /// /// # Returns /// An `anyhow::Result` representing the current block number. -pub fn get_block_number() -> anyhow::Result { +pub fn get_block_number(chain_id: u64) -> anyhow::Result { let action = EthAction::Request { + chain_id, method: "eth_blockNumber".to_string(), params: ().into(), }; @@ -122,12 +188,13 @@ pub fn get_block_number() -> anyhow::Result { /// /// # Returns /// An `anyhow::Result` representing the balance of the address. -pub fn get_balance(address: Address, tag: Option) -> anyhow::Result { +pub fn get_balance(chain_id: u64, address: Address, tag: Option) -> anyhow::Result { let params = serde_json::to_value(( address, tag.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest)), ))?; let action = EthAction::Request { + chain_id, method: "eth_getBalance".to_string(), params, }; @@ -142,8 +209,9 @@ pub fn get_balance(address: Address, tag: Option) -> anyhow::Result>` containing the logs that match the filter. -pub fn get_logs(filter: &Filter) -> anyhow::Result> { +pub fn get_logs(chain_id: u64, filter: &Filter) -> anyhow::Result> { let action = EthAction::Request { + chain_id, method: "eth_getLogs".to_string(), params: serde_json::to_value((filter,))?, }; @@ -155,8 +223,9 @@ pub fn get_logs(filter: &Filter) -> anyhow::Result> { /// /// # Returns /// An `anyhow::Result` representing the current gas price. -pub fn get_gas_price() -> anyhow::Result { +pub fn get_gas_price(chain_id: u64) -> anyhow::Result { let action = EthAction::Request { + chain_id, method: "eth_gasPrice".to_string(), params: ().into(), }; @@ -164,19 +233,6 @@ pub fn get_gas_price() -> anyhow::Result { send_request_and_parse_response::(action) } -/// Retrieves the chain ID. -/// -/// # Returns -/// An `anyhow::Result` representing the chain ID. -pub fn get_chain_id() -> anyhow::Result { - let action = EthAction::Request { - method: "eth_chainId".to_string(), - params: ().into(), - }; - - send_request_and_parse_response::(action) -} - /// Retrieves the number of transactions sent from the given address. /// /// # Parameters @@ -185,9 +241,14 @@ pub fn get_chain_id() -> anyhow::Result { /// /// # Returns /// An `anyhow::Result` representing the number of transactions sent from the address. -pub fn get_transaction_count(address: Address, tag: Option) -> anyhow::Result { +pub fn get_transaction_count( + chain_id: u64, + address: Address, + tag: Option, +) -> anyhow::Result { let params = serde_json::to_value((address, tag.unwrap_or_default()))?; let action = EthAction::Request { + chain_id, method: "eth_getTransactionCount".to_string(), params, }; @@ -203,9 +264,14 @@ pub fn get_transaction_count(address: Address, tag: Option) -> anyhow:: /// /// # Returns /// An `anyhow::Result>` representing the block, if found. -pub fn get_block_by_hash(hash: BlockHash, full_tx: bool) -> anyhow::Result> { +pub fn get_block_by_hash( + chain_id: u64, + hash: BlockHash, + full_tx: bool, +) -> anyhow::Result> { let params = serde_json::to_value((hash, full_tx))?; let action = EthAction::Request { + chain_id, method: "eth_getBlockByHash".to_string(), params, }; @@ -221,11 +287,13 @@ pub fn get_block_by_hash(hash: BlockHash, full_tx: bool) -> anyhow::Result>` representing the block, if found. pub fn get_block_by_number( + chain_id: u64, number: BlockNumberOrTag, full_tx: bool, ) -> anyhow::Result> { let params = serde_json::to_value((number, full_tx))?; let action = EthAction::Request { + chain_id, method: "eth_getBlockByNumber".to_string(), params, }; @@ -242,9 +310,15 @@ pub fn get_block_by_number( /// /// # Returns /// An `anyhow::Result` representing the data stored at the given address and key. -pub fn get_storage_at(address: Address, key: U256, tag: Option) -> anyhow::Result { +pub fn get_storage_at( + chain_id: u64, + address: Address, + key: U256, + tag: Option, +) -> anyhow::Result { let params = serde_json::to_value((address, key, tag.unwrap_or_default()))?; let action = EthAction::Request { + chain_id, method: "eth_getStorageAt".to_string(), params, }; @@ -260,9 +334,10 @@ pub fn get_storage_at(address: Address, key: U256, tag: Option) -> anyh /// /// # Returns /// An `anyhow::Result` representing the code stored at the given address. -pub fn get_code_at(address: Address, tag: BlockId) -> anyhow::Result { +pub fn get_code_at(chain_id: u64, address: Address, tag: BlockId) -> anyhow::Result { let params = serde_json::to_value((address, tag))?; let action = EthAction::Request { + chain_id, method: "eth_getCode".to_string(), params, }; @@ -277,9 +352,10 @@ pub fn get_code_at(address: Address, tag: BlockId) -> anyhow::Result { /// /// # Returns /// An `anyhow::Result>` representing the transaction, if found. -pub fn get_transaction_by_hash(hash: TxHash) -> anyhow::Result> { +pub fn get_transaction_by_hash(chain_id: u64, hash: TxHash) -> anyhow::Result> { let params = serde_json::to_value((hash,))?; let action = EthAction::Request { + chain_id, method: "eth_getTransactionByHash".to_string(), params, }; @@ -294,9 +370,13 @@ pub fn get_transaction_by_hash(hash: TxHash) -> anyhow::Result>` representing the transaction receipt, if found. -pub fn get_transaction_receipt(hash: TxHash) -> anyhow::Result> { +pub fn get_transaction_receipt( + chain_id: u64, + hash: TxHash, +) -> anyhow::Result> { let params = serde_json::to_value((hash,))?; let action = EthAction::Request { + chain_id, method: "eth_getTransactionReceipt".to_string(), params, }; @@ -312,9 +392,14 @@ pub fn get_transaction_receipt(hash: TxHash) -> anyhow::Result` representing the estimated gas amount. -pub fn estimate_gas(tx: TransactionRequest, block: Option) -> anyhow::Result { +pub fn estimate_gas( + chain_id: u64, + tx: TransactionRequest, + block: Option, +) -> anyhow::Result { let params = serde_json::to_value((tx, block.unwrap_or_default()))?; let action = EthAction::Request { + chain_id, method: "eth_estimateGas".to_string(), params, }; @@ -327,8 +412,9 @@ pub fn estimate_gas(tx: TransactionRequest, block: Option) -> anyhow::R /// # Returns /// An `anyhow::Result>` representing the list of accounts. /// Note: This function may return an empty list depending on the node's configuration and capabilities. -pub fn get_accounts() -> anyhow::Result> { +pub fn get_accounts(chain_id: u64) -> anyhow::Result> { let action = EthAction::Request { + chain_id, method: "eth_accounts".to_string(), params: serde_json::Value::Array(vec![]), }; @@ -346,12 +432,14 @@ pub fn get_accounts() -> anyhow::Result> { /// # Returns /// An `anyhow::Result` representing the fee history for the specified range. pub fn get_fee_history( + chain_id: u64, block_count: U256, last_block: BlockNumberOrTag, reward_percentiles: Vec, ) -> anyhow::Result { let params = serde_json::to_value((block_count, last_block, reward_percentiles))?; let action = EthAction::Request { + chain_id, method: "eth_feeHistory".to_string(), params, }; @@ -367,9 +455,14 @@ pub fn get_fee_history( /// /// # Returns /// An `anyhow::Result` representing the result of the call. -pub fn call(tx: TransactionRequest, block: Option) -> anyhow::Result { +pub fn call( + chain_id: u64, + tx: TransactionRequest, + block: Option, +) -> anyhow::Result { let params = serde_json::to_value((tx, block.unwrap_or_default()))?; let action = EthAction::Request { + chain_id, method: "eth_call".to_string(), params, }; @@ -384,8 +477,9 @@ pub fn call(tx: TransactionRequest, block: Option) -> anyhow::Result` representing the hash of the transaction once it has been sent. -pub fn send_raw_transaction(tx: Bytes) -> anyhow::Result { +pub fn send_raw_transaction(chain_id: u64, tx: Bytes) -> anyhow::Result { let action = EthAction::Request { + chain_id, method: "eth_sendRawTransaction".to_string(), params: serde_json::to_value((tx,))?, }; @@ -401,9 +495,10 @@ pub fn send_raw_transaction(tx: Bytes) -> anyhow::Result { /// /// # Returns /// An `anyhow::Result<()>` indicating the operation was dispatched. -pub fn subscribe(sub_id: u64, filter: Filter) -> anyhow::Result<()> { +pub fn subscribe(sub_id: u64, chain_id: u64, filter: Filter) -> anyhow::Result<()> { let action = EthAction::SubscribeLogs { sub_id, + chain_id, kind: SubscriptionKind::Logs, params: Params::Logs(Box::new(filter)), }; @@ -413,6 +508,7 @@ pub fn subscribe(sub_id: u64, filter: Filter) -> anyhow::Result<()> { .body(serde_json::to_vec(&action)?) .send() } + /// Unsubscribes from a previously created subscription. /// /// # Parameters diff --git a/src/kernel_types.rs b/src/kernel_types.rs index e79aef6..258e9f0 100644 --- a/src/kernel_types.rs +++ b/src/kernel_types.rs @@ -432,3 +432,14 @@ pub enum MessageType { Request, Response, } + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct KnsUpdate { + pub name: String, // actual username / domain name + pub owner: String, + pub node: String, // hex namehash of node + pub public_key: String, + pub ip: String, + pub port: u16, + pub routers: Vec, +} From 68b6a1a81f67a076762a0aeed3a63fb089746ac7 Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Thu, 22 Feb 2024 18:50:58 -0300 Subject: [PATCH 22/36] kv & sql: timeout options --- src/kv.rs | 24 +++++++++++++++--------- src/sqlite.rs | 22 ++++++++++++++-------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/kv.rs b/src/kv.rs index 1ad3680..a41d31b 100644 --- a/src/kv.rs +++ b/src/kv.rs @@ -57,6 +57,7 @@ pub enum KvError { pub struct Kv { pub package_id: PackageId, pub db: String, + pub timeout: u64, } impl Kv { @@ -69,7 +70,7 @@ impl Kv { db: self.db.clone(), action: KvAction::Get { key }, })?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match res { Ok(Message::Response { body, .. }) => { @@ -101,7 +102,7 @@ impl Kv { action: KvAction::Set { key, tx_id }, })?) .blob_bytes(value) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match res { Ok(Message::Response { body, .. }) => { @@ -126,7 +127,7 @@ impl Kv { db: self.db.clone(), action: KvAction::Delete { key, tx_id }, })?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match res { Ok(Message::Response { body, .. }) => { @@ -151,7 +152,7 @@ impl Kv { db: self.db.clone(), action: KvAction::BeginTx, })?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match res { Ok(Message::Response { body, .. }) => { @@ -176,7 +177,7 @@ impl Kv { db: self.db.clone(), action: KvAction::Commit { tx_id }, })?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match res { Ok(Message::Response { body, .. }) => { @@ -194,7 +195,9 @@ impl Kv { } /// Opens or creates a kv db. -pub fn open(package_id: PackageId, db: &str) -> anyhow::Result { +pub fn open(package_id: PackageId, db: &str, timeout: Option) -> anyhow::Result { + let timeout = timeout.unwrap_or(5); + let res = Request::new() .target(("our", "kv", "distro", "sys")) .body(serde_json::to_vec(&KvRequest { @@ -202,7 +205,7 @@ pub fn open(package_id: PackageId, db: &str) -> anyhow::Result { db: db.to_string(), action: KvAction::Open, })?) - .send_and_await_response(5)?; + .send_and_await_response(timeout)?; match res { Ok(Message::Response { body, .. }) => { @@ -212,6 +215,7 @@ pub fn open(package_id: PackageId, db: &str) -> anyhow::Result { KvResponse::Ok => Ok(Kv { package_id, db: db.to_string(), + timeout, }), KvResponse::Err { error } => Err(error.into()), _ => Err(anyhow::anyhow!("kv: unexpected response {:?}", response)), @@ -222,7 +226,9 @@ pub fn open(package_id: PackageId, db: &str) -> anyhow::Result { } /// Removes and deletes a kv db. -pub fn remove_db(package_id: PackageId, db: &str) -> anyhow::Result<()> { +pub fn remove_db(package_id: PackageId, db: &str, timeout: Option) -> anyhow::Result<()> { + let timeout = timeout.unwrap_or(5); + let res = Request::new() .target(("our", "kv", "distro", "sys")) .body(serde_json::to_vec(&KvRequest { @@ -230,7 +236,7 @@ pub fn remove_db(package_id: PackageId, db: &str) -> anyhow::Result<()> { db: db.to_string(), action: KvAction::RemoveDb, })?) - .send_and_await_response(5)?; + .send_and_await_response(timeout)?; match res { Ok(Message::Response { body, .. }) => { diff --git a/src/sqlite.rs b/src/sqlite.rs index 6bd1374..f87e120 100644 --- a/src/sqlite.rs +++ b/src/sqlite.rs @@ -79,6 +79,7 @@ pub enum SqliteError { pub struct Sqlite { pub package_id: PackageId, pub db: String, + pub timeout: u64, } impl Sqlite { @@ -96,7 +97,7 @@ impl Sqlite { action: SqliteAction::Read { query }, })?) .blob_bytes(serde_json::to_vec(¶ms)?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match res { Ok(Message::Response { body, .. }) => { @@ -141,7 +142,7 @@ impl Sqlite { action: SqliteAction::Write { statement, tx_id }, })?) .blob_bytes(serde_json::to_vec(¶ms)?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match res { Ok(Message::Response { body, .. }) => { @@ -169,7 +170,7 @@ impl Sqlite { db: self.db.clone(), action: SqliteAction::BeginTx, })?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match res { Ok(Message::Response { body, .. }) => { @@ -197,7 +198,7 @@ impl Sqlite { db: self.db.clone(), action: SqliteAction::Commit { tx_id }, })?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match res { Ok(Message::Response { body, .. }) => { @@ -218,7 +219,9 @@ impl Sqlite { } /// Open or create sqlite database. -pub fn open(package_id: PackageId, db: &str) -> anyhow::Result { +pub fn open(package_id: PackageId, db: &str, timeout: Option) -> anyhow::Result { + let timeout = timeout.unwrap_or(5); + let res = Request::new() .target(("our", "sqlite", "distro", "sys")) .body(serde_json::to_vec(&SqliteRequest { @@ -226,7 +229,7 @@ pub fn open(package_id: PackageId, db: &str) -> anyhow::Result { db: db.to_string(), action: SqliteAction::Open, })?) - .send_and_await_response(5)?; + .send_and_await_response(timeout)?; match res { Ok(Message::Response { body, .. }) => { @@ -236,6 +239,7 @@ pub fn open(package_id: PackageId, db: &str) -> anyhow::Result { SqliteResponse::Ok => Ok(Sqlite { package_id, db: db.to_string(), + timeout, }), SqliteResponse::Err { error } => Err(error.into()), _ => Err(anyhow::anyhow!( @@ -249,7 +253,9 @@ pub fn open(package_id: PackageId, db: &str) -> anyhow::Result { } /// Remove and delete sqlite database. -pub fn remove_db(package_id: PackageId, db: &str) -> anyhow::Result<()> { +pub fn remove_db(package_id: PackageId, db: &str, timeout: Option) -> anyhow::Result<()> { + let timeout = timeout.unwrap_or(5); + let res = Request::new() .target(("our", "sqlite", "distro", "sys")) .body(serde_json::to_vec(&SqliteRequest { @@ -257,7 +263,7 @@ pub fn remove_db(package_id: PackageId, db: &str) -> anyhow::Result<()> { db: db.to_string(), action: SqliteAction::RemoveDb, })?) - .send_and_await_response(5)?; + .send_and_await_response(timeout)?; match res { Ok(Message::Response { body, .. }) => { From 71580670f9648f8137ab85a1bd5ccd99a7d06b2a Mon Sep 17 00:00:00 2001 From: dr-frmr Date: Thu, 22 Feb 2024 18:55:36 -0300 Subject: [PATCH 23/36] eth: refactor into Provider struct --- src/eth.rs | 767 ++++++++++++++++++++++++++++------------------------- 1 file changed, 401 insertions(+), 366 deletions(-) diff --git a/src/eth.rs b/src/eth.rs index 2c0c6cb..4fea29e 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -137,390 +137,425 @@ pub enum NodeOrRpcUrl { RpcUrl(String), } -/// Sends a request based on the specified `EthAction` and parses the response. -/// -/// This function constructs a request targeting the Ethereum distribution system, serializes the provided `EthAction`, -/// and sends it. It awaits a response with a specified timeout, then attempts to parse the response into the expected -/// type `T`. This method is generic and can be used for various Ethereum actions by specifying the appropriate `EthAction` -/// and return type `T`. -/// Note the timeout of 5s. -pub fn send_request_and_parse_response( - action: EthAction, -) -> anyhow::Result { - let resp = KiRequest::new() - .target(("our", "eth", "distro", "sys")) - .body(serde_json::to_vec(&action)?) - .send_and_await_response(10)??; - - match resp { - Message::Response { body, .. } => { - let response = serde_json::from_slice::(&body)?; - match response { - EthResponse::Response { value } => serde_json::from_value::(value) - .map_err(|e| anyhow::anyhow!("failed to parse response: {}", e)), - _ => Err(anyhow::anyhow!("unexpected response: {:?}", response)), +/// An EVM chain provider. Create this object to start making RPC calls. +/// Set the chain_id to determine which chain to call: requests will fail +/// unless the node this process is running on has access to a provider +/// for that chain. +pub struct Provider { + chain_id: u64, + request_timeout: u64, +} + +impl Provider { + /// Sends a request based on the specified `EthAction` and parses the response. + /// + /// This function constructs a request targeting the Ethereum distribution system, serializes the provided `EthAction`, + /// and sends it. It awaits a response with a specified timeout, then attempts to parse the response into the expected + /// type `T`. This method is generic and can be used for various Ethereum actions by specifying the appropriate `EthAction` + /// and return type `T`. + pub fn send_request_and_parse_response( + &self, + action: EthAction, + ) -> anyhow::Result { + let resp = KiRequest::new() + .target(("our", "eth", "distro", "sys")) + .body(serde_json::to_vec(&action)?) + .send_and_await_response(self.request_timeout)??; + + match resp { + Message::Response { body, .. } => { + let response = serde_json::from_slice::(&body)?; + match response { + EthResponse::Response { value } => serde_json::from_value::(value) + .map_err(|e| anyhow::anyhow!("failed to parse response: {}", e)), + _ => Err(anyhow::anyhow!("unexpected response: {:?}", response)), + } } + _ => Err(anyhow::anyhow!("unexpected message type: {:?}", resp)), } - _ => Err(anyhow::anyhow!("unexpected message type: {:?}", resp)), } -} -/// Retrieves the current block number. -/// -/// # Returns -/// An `anyhow::Result` representing the current block number. -pub fn get_block_number(chain_id: u64) -> anyhow::Result { - let action = EthAction::Request { - chain_id, - method: "eth_blockNumber".to_string(), - params: ().into(), - }; - - let res = send_request_and_parse_response::(action)?; - Ok(res.to::()) -} + /// Retrieves the current block number. + /// + /// # Returns + /// An `anyhow::Result` representing the current block number. + pub fn get_block_number(&self) -> anyhow::Result { + let action = EthAction::Request { + chain_id: self.chain_id, + method: "eth_blockNumber".to_string(), + params: ().into(), + }; + + let res = self.send_request_and_parse_response::(action)?; + Ok(res.to::()) + } -/// Retrieves the balance of the given address at the specified block. -/// -/// # Parameters -/// - `address`: The address to query the balance for. -/// - `tag`: Optional block ID to specify the block at which the balance is queried. -/// -/// # Returns -/// An `anyhow::Result` representing the balance of the address. -pub fn get_balance(chain_id: u64, address: Address, tag: Option) -> anyhow::Result { - let params = serde_json::to_value(( - address, - tag.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest)), - ))?; - let action = EthAction::Request { - chain_id, - method: "eth_getBalance".to_string(), - params, - }; - - send_request_and_parse_response::(action) -} + /// Retrieves the balance of the given address at the specified block. + /// + /// # Parameters + /// - `address`: The address to query the balance for. + /// - `tag`: Optional block ID to specify the block at which the balance is queried. + /// + /// # Returns + /// An `anyhow::Result` representing the balance of the address. + pub fn get_balance(&self, address: Address, tag: Option) -> anyhow::Result { + let params = serde_json::to_value(( + address, + tag.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest)), + ))?; + let action = EthAction::Request { + chain_id: self.chain_id, + method: "eth_getBalance".to_string(), + params, + }; + + self.send_request_and_parse_response::(action) + } -/// Retrieves logs based on a filter. -/// -/// # Parameters -/// - `filter`: The filter criteria for the logs. -/// -/// # Returns -/// An `anyhow::Result>` containing the logs that match the filter. -pub fn get_logs(chain_id: u64, filter: &Filter) -> anyhow::Result> { - let action = EthAction::Request { - chain_id, - method: "eth_getLogs".to_string(), - params: serde_json::to_value((filter,))?, - }; - - send_request_and_parse_response::>(action) -} + /// Retrieves logs based on a filter. + /// + /// # Parameters + /// - `filter`: The filter criteria for the logs. + /// + /// # Returns + /// An `anyhow::Result>` containing the logs that match the filter. + pub fn get_logs(&self, filter: &Filter) -> anyhow::Result> { + let action = EthAction::Request { + chain_id: self.chain_id, + method: "eth_getLogs".to_string(), + params: serde_json::to_value(filter)?, + }; + + self.send_request_and_parse_response::>(action) + } -/// Retrieves the current gas price. -/// -/// # Returns -/// An `anyhow::Result` representing the current gas price. -pub fn get_gas_price(chain_id: u64) -> anyhow::Result { - let action = EthAction::Request { - chain_id, - method: "eth_gasPrice".to_string(), - params: ().into(), - }; - - send_request_and_parse_response::(action) -} + /// Retrieves the current gas price. + /// + /// # Returns + /// An `anyhow::Result` representing the current gas price. + pub fn get_gas_price(&self) -> anyhow::Result { + let action = EthAction::Request { + chain_id: self.chain_id, + method: "eth_gasPrice".to_string(), + params: ().into(), + }; + + self.send_request_and_parse_response::(action) + } -/// Retrieves the number of transactions sent from the given address. -/// -/// # Parameters -/// - `address`: The address to query the transaction count for. -/// - `tag`: Optional block ID to specify the block at which the count is queried. -/// -/// # Returns -/// An `anyhow::Result` representing the number of transactions sent from the address. -pub fn get_transaction_count( - chain_id: u64, - address: Address, - tag: Option, -) -> anyhow::Result { - let params = serde_json::to_value((address, tag.unwrap_or_default()))?; - let action = EthAction::Request { - chain_id, - method: "eth_getTransactionCount".to_string(), - params, - }; - - send_request_and_parse_response::(action) -} + /// Retrieves the number of transactions sent from the given address. + /// + /// # Parameters + /// - `address`: The address to query the transaction count for. + /// - `tag`: Optional block ID to specify the block at which the count is queried. + /// + /// # Returns + /// An `anyhow::Result` representing the number of transactions sent from the address. + pub fn get_transaction_count( + &self, + address: Address, + tag: Option, + ) -> anyhow::Result { + let params = serde_json::to_value((address, tag.unwrap_or_default()))?; + let action = EthAction::Request { + chain_id: self.chain_id, + method: "eth_getTransactionCount".to_string(), + params, + }; + + self.send_request_and_parse_response::(action) + } -/// Retrieves a block by its hash. -/// -/// # Parameters -/// - `hash`: The hash of the block to retrieve. -/// - `full_tx`: Whether to return full transaction objects or just their hashes. -/// -/// # Returns -/// An `anyhow::Result>` representing the block, if found. -pub fn get_block_by_hash( - chain_id: u64, - hash: BlockHash, - full_tx: bool, -) -> anyhow::Result> { - let params = serde_json::to_value((hash, full_tx))?; - let action = EthAction::Request { - chain_id, - method: "eth_getBlockByHash".to_string(), - params, - }; - - send_request_and_parse_response::>(action) -} -/// Retrieves a block by its number or tag. -/// -/// # Parameters -/// - `number`: The number or tag of the block to retrieve. -/// - `full_tx`: Whether to return full transaction objects or just their hashes. -/// -/// # Returns -/// An `anyhow::Result>` representing the block, if found. -pub fn get_block_by_number( - chain_id: u64, - number: BlockNumberOrTag, - full_tx: bool, -) -> anyhow::Result> { - let params = serde_json::to_value((number, full_tx))?; - let action = EthAction::Request { - chain_id, - method: "eth_getBlockByNumber".to_string(), - params, - }; - - send_request_and_parse_response::>(action) -} + /// Retrieves a block by its hash. + /// + /// # Parameters + /// - `hash`: The hash of the block to retrieve. + /// - `full_tx`: Whether to return full transaction objects or just their hashes. + /// + /// # Returns + /// An `anyhow::Result>` representing the block, if found. + pub fn get_block_by_hash( + &self, + hash: BlockHash, + full_tx: bool, + ) -> anyhow::Result> { + let params = serde_json::to_value((hash, full_tx))?; + let action = EthAction::Request { + chain_id: self.chain_id, + method: "eth_getBlockByHash".to_string(), + params, + }; + + self.send_request_and_parse_response::>(action) + } + /// Retrieves a block by its number or tag. + /// + /// # Parameters + /// - `number`: The number or tag of the block to retrieve. + /// - `full_tx`: Whether to return full transaction objects or just their hashes. + /// + /// # Returns + /// An `anyhow::Result>` representing the block, if found. + pub fn get_block_by_number( + &self, + number: BlockNumberOrTag, + full_tx: bool, + ) -> anyhow::Result> { + let params = serde_json::to_value((number, full_tx))?; + let action = EthAction::Request { + chain_id: self.chain_id, + method: "eth_getBlockByNumber".to_string(), + params, + }; + + self.send_request_and_parse_response::>(action) + } -/// Retrieves the storage at a given address and key. -/// -/// # Parameters -/// - `address`: The address of the storage to query. -/// - `key`: The key of the storage slot to retrieve. -/// - `tag`: Optional block ID to specify the block at which the storage is queried. -/// -/// # Returns -/// An `anyhow::Result` representing the data stored at the given address and key. -pub fn get_storage_at( - chain_id: u64, - address: Address, - key: U256, - tag: Option, -) -> anyhow::Result { - let params = serde_json::to_value((address, key, tag.unwrap_or_default()))?; - let action = EthAction::Request { - chain_id, - method: "eth_getStorageAt".to_string(), - params, - }; - - send_request_and_parse_response::(action) -} + /// Retrieves the storage at a given address and key. + /// + /// # Parameters + /// - `address`: The address of the storage to query. + /// - `key`: The key of the storage slot to retrieve. + /// - `tag`: Optional block ID to specify the block at which the storage is queried. + /// + /// # Returns + /// An `anyhow::Result` representing the data stored at the given address and key. + pub fn get_storage_at( + &self, + address: Address, + key: U256, + tag: Option, + ) -> anyhow::Result { + let params = serde_json::to_value((address, key, tag.unwrap_or_default()))?; + let action = EthAction::Request { + chain_id: self.chain_id, + method: "eth_getStorageAt".to_string(), + params, + }; + + self.send_request_and_parse_response::(action) + } -/// Retrieves the code at a given address. -/// -/// # Parameters -/// - `address`: The address of the code to query. -/// - `tag`: The block ID to specify the block at which the code is queried. -/// -/// # Returns -/// An `anyhow::Result` representing the code stored at the given address. -pub fn get_code_at(chain_id: u64, address: Address, tag: BlockId) -> anyhow::Result { - let params = serde_json::to_value((address, tag))?; - let action = EthAction::Request { - chain_id, - method: "eth_getCode".to_string(), - params, - }; - - send_request_and_parse_response::(action) -} + /// Retrieves the code at a given address. + /// + /// # Parameters + /// - `address`: The address of the code to query. + /// - `tag`: The block ID to specify the block at which the code is queried. + /// + /// # Returns + /// An `anyhow::Result` representing the code stored at the given address. + pub fn get_code_at(&self, address: Address, tag: BlockId) -> anyhow::Result { + let params = serde_json::to_value((address, tag))?; + let action = EthAction::Request { + chain_id: self.chain_id, + method: "eth_getCode".to_string(), + params, + }; + + self.send_request_and_parse_response::(action) + } -/// Retrieves a transaction by its hash. -/// -/// # Parameters -/// - `hash`: The hash of the transaction to retrieve. -/// -/// # Returns -/// An `anyhow::Result>` representing the transaction, if found. -pub fn get_transaction_by_hash(chain_id: u64, hash: TxHash) -> anyhow::Result> { - let params = serde_json::to_value((hash,))?; - let action = EthAction::Request { - chain_id, - method: "eth_getTransactionByHash".to_string(), - params, - }; - - send_request_and_parse_response::>(action) -} + /// Retrieves a transaction by its hash. + /// + /// # Parameters + /// - `hash`: The hash of the transaction to retrieve. + /// + /// # Returns + /// An `anyhow::Result>` representing the transaction, if found. + pub fn get_transaction_by_hash(&self, hash: TxHash) -> anyhow::Result> { + let params = serde_json::to_value(hash)?; + let action = EthAction::Request { + chain_id: self.chain_id, + method: "eth_getTransactionByHash".to_string(), + params, + }; + + self.send_request_and_parse_response::>(action) + } -/// Retrieves the receipt of a transaction by its hash. -/// -/// # Parameters -/// - `hash`: The hash of the transaction for which the receipt is requested. -/// -/// # Returns -/// An `anyhow::Result>` representing the transaction receipt, if found. -pub fn get_transaction_receipt( - chain_id: u64, - hash: TxHash, -) -> anyhow::Result> { - let params = serde_json::to_value((hash,))?; - let action = EthAction::Request { - chain_id, - method: "eth_getTransactionReceipt".to_string(), - params, - }; - - send_request_and_parse_response::>(action) -} + /// Retrieves the receipt of a transaction by its hash. + /// + /// # Parameters + /// - `hash`: The hash of the transaction for which the receipt is requested. + /// + /// # Returns + /// An `anyhow::Result>` representing the transaction receipt, if found. + pub fn get_transaction_receipt( + &self, + hash: TxHash, + ) -> anyhow::Result> { + let params = serde_json::to_value(hash)?; + let action = EthAction::Request { + chain_id: self.chain_id, + method: "eth_getTransactionReceipt".to_string(), + params, + }; + + self.send_request_and_parse_response::>(action) + } -/// Estimates the amount of gas that a transaction will consume. -/// -/// # Parameters -/// - `tx`: The transaction request object containing the details of the transaction to estimate gas for. -/// - `block`: Optional block ID to specify the block at which the gas estimate should be made. -/// -/// # Returns -/// An `anyhow::Result` representing the estimated gas amount. -pub fn estimate_gas( - chain_id: u64, - tx: TransactionRequest, - block: Option, -) -> anyhow::Result { - let params = serde_json::to_value((tx, block.unwrap_or_default()))?; - let action = EthAction::Request { - chain_id, - method: "eth_estimateGas".to_string(), - params, - }; - - send_request_and_parse_response::(action) -} + /// Estimates the amount of gas that a transaction will consume. + /// + /// # Parameters + /// - `tx`: The transaction request object containing the details of the transaction to estimate gas for. + /// - `block`: Optional block ID to specify the block at which the gas estimate should be made. + /// + /// # Returns + /// An `anyhow::Result` representing the estimated gas amount. + pub fn estimate_gas( + &self, + tx: TransactionRequest, + block: Option, + ) -> anyhow::Result { + let params = serde_json::to_value((tx, block.unwrap_or_default()))?; + let action = EthAction::Request { + chain_id: self.chain_id, + method: "eth_estimateGas".to_string(), + params, + }; + + self.send_request_and_parse_response::(action) + } -/// Retrieves the list of accounts controlled by the node. -/// -/// # Returns -/// An `anyhow::Result>` representing the list of accounts. -/// Note: This function may return an empty list depending on the node's configuration and capabilities. -pub fn get_accounts(chain_id: u64) -> anyhow::Result> { - let action = EthAction::Request { - chain_id, - method: "eth_accounts".to_string(), - params: serde_json::Value::Array(vec![]), - }; - - send_request_and_parse_response::>(action) -} + /// Retrieves the list of accounts controlled by the node. + /// + /// # Returns + /// An `anyhow::Result>` representing the list of accounts. + /// Note: This function may return an empty list depending on the node's configuration and capabilities. + pub fn get_accounts(&self) -> anyhow::Result> { + let action = EthAction::Request { + chain_id: self.chain_id, + method: "eth_accounts".to_string(), + params: serde_json::Value::Array(vec![]), + }; + + self.send_request_and_parse_response::>(action) + } -/// Retrieves the fee history for a given range of blocks. -/// -/// # Parameters -/// - `block_count`: The number of blocks to include in the history. -/// - `last_block`: The ending block number or tag for the history range. -/// - `reward_percentiles`: A list of percentiles to report fee rewards for. -/// -/// # Returns -/// An `anyhow::Result` representing the fee history for the specified range. -pub fn get_fee_history( - chain_id: u64, - block_count: U256, - last_block: BlockNumberOrTag, - reward_percentiles: Vec, -) -> anyhow::Result { - let params = serde_json::to_value((block_count, last_block, reward_percentiles))?; - let action = EthAction::Request { - chain_id, - method: "eth_feeHistory".to_string(), - params, - }; - - send_request_and_parse_response::(action) -} + /// Retrieves the fee history for a given range of blocks. + /// + /// # Parameters + /// - `block_count`: The number of blocks to include in the history. + /// - `last_block`: The ending block number or tag for the history range. + /// - `reward_percentiles`: A list of percentiles to report fee rewards for. + /// + /// # Returns + /// An `anyhow::Result` representing the fee history for the specified range. + pub fn get_fee_history( + &self, + block_count: U256, + last_block: BlockNumberOrTag, + reward_percentiles: Vec, + ) -> anyhow::Result { + let params = serde_json::to_value((block_count, last_block, reward_percentiles))?; + let action = EthAction::Request { + chain_id: self.chain_id, + method: "eth_feeHistory".to_string(), + params, + }; + + self.send_request_and_parse_response::(action) + } -/// Executes a call transaction, which is directly executed in the VM of the node, but never mined into the blockchain. -/// -/// # Parameters -/// - `tx`: The transaction request object containing the details of the call. -/// - `block`: Optional block ID to specify the block at which the call should be made. -/// -/// # Returns -/// An `anyhow::Result` representing the result of the call. -pub fn call( - chain_id: u64, - tx: TransactionRequest, - block: Option, -) -> anyhow::Result { - let params = serde_json::to_value((tx, block.unwrap_or_default()))?; - let action = EthAction::Request { - chain_id, - method: "eth_call".to_string(), - params, - }; - - send_request_and_parse_response::(action) -} + /// Executes a call transaction, which is directly executed in the VM of the node, but never mined into the blockchain. + /// + /// # Parameters + /// - `tx`: The transaction request object containing the details of the call. + /// - `block`: Optional block ID to specify the block at which the call should be made. + /// + /// # Returns + /// An `anyhow::Result` representing the result of the call. + pub fn call(&self, tx: TransactionRequest, block: Option) -> anyhow::Result { + let params = serde_json::to_value((tx, block.unwrap_or_default()))?; + let action = EthAction::Request { + chain_id: self.chain_id, + method: "eth_call".to_string(), + params, + }; + + self.send_request_and_parse_response::(action) + } -/// Sends a raw transaction to the network. -/// -/// # Parameters -/// - `tx`: The raw transaction data. -/// -/// # Returns -/// An `anyhow::Result` representing the hash of the transaction once it has been sent. -pub fn send_raw_transaction(chain_id: u64, tx: Bytes) -> anyhow::Result { - let action = EthAction::Request { - chain_id, - method: "eth_sendRawTransaction".to_string(), - params: serde_json::to_value((tx,))?, - }; - - send_request_and_parse_response::(action) -} + /// Sends a raw transaction to the network. + /// + /// # Parameters + /// - `tx`: The raw transaction data. + /// + /// # Returns + /// An `anyhow::Result` representing the hash of the transaction once it has been sent. + pub fn send_raw_transaction(&self, tx: Bytes) -> anyhow::Result { + let action = EthAction::Request { + chain_id: self.chain_id, + method: "eth_sendRawTransaction".to_string(), + params: serde_json::to_value(tx)?, + }; + + self.send_request_and_parse_response::(action) + } -/// Subscribes to logs without waiting for a confirmation. -/// -/// # Parameters -/// - `sub_id`: The subscription ID to be used for unsubscribing. -/// - `filter`: The filter criteria for the logs. -/// -/// # Returns -/// An `anyhow::Result<()>` indicating the operation was dispatched. -pub fn subscribe(sub_id: u64, chain_id: u64, filter: Filter) -> anyhow::Result<()> { - let action = EthAction::SubscribeLogs { - sub_id, - chain_id, - kind: SubscriptionKind::Logs, - params: Params::Logs(Box::new(filter)), - }; - - KiRequest::new() - .target(("our", "eth", "distro", "sys")) - .body(serde_json::to_vec(&action)?) - .send() -} + /// Subscribes to logs without waiting for a confirmation. + /// + /// # Parameters + /// - `sub_id`: The subscription ID to be used for unsubscribing. + /// - `filter`: The filter criteria for the logs. + /// + /// # Returns + /// An `anyhow::Result<()>` indicating whether the subscription was created. + pub fn subscribe(&self, sub_id: u64, filter: Filter) -> anyhow::Result<()> { + let action = EthAction::SubscribeLogs { + sub_id, + chain_id: self.chain_id, + kind: SubscriptionKind::Logs, + params: Params::Logs(Box::new(filter)), + }; + + let resp = KiRequest::new() + .target(("our", "eth", "distro", "sys")) + .body(serde_json::to_vec(&action)?) + .send_and_await_response(self.request_timeout)??; + + match resp { + Message::Response { body, .. } => { + let response = serde_json::from_slice::(&body)?; + match response { + EthResponse::Ok => Ok(()), + EthResponse::Response { .. } => { + Err(anyhow::anyhow!("unexpected response: {:?}", response)) + } + EthResponse::Err(e) => Err(anyhow::anyhow!("{e:?}")), + } + } + _ => Err(anyhow::anyhow!("unexpected message type: {:?}", resp)), + } + } -/// Unsubscribes from a previously created subscription. -/// -/// # Parameters -/// - `sub_id`: The subscription ID to unsubscribe from. -/// -/// # Returns -/// An `anyhow::Result<()>` indicating the success or failure of the unsubscription request. -pub fn unsubscribe(sub_id: u64) -> anyhow::Result<()> { - let action = EthAction::UnsubscribeLogs(sub_id); - - KiRequest::new() - .target(("our", "eth", "distro", "sys")) - .body(serde_json::to_vec(&action)?) - .send() + /// Unsubscribes from a previously created subscription. + /// + /// # Parameters + /// - `sub_id`: The subscription ID to unsubscribe from. + /// + /// # Returns + /// An `anyhow::Result<()>` indicating whether the subscription was cancelled. + pub fn unsubscribe(&self, sub_id: u64) -> anyhow::Result<()> { + let action = EthAction::UnsubscribeLogs(sub_id); + + let resp = KiRequest::new() + .target(("our", "eth", "distro", "sys")) + .body(serde_json::to_vec(&action)?) + .send_and_await_response(self.request_timeout)??; + + match resp { + Message::Response { body, .. } => { + let response = serde_json::from_slice::(&body)?; + match response { + EthResponse::Ok => Ok(()), + EthResponse::Response { .. } => { + Err(anyhow::anyhow!("unexpected response: {:?}", response)) + } + EthResponse::Err(e) => Err(anyhow::anyhow!("{e:?}")), + } + } + _ => Err(anyhow::anyhow!("unexpected message type: {:?}", resp)), + } + } } From 75282adbb8a9c52e8d9ae8079a23cbf671edc157 Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Thu, 22 Feb 2024 18:57:11 -0300 Subject: [PATCH 24/36] vfs: timeout options --- src/vfs/directory.rs | 8 ++++++-- src/vfs/file.rs | 33 +++++++++++++++++++-------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/vfs/directory.rs b/src/vfs/directory.rs index 31fb296..09c8d26 100644 --- a/src/vfs/directory.rs +++ b/src/vfs/directory.rs @@ -6,6 +6,7 @@ use crate::{Message, Request}; /// You can call it's impl functions to interact with it. pub struct Directory { pub path: String, + pub timeout: u64, } impl Directory { @@ -37,10 +38,12 @@ impl Directory { /// Opens or creates a directory at path. /// If trying to create an existing directory, will just give you the path. -pub fn open_dir(path: &str, create: bool) -> anyhow::Result { +pub fn open_dir(path: &str, create: bool, timeout: Option) -> anyhow::Result { + let timeout = timeout.unwrap_or(5); if !create { return Ok(Directory { path: path.to_string(), + timeout, }); } let request = VfsRequest { @@ -51,7 +54,7 @@ pub fn open_dir(path: &str, create: bool) -> anyhow::Result { let message = Request::new() .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) - .send_and_await_response(5)?; + .send_and_await_response(timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -59,6 +62,7 @@ pub fn open_dir(path: &str, create: bool) -> anyhow::Result { match response { VfsResponse::Ok => Ok(Directory { path: path.to_string(), + timeout, }), VfsResponse::Err(e) => Err(e.into()), _ => Err(anyhow::anyhow!("vfs: unexpected response: {:?}", response)), diff --git a/src/vfs/file.rs b/src/vfs/file.rs index ef46345..0ddf25c 100644 --- a/src/vfs/file.rs +++ b/src/vfs/file.rs @@ -6,6 +6,7 @@ use crate::{get_blob, Message, PackageId, Request}; /// You can call it's impl functions to interact with it. pub struct File { pub path: String, + pub timeout: u64, } impl File { @@ -19,7 +20,7 @@ impl File { let message = Request::new() .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -50,7 +51,7 @@ impl File { let message = Request::new() .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -84,7 +85,7 @@ impl File { let message = Request::new() .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -117,7 +118,7 @@ impl File { let message = Request::new() .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -149,7 +150,7 @@ impl File { let message = Request::new() .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -176,7 +177,7 @@ impl File { .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) .blob_bytes(buffer) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -201,7 +202,7 @@ impl File { .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) .blob_bytes(buffer) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -226,7 +227,7 @@ impl File { .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) .blob_bytes(buffer) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -251,7 +252,7 @@ impl File { let message = Request::new() .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -286,6 +287,7 @@ impl File { match response { VfsResponse::Ok => Ok(File { path: path.to_string(), + timeout: self.timeout, }), VfsResponse::Err(e) => Err(e.into()), _ => Err(anyhow::anyhow!("vfs: unexpected response: {:?}", response)), @@ -304,7 +306,7 @@ impl File { let message = Request::new() .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -328,7 +330,7 @@ impl File { let message = Request::new() .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -352,7 +354,7 @@ impl File { let message = Request::new() .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -412,6 +414,7 @@ pub fn open_file(path: &str, create: bool) -> anyhow::Result { match response { VfsResponse::Ok => Ok(File { path: path.to_string(), + timeout: 5, }), VfsResponse::Err(e) => Err(e.into()), _ => Err(anyhow::anyhow!("vfs: unexpected response: {:?}", response)), @@ -422,7 +425,8 @@ pub fn open_file(path: &str, create: bool) -> anyhow::Result { } /// Creates a file at path, if file found at path, truncates it to 0. -pub fn create_file(path: &str) -> anyhow::Result { +pub fn create_file(path: &str, timeout: Option) -> anyhow::Result { + let timeout = timeout.unwrap_or(5); let request = VfsRequest { path: path.to_string(), action: VfsAction::CreateFile, @@ -431,7 +435,7 @@ pub fn create_file(path: &str) -> anyhow::Result { let message = Request::new() .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) - .send_and_await_response(5)?; + .send_and_await_response(timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -439,6 +443,7 @@ pub fn create_file(path: &str) -> anyhow::Result { match response { VfsResponse::Ok => Ok(File { path: path.to_string(), + timeout, }), VfsResponse::Err(e) => Err(e.into()), _ => Err(anyhow::anyhow!("vfs: unexpected response: {:?}", response)), From 8e4d015404c3803981b05d2e64e3e100c5b782fc Mon Sep 17 00:00:00 2001 From: dr-frmr Date: Thu, 22 Feb 2024 19:03:45 -0300 Subject: [PATCH 25/36] add provider::new() --- src/eth.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/eth.rs b/src/eth.rs index 4fea29e..fa5f4f7 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -147,6 +147,13 @@ pub struct Provider { } impl Provider { + /// Instantiate a new provider. + pub fn new(chain_id: u64, request_timeout: u64) -> Self { + Self { + chain_id, + request_timeout, + } + } /// Sends a request based on the specified `EthAction` and parses the response. /// /// This function constructs a request targeting the Ethereum distribution system, serializes the provided `EthAction`, From 567ba7830ba387625e668c61f252f98ff849d6eb Mon Sep 17 00:00:00 2001 From: dr-frmr Date: Fri, 23 Feb 2024 20:25:36 -0300 Subject: [PATCH 26/36] eth: add `EthError` variants, make all fns return EthError instead of anyhow --- src/eth.rs | 165 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 100 insertions(+), 65 deletions(-) diff --git a/src/eth.rs b/src/eth.rs index fa5f4f7..2796428 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -53,7 +53,7 @@ pub struct EthSubError { } /// The Response type which a process will get from requesting with an [`EthAction`] will be -/// of the form `Result<(), EthError>`, serialized and deserialized using `serde_json::to_vec` +/// of this type, serialized and deserialized using `serde_json::to_vec` /// and `serde_json::from_slice`. #[derive(Debug, Serialize, Deserialize)] pub enum EthResponse { @@ -74,10 +74,14 @@ pub enum EthError { SubscriptionNotFound, /// Invalid method InvalidMethod(String), + /// Invalid params + InvalidParams, /// Permission denied PermissionDenied, /// Internal RPC error RpcError(String), + /// RPC timed out + RpcTimeout, } /// The action type used for configuring eth:distro:sys. Only processes which have the "root" @@ -163,30 +167,33 @@ impl Provider { pub fn send_request_and_parse_response( &self, action: EthAction, - ) -> anyhow::Result { + ) -> Result { let resp = KiRequest::new() .target(("our", "eth", "distro", "sys")) - .body(serde_json::to_vec(&action)?) - .send_and_await_response(self.request_timeout)??; + .body(serde_json::to_vec(&action).unwrap()) + .send_and_await_response(self.request_timeout) + .unwrap() + .map_err(|_| EthError::RpcTimeout)?; match resp { Message::Response { body, .. } => { - let response = serde_json::from_slice::(&body)?; + let response = serde_json::from_slice::(&body); match response { - EthResponse::Response { value } => serde_json::from_value::(value) - .map_err(|e| anyhow::anyhow!("failed to parse response: {}", e)), - _ => Err(anyhow::anyhow!("unexpected response: {:?}", response)), + Ok(EthResponse::Response { value }) => serde_json::from_value::(value) + .map_err(|e| EthError::RpcError(format!("{e:?}"))), + Ok(EthResponse::Err(e)) => Err(e), + _ => Err(EthError::RpcError("unexpected response".to_string())), } } - _ => Err(anyhow::anyhow!("unexpected message type: {:?}", resp)), + _ => Err(EthError::RpcError("unexpected response".to_string())), } } /// Retrieves the current block number. /// /// # Returns - /// An `anyhow::Result` representing the current block number. - pub fn get_block_number(&self) -> anyhow::Result { + /// A `Result` representing the current block number. + pub fn get_block_number(&self) -> Result { let action = EthAction::Request { chain_id: self.chain_id, method: "eth_blockNumber".to_string(), @@ -204,12 +211,13 @@ impl Provider { /// - `tag`: Optional block ID to specify the block at which the balance is queried. /// /// # Returns - /// An `anyhow::Result` representing the balance of the address. - pub fn get_balance(&self, address: Address, tag: Option) -> anyhow::Result { + /// A `Result` representing the balance of the address. + pub fn get_balance(&self, address: Address, tag: Option) -> Result { let params = serde_json::to_value(( address, tag.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest)), - ))?; + )) + .unwrap(); let action = EthAction::Request { chain_id: self.chain_id, method: "eth_getBalance".to_string(), @@ -225,12 +233,15 @@ impl Provider { /// - `filter`: The filter criteria for the logs. /// /// # Returns - /// An `anyhow::Result>` containing the logs that match the filter. - pub fn get_logs(&self, filter: &Filter) -> anyhow::Result> { + /// A `Result, EthError>` containing the logs that match the filter. + pub fn get_logs(&self, filter: &Filter) -> Result, EthError> { + let Ok(params) = serde_json::to_value(filter) else { + return Err(EthError::InvalidParams); + }; let action = EthAction::Request { chain_id: self.chain_id, method: "eth_getLogs".to_string(), - params: serde_json::to_value(filter)?, + params, }; self.send_request_and_parse_response::>(action) @@ -239,8 +250,8 @@ impl Provider { /// Retrieves the current gas price. /// /// # Returns - /// An `anyhow::Result` representing the current gas price. - pub fn get_gas_price(&self) -> anyhow::Result { + /// A `Result` representing the current gas price. + pub fn get_gas_price(&self) -> Result { let action = EthAction::Request { chain_id: self.chain_id, method: "eth_gasPrice".to_string(), @@ -257,13 +268,15 @@ impl Provider { /// - `tag`: Optional block ID to specify the block at which the count is queried. /// /// # Returns - /// An `anyhow::Result` representing the number of transactions sent from the address. + /// A `Result` representing the number of transactions sent from the address. pub fn get_transaction_count( &self, address: Address, tag: Option, - ) -> anyhow::Result { - let params = serde_json::to_value((address, tag.unwrap_or_default()))?; + ) -> Result { + let Ok(params) = serde_json::to_value((address, tag.unwrap_or_default())) else { + return Err(EthError::InvalidParams); + }; let action = EthAction::Request { chain_id: self.chain_id, method: "eth_getTransactionCount".to_string(), @@ -280,13 +293,15 @@ impl Provider { /// - `full_tx`: Whether to return full transaction objects or just their hashes. /// /// # Returns - /// An `anyhow::Result>` representing the block, if found. + /// A `Result, EthError>` representing the block, if found. pub fn get_block_by_hash( &self, hash: BlockHash, full_tx: bool, - ) -> anyhow::Result> { - let params = serde_json::to_value((hash, full_tx))?; + ) -> Result, EthError> { + let Ok(params) = serde_json::to_value((hash, full_tx)) else { + return Err(EthError::InvalidParams); + }; let action = EthAction::Request { chain_id: self.chain_id, method: "eth_getBlockByHash".to_string(), @@ -302,13 +317,15 @@ impl Provider { /// - `full_tx`: Whether to return full transaction objects or just their hashes. /// /// # Returns - /// An `anyhow::Result>` representing the block, if found. + /// A `Result, EthError>` representing the block, if found. pub fn get_block_by_number( &self, number: BlockNumberOrTag, full_tx: bool, - ) -> anyhow::Result> { - let params = serde_json::to_value((number, full_tx))?; + ) -> Result, EthError> { + let Ok(params) = serde_json::to_value((number, full_tx)) else { + return Err(EthError::InvalidParams); + }; let action = EthAction::Request { chain_id: self.chain_id, method: "eth_getBlockByNumber".to_string(), @@ -326,14 +343,16 @@ impl Provider { /// - `tag`: Optional block ID to specify the block at which the storage is queried. /// /// # Returns - /// An `anyhow::Result` representing the data stored at the given address and key. + /// A `Result` representing the data stored at the given address and key. pub fn get_storage_at( &self, address: Address, key: U256, tag: Option, - ) -> anyhow::Result { - let params = serde_json::to_value((address, key, tag.unwrap_or_default()))?; + ) -> Result { + let Ok(params) = serde_json::to_value((address, key, tag.unwrap_or_default())) else { + return Err(EthError::InvalidParams); + }; let action = EthAction::Request { chain_id: self.chain_id, method: "eth_getStorageAt".to_string(), @@ -350,9 +369,11 @@ impl Provider { /// - `tag`: The block ID to specify the block at which the code is queried. /// /// # Returns - /// An `anyhow::Result` representing the code stored at the given address. - pub fn get_code_at(&self, address: Address, tag: BlockId) -> anyhow::Result { - let params = serde_json::to_value((address, tag))?; + /// A `Result` representing the code stored at the given address. + pub fn get_code_at(&self, address: Address, tag: BlockId) -> Result { + let Ok(params) = serde_json::to_value((address, tag)) else { + return Err(EthError::InvalidParams); + }; let action = EthAction::Request { chain_id: self.chain_id, method: "eth_getCode".to_string(), @@ -368,9 +389,11 @@ impl Provider { /// - `hash`: The hash of the transaction to retrieve. /// /// # Returns - /// An `anyhow::Result>` representing the transaction, if found. - pub fn get_transaction_by_hash(&self, hash: TxHash) -> anyhow::Result> { - let params = serde_json::to_value(hash)?; + /// A `Result, EthError>` representing the transaction, if found. + pub fn get_transaction_by_hash(&self, hash: TxHash) -> Result, EthError> { + let Ok(params) = serde_json::to_value(hash) else { + return Err(EthError::InvalidParams); + }; let action = EthAction::Request { chain_id: self.chain_id, method: "eth_getTransactionByHash".to_string(), @@ -386,12 +409,14 @@ impl Provider { /// - `hash`: The hash of the transaction for which the receipt is requested. /// /// # Returns - /// An `anyhow::Result>` representing the transaction receipt, if found. + /// A `Result, EthError>` representing the transaction receipt, if found. pub fn get_transaction_receipt( &self, hash: TxHash, - ) -> anyhow::Result> { - let params = serde_json::to_value(hash)?; + ) -> Result, EthError> { + let Ok(params) = serde_json::to_value(hash) else { + return Err(EthError::InvalidParams); + }; let action = EthAction::Request { chain_id: self.chain_id, method: "eth_getTransactionReceipt".to_string(), @@ -408,13 +433,15 @@ impl Provider { /// - `block`: Optional block ID to specify the block at which the gas estimate should be made. /// /// # Returns - /// An `anyhow::Result` representing the estimated gas amount. + /// A `Result` representing the estimated gas amount. pub fn estimate_gas( &self, tx: TransactionRequest, block: Option, - ) -> anyhow::Result { - let params = serde_json::to_value((tx, block.unwrap_or_default()))?; + ) -> Result { + let Ok(params) = serde_json::to_value((tx, block.unwrap_or_default())) else { + return Err(EthError::InvalidParams); + }; let action = EthAction::Request { chain_id: self.chain_id, method: "eth_estimateGas".to_string(), @@ -427,9 +454,9 @@ impl Provider { /// Retrieves the list of accounts controlled by the node. /// /// # Returns - /// An `anyhow::Result>` representing the list of accounts. + /// A `Result, EthError>` representing the list of accounts. /// Note: This function may return an empty list depending on the node's configuration and capabilities. - pub fn get_accounts(&self) -> anyhow::Result> { + pub fn get_accounts(&self) -> Result, EthError> { let action = EthAction::Request { chain_id: self.chain_id, method: "eth_accounts".to_string(), @@ -447,14 +474,16 @@ impl Provider { /// - `reward_percentiles`: A list of percentiles to report fee rewards for. /// /// # Returns - /// An `anyhow::Result` representing the fee history for the specified range. + /// A `Result` representing the fee history for the specified range. pub fn get_fee_history( &self, block_count: U256, last_block: BlockNumberOrTag, reward_percentiles: Vec, - ) -> anyhow::Result { - let params = serde_json::to_value((block_count, last_block, reward_percentiles))?; + ) -> Result { + let Ok(params) = serde_json::to_value((block_count, last_block, reward_percentiles)) else { + return Err(EthError::InvalidParams); + }; let action = EthAction::Request { chain_id: self.chain_id, method: "eth_feeHistory".to_string(), @@ -471,9 +500,11 @@ impl Provider { /// - `block`: Optional block ID to specify the block at which the call should be made. /// /// # Returns - /// An `anyhow::Result` representing the result of the call. - pub fn call(&self, tx: TransactionRequest, block: Option) -> anyhow::Result { - let params = serde_json::to_value((tx, block.unwrap_or_default()))?; + /// A `Result` representing the result of the call. + pub fn call(&self, tx: TransactionRequest, block: Option) -> Result { + let Ok(params) = serde_json::to_value((tx, block.unwrap_or_default())) else { + return Err(EthError::InvalidParams); + }; let action = EthAction::Request { chain_id: self.chain_id, method: "eth_call".to_string(), @@ -489,12 +520,12 @@ impl Provider { /// - `tx`: The raw transaction data. /// /// # Returns - /// An `anyhow::Result` representing the hash of the transaction once it has been sent. - pub fn send_raw_transaction(&self, tx: Bytes) -> anyhow::Result { + /// A `Result` representing the hash of the transaction once it has been sent. + pub fn send_raw_transaction(&self, tx: Bytes) -> Result { let action = EthAction::Request { chain_id: self.chain_id, method: "eth_sendRawTransaction".to_string(), - params: serde_json::to_value(tx)?, + params: serde_json::to_value(tx).unwrap(), }; self.send_request_and_parse_response::(action) @@ -507,8 +538,8 @@ impl Provider { /// - `filter`: The filter criteria for the logs. /// /// # Returns - /// An `anyhow::Result<()>` indicating whether the subscription was created. - pub fn subscribe(&self, sub_id: u64, filter: Filter) -> anyhow::Result<()> { + /// A `Result<(), EthError>` indicating whether the subscription was created. + pub fn subscribe(&self, sub_id: u64, filter: Filter) -> Result<(), EthError> { let action = EthAction::SubscribeLogs { sub_id, chain_id: self.chain_id, @@ -516,23 +547,27 @@ impl Provider { params: Params::Logs(Box::new(filter)), }; + let Ok(body) = serde_json::to_vec(&action) else { + return Err(EthError::InvalidParams); + }; + let resp = KiRequest::new() .target(("our", "eth", "distro", "sys")) - .body(serde_json::to_vec(&action)?) - .send_and_await_response(self.request_timeout)??; + .body(body) + .send_and_await_response(self.request_timeout) + .unwrap() + .map_err(|_| EthError::RpcTimeout)?; match resp { Message::Response { body, .. } => { - let response = serde_json::from_slice::(&body)?; + let response = serde_json::from_slice::(&body); match response { - EthResponse::Ok => Ok(()), - EthResponse::Response { .. } => { - Err(anyhow::anyhow!("unexpected response: {:?}", response)) - } - EthResponse::Err(e) => Err(anyhow::anyhow!("{e:?}")), + Ok(EthResponse::Ok) => Ok(()), + Ok(EthResponse::Err(e)) => Err(e), + _ => Err(EthError::RpcError("unexpected response".to_string())), } } - _ => Err(anyhow::anyhow!("unexpected message type: {:?}", resp)), + _ => Err(EthError::RpcError("unexpected response".to_string())), } } From d1c29c20ab7be0e1cf98ee96711b719e147cfc56 Mon Sep 17 00:00:00 2001 From: dr-frmr Date: Mon, 26 Feb 2024 02:04:29 -0300 Subject: [PATCH 27/36] fix: add magic tuples, update alloy versions --- Cargo.lock | 33 ++++++++++++++++++++++++++++----- Cargo.toml | 8 ++++---- src/eth.rs | 12 ++++++++---- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 60c0706..060b678 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,7 +20,7 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "alloy-json-rpc" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git?rev=098ad56#098ad5657d55bbc5fe9469ede2a9ca79def738f2" +source = "git+https://github.com/alloy-rs/alloy.git?rev=6f8ebb4#6f8ebb45afca1a201a11d421ec46db0f7a1d8d08" dependencies = [ "alloy-primitives", "serde", @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4b6fb2b432ff223d513db7f908937f63c252bee0af9b82bfd25b0a5dd1eb0d8" +checksum = "ef197eb250c64962003cb08b90b17f0882c192f4a6f2f544809d424fd7cb0e7d" dependencies = [ "alloy-rlp", "bytes", @@ -75,7 +75,7 @@ dependencies = [ [[package]] name = "alloy-rpc-types" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git?rev=098ad56#098ad5657d55bbc5fe9469ede2a9ca79def738f2" +source = "git+https://github.com/alloy-rs/alloy.git?rev=6f8ebb4#6f8ebb45afca1a201a11d421ec46db0f7a1d8d08" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -88,10 +88,11 @@ dependencies = [ [[package]] name = "alloy-transport" version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git?rev=098ad56#098ad5657d55bbc5fe9469ede2a9ca79def738f2" +source = "git+https://github.com/alloy-rs/alloy.git?rev=6f8ebb4#6f8ebb45afca1a201a11d421ec46db0f7a1d8d08" dependencies = [ "alloy-json-rpc", "base64", + "futures-util", "serde", "serde_json", "thiserror", @@ -618,6 +619,17 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "futures-task" version = "0.3.30" @@ -631,9 +643,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", + "futures-macro", "futures-task", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -1386,6 +1400,15 @@ dependencies = [ "rand_core", ] +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" version = "1.13.1" diff --git a/Cargo.toml b/Cargo.toml index 2a8a97f..ed4c7e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,10 +8,10 @@ homepage = "https://kinode.org" repository = "https://github.com/kinode-dao/process_lib" [dependencies] -alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "098ad56" } -alloy-primitives = "0.6.2" -alloy-transport = { git = "https://github.com/alloy-rs/alloy.git", rev = "098ad56" } -alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy.git", rev = "098ad56" } +alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "6f8ebb4" } +alloy-primitives = "0.6.3" +alloy-transport = { git = "https://github.com/alloy-rs/alloy.git", rev = "6f8ebb4" } +alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy.git", rev = "6f8ebb4" } anyhow = "1.0" bincode = "1.3.3" http = "1.0.0" diff --git a/src/eth.rs b/src/eth.rs index 2796428..8d9ddd9 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -235,7 +235,8 @@ impl Provider { /// # Returns /// A `Result, EthError>` containing the logs that match the filter. pub fn get_logs(&self, filter: &Filter) -> Result, EthError> { - let Ok(params) = serde_json::to_value(filter) else { + // NOTE: filter must be encased by a tuple to be serialized correctly + let Ok(params) = serde_json::to_value((filter,)) else { return Err(EthError::InvalidParams); }; let action = EthAction::Request { @@ -391,7 +392,8 @@ impl Provider { /// # Returns /// A `Result, EthError>` representing the transaction, if found. pub fn get_transaction_by_hash(&self, hash: TxHash) -> Result, EthError> { - let Ok(params) = serde_json::to_value(hash) else { + // NOTE: hash must be encased by a tuple to be serialized correctly + let Ok(params) = serde_json::to_value((hash,)) else { return Err(EthError::InvalidParams); }; let action = EthAction::Request { @@ -414,7 +416,8 @@ impl Provider { &self, hash: TxHash, ) -> Result, EthError> { - let Ok(params) = serde_json::to_value(hash) else { + // NOTE: hash must be encased by a tuple to be serialized correctly + let Ok(params) = serde_json::to_value((hash,)) else { return Err(EthError::InvalidParams); }; let action = EthAction::Request { @@ -525,7 +528,8 @@ impl Provider { let action = EthAction::Request { chain_id: self.chain_id, method: "eth_sendRawTransaction".to_string(), - params: serde_json::to_value(tx).unwrap(), + // NOTE: tx must be encased by a tuple to be serialized correctly + params: serde_json::to_value((tx,)).unwrap(), }; self.send_request_and_parse_response::(action) From bc24fd0ad76d133d694605a89b6cf65138e58500 Mon Sep 17 00:00:00 2001 From: dr-frmr Date: Mon, 26 Feb 2024 17:29:39 -0300 Subject: [PATCH 28/36] eth error refactor out unused --- src/eth.rs | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/src/eth.rs b/src/eth.rs index 8d9ddd9..035de5c 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -7,6 +7,11 @@ pub use alloy_rpc_types::{ TransactionReceipt, }; use serde::{Deserialize, Serialize}; +use std::collections::HashSet; + +// +// types mirrored from runtime module +// /// The Action and Request type that can be made to eth:distro:sys. Any process with messaging /// capabilities can send this action to the eth provider. @@ -32,13 +37,13 @@ pub enum EthAction { }, } -/// Incoming Result type for subscription updates or errors that processes will receive. +/// Incoming `Request` containing subscription updates or errors that processes will receive. /// Can deserialize all incoming requests from eth:distro:sys to this type. /// /// Will be serialized and deserialized using `serde_json::to_vec` and `serde_json::from_slice`. pub type EthSubResult = Result; -/// Incoming Request type for successful subscription updates. +/// Incoming type for successful subscription updates. #[derive(Debug, Serialize, Deserialize)] pub struct EthSub { pub id: u64, @@ -55,6 +60,9 @@ pub struct EthSubError { /// The Response type which a process will get from requesting with an [`EthAction`] will be /// of this type, serialized and deserialized using `serde_json::to_vec` /// and `serde_json::from_slice`. +/// +/// In the case of an [`EthAction::SubscribeLogs`] request, the response will indicate if +/// the subscription was successfully created or not. #[derive(Debug, Serialize, Deserialize)] pub enum EthResponse { Ok, @@ -64,22 +72,16 @@ pub enum EthResponse { #[derive(Debug, Serialize, Deserialize)] pub enum EthError { + /// provider module cannot parse message + MalformedRequest, /// No RPC provider for the chain NoRpcForChain, - /// Underlying transport error - TransportError(String), /// Subscription closed SubscriptionClosed(u64), - /// The subscription ID was not found, so we couldn't unsubscribe. - SubscriptionNotFound, /// Invalid method InvalidMethod(String), - /// Invalid params - InvalidParams, /// Permission denied PermissionDenied, - /// Internal RPC error - RpcError(String), /// RPC timed out RpcTimeout, } @@ -111,8 +113,10 @@ pub enum EthConfigAction { /// Set the list of providers to a new list. /// Replaces all existing saved provider configs. SetProviders(SavedConfigs), - /// Get the list of as a [`SavedConfigs`] object. + /// Get the list of current providers as a [`SavedConfigs`] object. GetProviders, + /// Get the current access settings. + GetAccessSettings, } /// Response type from an [`EthConfigAction`] request. @@ -120,11 +124,23 @@ pub enum EthConfigAction { pub enum EthConfigResponse { Ok, /// Response from a GetProviders request. + /// Note the [`crate::kernel_types::KnsUpdate`] will only have the correct `name` field. + /// The rest of the Update is not saved in this module. Providers(SavedConfigs), + /// Response from a GetAccessSettings request. + AccessSettings(AccessSettings), /// Permission denied due to missing capability PermissionDenied, } +/// Settings for our ETH provider +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct AccessSettings { + pub public: bool, // whether or not other nodes can access through us + pub allow: HashSet, // whitelist for access (only used if public == false) + pub deny: HashSet, // blacklist for access (always used) +} + pub type SavedConfigs = Vec; /// Provider config. Can currently be a node or a ws provider instance. @@ -141,6 +157,15 @@ pub enum NodeOrRpcUrl { RpcUrl(String), } +impl std::cmp::PartialEq for NodeOrRpcUrl { + fn eq(&self, other: &str) -> bool { + match self { + NodeOrRpcUrl::Node(kns) => kns.name == other, + NodeOrRpcUrl::RpcUrl(url) => url == other, + } + } +} + /// An EVM chain provider. Create this object to start making RPC calls. /// Set the chain_id to determine which chain to call: requests will fail /// unless the node this process is running on has access to a provider From 9838f5d1cb0b2b6d63ad4d82c9628ff3e8d33dff Mon Sep 17 00:00:00 2001 From: dr-frmr Date: Mon, 26 Feb 2024 17:41:26 -0300 Subject: [PATCH 29/36] re-add missing errors --- src/eth.rs | 50 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/src/eth.rs b/src/eth.rs index 035de5c..62ad109 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -80,10 +80,14 @@ pub enum EthError { SubscriptionClosed(u64), /// Invalid method InvalidMethod(String), + /// Invalid parameters + InvalidParams, /// Permission denied PermissionDenied, /// RPC timed out RpcTimeout, + /// RPC gave garbage back + RpcMalformedResponse, } /// The action type used for configuring eth:distro:sys. Only processes which have the "root" @@ -201,16 +205,14 @@ impl Provider { .map_err(|_| EthError::RpcTimeout)?; match resp { - Message::Response { body, .. } => { - let response = serde_json::from_slice::(&body); - match response { - Ok(EthResponse::Response { value }) => serde_json::from_value::(value) - .map_err(|e| EthError::RpcError(format!("{e:?}"))), - Ok(EthResponse::Err(e)) => Err(e), - _ => Err(EthError::RpcError("unexpected response".to_string())), + Message::Response { body, .. } => match serde_json::from_slice::(&body) { + Ok(EthResponse::Response { value }) => { + serde_json::from_value::(value).map_err(|_| EthError::RpcMalformedResponse) } - } - _ => Err(EthError::RpcError("unexpected response".to_string())), + Ok(EthResponse::Err(e)) => Err(e), + _ => Err(EthError::RpcMalformedResponse), + }, + _ => Err(EthError::RpcMalformedResponse), } } @@ -593,10 +595,10 @@ impl Provider { match response { Ok(EthResponse::Ok) => Ok(()), Ok(EthResponse::Err(e)) => Err(e), - _ => Err(EthError::RpcError("unexpected response".to_string())), + _ => Err(EthError::RpcMalformedResponse), } } - _ => Err(EthError::RpcError("unexpected response".to_string())), + _ => Err(EthError::RpcMalformedResponse), } } @@ -606,27 +608,23 @@ impl Provider { /// - `sub_id`: The subscription ID to unsubscribe from. /// /// # Returns - /// An `anyhow::Result<()>` indicating whether the subscription was cancelled. - pub fn unsubscribe(&self, sub_id: u64) -> anyhow::Result<()> { + /// A `Result<(), EthError>` indicating whether the subscription was cancelled. + pub fn unsubscribe(&self, sub_id: u64) -> Result<(), EthError> { let action = EthAction::UnsubscribeLogs(sub_id); let resp = KiRequest::new() .target(("our", "eth", "distro", "sys")) - .body(serde_json::to_vec(&action)?) - .send_and_await_response(self.request_timeout)??; + .body(serde_json::to_vec(&action).map_err(|_| EthError::MalformedRequest)?) + .send_and_await_response(self.request_timeout) + .unwrap() + .map_err(|_| EthError::RpcTimeout)?; match resp { - Message::Response { body, .. } => { - let response = serde_json::from_slice::(&body)?; - match response { - EthResponse::Ok => Ok(()), - EthResponse::Response { .. } => { - Err(anyhow::anyhow!("unexpected response: {:?}", response)) - } - EthResponse::Err(e) => Err(anyhow::anyhow!("{e:?}")), - } - } - _ => Err(anyhow::anyhow!("unexpected message type: {:?}", resp)), + Message::Response { body, .. } => match serde_json::from_slice::(&body) { + Ok(EthResponse::Ok) => Ok(()), + _ => Err(EthError::RpcMalformedResponse), + }, + _ => Err(EthError::RpcMalformedResponse), } } } From 03d3fc19dbfabe52413ec50a4b1a493f6bcf1d2d Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Fri, 1 Mar 2024 13:56:00 -0300 Subject: [PATCH 30/36] add timeouts to helper functions too --- src/vfs/directory.rs | 8 +++++--- src/vfs/file.rs | 24 +++++++++++++++++------- src/vfs/mod.rs | 14 ++++++++------ 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/vfs/directory.rs b/src/vfs/directory.rs index 09c8d26..6cc8154 100644 --- a/src/vfs/directory.rs +++ b/src/vfs/directory.rs @@ -20,7 +20,7 @@ impl Directory { let message = Request::new() .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) - .send_and_await_response(5)?; + .send_and_await_response(self.timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -73,7 +73,9 @@ pub fn open_dir(path: &str, create: bool, timeout: Option) -> anyhow::Resul } /// Removes a dir at path, errors if path not found or path is not a directory. -pub fn remove_dir(path: &str) -> anyhow::Result<()> { +pub fn remove_dir(path: &str, timeout: Option) -> anyhow::Result<()> { + let timeout = timeout.unwrap_or(5); + let request = VfsRequest { path: path.to_string(), action: VfsAction::RemoveDir, @@ -82,7 +84,7 @@ pub fn remove_dir(path: &str) -> anyhow::Result<()> { let message = Request::new() .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) - .send_and_await_response(5)?; + .send_and_await_response(timeout)?; match message { Ok(Message::Response { body, .. }) => { diff --git a/src/vfs/file.rs b/src/vfs/file.rs index 0ddf25c..6d38e82 100644 --- a/src/vfs/file.rs +++ b/src/vfs/file.rs @@ -373,7 +373,13 @@ impl File { /// Creates a drive with path "/package_id/drive", gives you read and write caps. /// Will only work on the same package_id as you're calling it from, unless you /// have root capabilities. -pub fn create_drive(package_id: PackageId, drive: &str) -> anyhow::Result { +pub fn create_drive( + package_id: PackageId, + drive: &str, + timeout: Option, +) -> anyhow::Result { + let timeout = timeout.unwrap_or(5); + let path = format!("/{}/{}", package_id, drive); let res = Request::new() .target(("our", "vfs", "distro", "sys")) @@ -381,7 +387,7 @@ pub fn create_drive(package_id: PackageId, drive: &str) -> anyhow::Result { @@ -397,7 +403,9 @@ pub fn create_drive(package_id: PackageId, drive: &str) -> anyhow::Result anyhow::Result { +pub fn open_file(path: &str, create: bool, timeout: Option) -> anyhow::Result { + let timeout = timeout.unwrap_or(5); + let request = VfsRequest { path: path.to_string(), action: VfsAction::OpenFile { create }, @@ -406,7 +414,7 @@ pub fn open_file(path: &str, create: bool) -> anyhow::Result { let message = Request::new() .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) - .send_and_await_response(5)?; + .send_and_await_response(timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -414,7 +422,7 @@ pub fn open_file(path: &str, create: bool) -> anyhow::Result { match response { VfsResponse::Ok => Ok(File { path: path.to_string(), - timeout: 5, + timeout, }), VfsResponse::Err(e) => Err(e.into()), _ => Err(anyhow::anyhow!("vfs: unexpected response: {:?}", response)), @@ -454,7 +462,9 @@ pub fn create_file(path: &str, timeout: Option) -> anyhow::Result { } /// Removes a file at path, errors if path not found or path is not a file. -pub fn remove_file(path: &str) -> anyhow::Result<()> { +pub fn remove_file(path: &str, timeout: Option) -> anyhow::Result<()> { + let timeout = timeout.unwrap_or(5); + let request = VfsRequest { path: path.to_string(), action: VfsAction::RemoveFile, @@ -463,7 +473,7 @@ pub fn remove_file(path: &str) -> anyhow::Result<()> { let message = Request::new() .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) - .send_and_await_response(5)?; + .send_and_await_response(timeout)?; match message { Ok(Message::Response { body, .. }) => { diff --git a/src/vfs/mod.rs b/src/vfs/mod.rs index cefbdbe..5f0aa5f 100644 --- a/src/vfs/mod.rs +++ b/src/vfs/mod.rs @@ -127,7 +127,9 @@ impl VfsError { } /// Metadata of a path, returns file type and length. -pub fn metadata(path: &str) -> anyhow::Result { +pub fn metadata(path: &str, timeout: Option) -> anyhow::Result { + let timeout = timeout.unwrap_or(5); + let request = VfsRequest { path: path.to_string(), action: VfsAction::Metadata, @@ -135,7 +137,7 @@ pub fn metadata(path: &str) -> anyhow::Result { let message = Request::new() .target(("our", "vfs", "distro", "sys")) .body(serde_json::to_vec(&request)?) - .send_and_await_response(5)?; + .send_and_await_response(timeout)?; match message { Ok(Message::Response { body, .. }) => { @@ -151,11 +153,11 @@ pub fn metadata(path: &str) -> anyhow::Result { } /// Removes a path, if it's either a directory or a file. -pub fn remove_path(path: &str) -> anyhow::Result<()> { - let meta = metadata(path)?; +pub fn remove_path(path: &str, timeout: Option) -> anyhow::Result<()> { + let meta = metadata(path, timeout)?; match meta.file_type { - FileType::Directory => remove_dir(path), - FileType::File => remove_file(path), + FileType::Directory => remove_dir(path, timeout), + FileType::File => remove_file(path, timeout), _ => Err(anyhow::anyhow!( "vfs: path is not a file or directory: {}", path From e055bedf6ed95bf5956a2af30168d042a2cf7458 Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Fri, 1 Mar 2024 14:31:45 -0300 Subject: [PATCH 31/36] kv: automatic key and value serialization --- src/kv.rs | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/kv.rs b/src/kv.rs index a41d31b..0aa309a 100644 --- a/src/kv.rs +++ b/src/kv.rs @@ -1,5 +1,6 @@ use crate::{get_blob, Message, PackageId, Request}; -use serde::{Deserialize, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use std::marker::PhantomData; use thiserror::Error; /// Actions are sent to a specific key value database, "db" is the name, @@ -54,15 +55,21 @@ pub enum KvError { /// Opening or creating a kv will give you a Result. /// You can call it's impl functions to interact with it. #[derive(Debug, Serialize, Deserialize)] -pub struct Kv { +pub struct Kv { pub package_id: PackageId, pub db: String, pub timeout: u64, + _marker: PhantomData<(K, V)>, } -impl Kv { +impl Kv +where + K: Serialize + DeserializeOwned, + V: Serialize + DeserializeOwned, +{ /// Get a value. - pub fn get(&self, key: Vec) -> anyhow::Result> { + pub fn get(&self, key: &K) -> anyhow::Result { + let key = serde_json::to_vec(key)?; let res = Request::new() .target(("our", "kv", "distro", "sys")) .body(serde_json::to_vec(&KvRequest { @@ -82,7 +89,9 @@ impl Kv { Some(bytes) => bytes.bytes, None => return Err(anyhow::anyhow!("kv: no blob")), }; - Ok(bytes) + let value = serde_json::from_slice::(&bytes) + .map_err(|e| anyhow::anyhow!("Failed to deserialize value: {}", e))?; + Ok(value) } KvResponse::Err { error } => Err(error.into()), _ => Err(anyhow::anyhow!("kv: unexpected response {:?}", response)), @@ -93,7 +102,10 @@ impl Kv { } /// Set a value, optionally in a transaction. - pub fn set(&self, key: Vec, value: Vec, tx_id: Option) -> anyhow::Result<()> { + pub fn set(&self, key: &K, value: &V, tx_id: Option) -> anyhow::Result<()> { + let key = serde_json::to_vec(key)?; + let value = serde_json::to_vec(value)?; + let res = Request::new() .target(("our", "kv", "distro", "sys")) .body(serde_json::to_vec(&KvRequest { @@ -119,7 +131,8 @@ impl Kv { } /// Delete a value, optionally in a transaction. - pub fn delete(&self, key: Vec, tx_id: Option) -> anyhow::Result<()> { + pub fn delete(&self, key: &K, tx_id: Option) -> anyhow::Result<()> { + let key = serde_json::to_vec(key)?; let res = Request::new() .target(("our", "kv", "distro", "sys")) .body(serde_json::to_vec(&KvRequest { @@ -195,7 +208,11 @@ impl Kv { } /// Opens or creates a kv db. -pub fn open(package_id: PackageId, db: &str, timeout: Option) -> anyhow::Result { +pub fn open(package_id: PackageId, db: &str, timeout: Option) -> anyhow::Result> +where + K: Serialize + DeserializeOwned, + V: Serialize + DeserializeOwned, +{ let timeout = timeout.unwrap_or(5); let res = Request::new() @@ -216,6 +233,7 @@ pub fn open(package_id: PackageId, db: &str, timeout: Option) -> anyhow::Re package_id, db: db.to_string(), timeout, + _marker: PhantomData, }), KvResponse::Err { error } => Err(error.into()), _ => Err(anyhow::anyhow!("kv: unexpected response {:?}", response)), From 86ae506b03dccf0265f5994967ced1871009c76b Mon Sep 17 00:00:00 2001 From: dr-frmr Date: Mon, 4 Mar 2024 15:41:23 -0300 Subject: [PATCH 32/36] match types to runtime --- src/eth.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/eth.rs b/src/eth.rs index 62ad109..07f27fb 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -17,7 +17,7 @@ use std::collections::HashSet; /// capabilities can send this action to the eth provider. /// /// Will be serialized and deserialized using `serde_json::to_vec` and `serde_json::from_slice`. -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub enum EthAction { /// Subscribe to logs with a custom filter. ID is to be used to unsubscribe. /// Logs come in as alloy_rpc_types::pubsub::SubscriptionResults @@ -70,7 +70,7 @@ pub enum EthResponse { Err(EthError), } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, PartialEq)] pub enum EthError { /// provider module cannot parse message MalformedRequest, @@ -157,14 +157,17 @@ pub struct ProviderConfig { #[derive(Clone, Debug, Deserialize, Serialize)] pub enum NodeOrRpcUrl { - Node(crate::kernel_types::KnsUpdate), + Node { + kns_update: crate::kernel_types::KnsUpdate, + use_as_provider: bool, // for routers inside saved config + }, RpcUrl(String), } impl std::cmp::PartialEq for NodeOrRpcUrl { fn eq(&self, other: &str) -> bool { match self { - NodeOrRpcUrl::Node(kns) => kns.name == other, + NodeOrRpcUrl::Node { kns_update, .. } => kns_update.name == other, NodeOrRpcUrl::RpcUrl(url) => url == other, } } From 9223aed471d458da1a940a3b064674d1d865d3fd Mon Sep 17 00:00:00 2001 From: dr-frmr Date: Tue, 5 Mar 2024 17:14:08 -0300 Subject: [PATCH 33/36] sync with runtime --- src/eth.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/eth.rs b/src/eth.rs index 07f27fb..8dfd266 100644 --- a/src/eth.rs +++ b/src/eth.rs @@ -7,7 +7,7 @@ pub use alloy_rpc_types::{ TransactionReceipt, }; use serde::{Deserialize, Serialize}; -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; // // types mirrored from runtime module @@ -121,6 +121,8 @@ pub enum EthConfigAction { GetProviders, /// Get the current access settings. GetAccessSettings, + /// Get the state of calls and subscriptions. Used for debugging. + GetState, } /// Response type from an [`EthConfigAction`] request. @@ -135,6 +137,11 @@ pub enum EthConfigResponse { AccessSettings(AccessSettings), /// Permission denied due to missing capability PermissionDenied, + /// Response from a GetState request + State { + active_subscriptions: HashMap>>, // None if local, Some(node_provider_name) if remote + outstanding_requests: HashSet, + }, } /// Settings for our ETH provider From 69d8c0803f0e5fd1b74c69471a0d6abfae269623 Mon Sep 17 00:00:00 2001 From: dr-frmr Date: Wed, 6 Mar 2024 14:20:28 -0300 Subject: [PATCH 34/36] add unbind actions and helpers --- src/http.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/http.rs b/src/http.rs index 885cb52..aeead28 100644 --- a/src/http.rs +++ b/src/http.rs @@ -96,6 +96,8 @@ pub enum HttpServerAction { /// lazy_load_blob bytes and serve them as the response to any request to this path. cache: bool, }, + /// Unbind a previously-bound HTTP path + Unbind { path: String }, /// Bind a path to receive incoming WebSocket connections. /// Doesn't need a cache since does not serve assets. WebSocketBind { @@ -113,6 +115,8 @@ pub enum HttpServerAction { encrypted: bool, extension: bool, }, + /// Unbind a previously-bound WebSocket path + WebSocketUnbind { path: String }, /// Processes will RECEIVE this kind of request when a client connects to them. /// If a process does not want this websocket open, they should issue a *request* /// containing a [`type@HttpServerAction::WebSocketClose`] message and this channel ID. @@ -434,6 +438,27 @@ where resp } +pub fn unbind_http_path(path: T) -> std::result::Result<(), HttpServerError> +where + T: Into, +{ + let res = KiRequest::to(("our", "http_server", "distro", "sys")) + .body(serde_json::to_vec(&HttpServerAction::Unbind { path: path.into() }).unwrap()) + .send_and_await_response(5) + .unwrap(); + let Ok(Message::Response { body, .. }) = res else { + return Err(HttpServerError::PathBindError { + error: "http_server timed out".to_string(), + }); + }; + let Ok(resp) = serde_json::from_slice::>(&body) else { + return Err(HttpServerError::PathBindError { + error: "http_server gave unexpected response".to_string(), + }); + }; + resp +} + /// Register a WebSockets path with the HTTP server. Your app must do this /// in order to receive incoming WebSocket connections. pub fn bind_ws_path( @@ -501,6 +526,27 @@ where resp } +pub fn unbind_ws_path(path: T) -> std::result::Result<(), HttpServerError> +where + T: Into, +{ + let res = KiRequest::to(("our", "http_server", "distro", "sys")) + .body(serde_json::to_vec(&HttpServerAction::WebSocketUnbind { path: path.into() }).unwrap()) + .send_and_await_response(5) + .unwrap(); + let Ok(Message::Response { body, .. }) = res else { + return Err(HttpServerError::PathBindError { + error: "http_server timed out".to_string(), + }); + }; + let Ok(resp) = serde_json::from_slice::>(&body) else { + return Err(HttpServerError::PathBindError { + error: "http_server gave unexpected response".to_string(), + }); + }; + resp +} + /// Send an HTTP response to the incoming HTTP request. pub fn send_response(status: StatusCode, headers: Option>, body: Vec) { KiResponse::new() From b699c3d7fde99ef66dd5f8f2f4193a19956c2ae4 Mon Sep 17 00:00:00 2001 From: dr-frmr Date: Fri, 8 Mar 2024 18:24:22 -0300 Subject: [PATCH 35/36] update kinode-wit submodule --- kinode-wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kinode-wit b/kinode-wit index 373542a..a53273e 160000 --- a/kinode-wit +++ b/kinode-wit @@ -1 +1 @@ -Subproject commit 373542a9a94ae61a7d216159f9f7bdf9266cd935 +Subproject commit a53273e808b6a79e8484bc9e539f4ce7fcf5b726 From e80d706ae02baa668d8a12459fe12885b9dd82de Mon Sep 17 00:00:00 2001 From: dr-frmr Date: Fri, 8 Mar 2024 19:18:37 -0300 Subject: [PATCH 36/36] update wit --- kinode-wit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kinode-wit b/kinode-wit index a53273e..aa2c8b1 160000 --- a/kinode-wit +++ b/kinode-wit @@ -1 +1 @@ -Subproject commit a53273e808b6a79e8484bc9e539f4ce7fcf5b726 +Subproject commit aa2c8b11c9171b949d1991c32f58591c0e881f85