diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..33332034 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +.vscode +**/target/ diff --git a/.gitignore b/.gitignore index 69552e7f..346dcde5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ node_modules .env .DS_Store **/.idea/ +target/ +offchain/core/src/contract/*tournament.rs diff --git a/.gitmodules b/.gitmodules index 2363f251..6c8ff751 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "permissionless-arbitration/contracts/lib/forge-std"] path = permissionless-arbitration/contracts/lib/forge-std url = https://github.com/foundry-rs/forge-std +[submodule "machine-json-rpc"] + path = machine-json-rpc + url = https://github.com/cartesi/machine-json-rpc diff --git a/machine-json-rpc b/machine-json-rpc new file mode 160000 index 00000000..b662bf93 --- /dev/null +++ b/machine-json-rpc @@ -0,0 +1 @@ +Subproject commit b662bf93bd86b5a02ae73af27d8396b559707e20 diff --git a/offchain/Cargo.lock b/offchain/Cargo.lock new file mode 100644 index 00000000..4d7abb0e --- /dev/null +++ b/offchain/Cargo.lock @@ -0,0 +1,4368 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloy-json-abi" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "838228983f74f30e4efbd8d42d25bfe1b5bf6450ca71ee9d7628f134fbe8ae8e" +dependencies = [ + "alloy-primitives", + "alloy-sol-type-parser", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-primitives" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c234f92024707f224510ff82419b2be0e1d8e1fd911defcac5a085cd7f83898" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more", + "getrandom", + "hex-literal", + "itoa", + "keccak-asm", + "proptest", + "rand", + "ruint", + "serde", + "tiny-keccak", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac" +dependencies = [ + "arrayvec", + "bytes", +] + +[[package]] +name = "alloy-sol-type-parser" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c82c1ed2d61e982cef4c4d709f4aeef5f39a6a6a7c59b6e54c9ed4f3f7e3741b" +dependencies = [ + "winnow", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.4.0", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint", + "num-traits", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "ascii-canvas" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" +dependencies = [ + "term", +] + +[[package]] +name = "async-recursion" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "async_io_stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" +dependencies = [ + "futures", + "pharos", + "rustc_version 0.4.0", +] + +[[package]] +name = "auto_impl" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "autocfg" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" +dependencies = [ + "serde", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "sha2", + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +dependencies = [ + "serde", +] + +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12024c4645c97566567129c204f65d5815a8c9aecf30fcbe682b2fe034996d36" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.20", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cartesi-compute-core" +version = "0.1.0" +dependencies = [ + "async-recursion", + "async-trait", + "base64 0.21.5", + "cartesi-machine-json-rpc", + "convert_case 0.6.0", + "ethers", + "ethers-contract-abigen", + "foundry-compilers", + "hex", + "log", + "serde_json", + "sha3", + "thiserror", +] + +[[package]] +name = "cartesi-machine-json-rpc" +version = "0.1.0" +dependencies = [ + "base64 0.21.5", + "derive_builder", + "jsonrpsee", + "serde", + "serde_json", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cfg-if" +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 = [ + "num-traits", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "coins-bip32" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b6be4a5df2098cd811f3194f64ddb96c267606bffd9689ac7b0160097b01ad3" +dependencies = [ + "bs58", + "coins-core", + "digest 0.10.7", + "hmac", + "k256", + "serde", + "sha2", + "thiserror", +] + +[[package]] +name = "coins-bip39" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8fba409ce3dc04f7d804074039eb68b960b0829161f8e06c95fea3f122528" +dependencies = [ + "bitvec", + "coins-bip32", + "hmac", + "once_cell", + "pbkdf2 0.12.2", + "rand", + "sha2", + "thiserror", +] + +[[package]] +name = "coins-core" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" +dependencies = [ + "base64 0.21.5", + "bech32", + "bs58", + "digest 0.10.7", + "generic-array", + "hex", + "ripemd", + "serde", + "serde_derive", + "sha2", + "sha3", + "thiserror", +] + +[[package]] +name = "const-hex" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "proptest", + "serde", +] + +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cpufeatures" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "data-encoding" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" + +[[package]] +name = "dave-compute" +version = "0.1.0" +dependencies = [ + "cartesi-compute-core", + "env_logger", + "ethers", + "log", + "tokio", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_macro" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" +dependencies = [ + "derive_builder_core", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn 1.0.109", +] + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "ecdsa" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "elliptic-curve" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "ena" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" +dependencies = [ + "log", +] + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enr" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe81b5c06ecfdbc71dd845216f225f53b62a10cb8a16c946836a3467f701d05b" +dependencies = [ + "base64 0.21.5", + "bytes", + "hex", + "k256", + "log", + "rand", + "rlp", + "serde", + "sha3", + "zeroize", +] + +[[package]] +name = "env_logger" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "eth-keystore" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" +dependencies = [ + "aes", + "ctr", + "digest 0.10.7", + "hex", + "hmac", + "pbkdf2 0.11.0", + "rand", + "scrypt", + "serde", + "serde_json", + "sha2", + "sha3", + "thiserror", + "uuid", +] + +[[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" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5344eea9b20effb5efeaad29418215c4d27017639fd1f908260f59cbbd226e" +dependencies = [ + "ethers-addressbook", + "ethers-contract", + "ethers-core", + "ethers-etherscan", + "ethers-middleware", + "ethers-providers", + "ethers-signers", + "ethers-solc", +] + +[[package]] +name = "ethers-addressbook" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c405f24ea3a517899ba7985385c43dc4a7eb1209af3b1e0a1a32d7dcc7f8d09" +dependencies = [ + "ethers-core", + "once_cell", + "serde", + "serde_json", +] + +[[package]] +name = "ethers-contract" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0111ead599d17a7bff6985fd5756f39ca7033edc79a31b23026a8d5d64fa95cd" +dependencies = [ + "const-hex", + "ethers-contract-abigen", + "ethers-contract-derive", + "ethers-core", + "ethers-providers", + "futures-util", + "once_cell", + "pin-project", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "ethers-contract-abigen" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51258120c6b47ea9d9bec0d90f9e8af71c977fbefbef8213c91bfed385fe45eb" +dependencies = [ + "Inflector", + "const-hex", + "dunce", + "ethers-core", + "ethers-etherscan", + "eyre", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "reqwest", + "serde", + "serde_json", + "syn 2.0.38", + "toml", + "walkdir", +] + +[[package]] +name = "ethers-contract-derive" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936e7a0f1197cee2b62dc89f63eff3201dbf87c283ff7e18d86d38f83b845483" +dependencies = [ + "Inflector", + "const-hex", + "ethers-contract-abigen", + "ethers-core", + "proc-macro2", + "quote", + "serde_json", + "syn 2.0.38", +] + +[[package]] +name = "ethers-core" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f03e0bdc216eeb9e355b90cf610ef6c5bb8aca631f97b5ae9980ce34ea7878d" +dependencies = [ + "arrayvec", + "bytes", + "cargo_metadata", + "chrono", + "const-hex", + "elliptic-curve", + "ethabi", + "generic-array", + "k256", + "num_enum", + "once_cell", + "open-fastrlp", + "rand", + "rlp", + "serde", + "serde_json", + "strum", + "syn 2.0.38", + "tempfile", + "thiserror", + "tiny-keccak", + "unicode-xid", +] + +[[package]] +name = "ethers-etherscan" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abbac2c890bdbe0f1b8e549a53b00e2c4c1de86bb077c1094d1f38cdf9381a56" +dependencies = [ + "chrono", + "ethers-core", + "reqwest", + "semver 1.0.20", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "ethers-middleware" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681ece6eb1d10f7cf4f873059a77c04ff1de4f35c63dd7bccde8f438374fcb93" +dependencies = [ + "async-trait", + "auto_impl", + "ethers-contract", + "ethers-core", + "ethers-etherscan", + "ethers-providers", + "ethers-signers", + "futures-channel", + "futures-locks", + "futures-util", + "instant", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", + "tracing-futures", + "url", +] + +[[package]] +name = "ethers-providers" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25d6c0c9455d93d4990c06e049abf9b30daf148cf461ee939c11d88907c60816" +dependencies = [ + "async-trait", + "auto_impl", + "base64 0.21.5", + "bytes", + "const-hex", + "enr", + "ethers-core", + "futures-core", + "futures-timer", + "futures-util", + "hashers", + "http", + "instant", + "jsonwebtoken", + "once_cell", + "pin-project", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing", + "tracing-futures", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "ws_stream_wasm", +] + +[[package]] +name = "ethers-signers" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cb1b714e227bbd2d8c53528adb580b203009728b17d0d0e4119353aa9bc5532" +dependencies = [ + "async-trait", + "coins-bip32", + "coins-bip39", + "const-hex", + "elliptic-curve", + "eth-keystore", + "ethers-core", + "rand", + "sha2", + "thiserror", + "tracing", +] + +[[package]] +name = "ethers-solc" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a64f710586d147864cff66540a6d64518b9ff37d73ef827fee430538265b595f" +dependencies = [ + "cfg-if", + "const-hex", + "dirs", + "dunce", + "ethers-core", + "glob", + "home", + "md-5", + "num_cpus", + "once_cell", + "path-slash", + "rayon", + "regex", + "semver 1.0.20", + "serde", + "serde_json", + "solang-parser", + "svm-rs", + "thiserror", + "tiny-keccak", + "tokio", + "tracing", + "walkdir", + "yansi", +] + +[[package]] +name = "eyre" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "foundry-compilers" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "723188b46b06f9a9836a5c6e21a5cb97c12e7411c2104afffba06a6c2beee518" +dependencies = [ + "alloy-json-abi", + "alloy-primitives", + "cfg-if", + "const-hex", + "dirs", + "dunce", + "glob", + "home", + "md-5", + "memmap2", + "num_cpus", + "once_cell", + "path-slash", + "rayon", + "regex", + "semver 1.0.20", + "serde", + "serde_json", + "solang-parser", + "svm-rs", + "thiserror", + "tiny-keccak", + "tokio", + "tracing", + "walkdir", + "yansi", +] + +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-executor" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-locks" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" +dependencies = [ + "futures-channel", + "futures-task", +] + +[[package]] +name = "futures-macro" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +dependencies = [ + "gloo-timers", + "send_wrapper 0.4.0", +] + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 1.9.3", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" + +[[package]] +name = "hashers" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2bca93b15ea5a746f220e56587f71e73c6165eab783df9e26590069953e3c30" +dependencies = [ + "fxhash", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "log", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[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", +] + +[[package]] +name = "indexmap" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +dependencies = [ + "equivalent", + "hashbrown 0.14.2", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonrpsee" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1822d18e4384a5e79d94dc9e4d1239cfa9fad24e55b44d2efeff5b394c9fece4" +dependencies = [ + "jsonrpsee-core", + "jsonrpsee-http-client", +] + +[[package]] +name = "jsonrpsee-core" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c6832a55f662b5a6ecc844db24b8b9c387453f923de863062c60ce33d62b81" +dependencies = [ + "anyhow", + "async-trait", + "beef", + "futures-util", + "hyper", + "jsonrpsee-types", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "jsonrpsee-http-client" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1705c65069729e3dccff6fd91ee431d5d31cabcf00ce68a62a2c6435ac713af9" +dependencies = [ + "async-trait", + "hyper", + "hyper-rustls", + "jsonrpsee-core", + "jsonrpsee-types", + "serde", + "serde_json", + "thiserror", + "tokio", + "tower", + "tracing", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5bf6c75ce2a4217421154adfc65a24d2b46e77286e59bba5d9fa6544ccc8f4" +dependencies = [ + "anyhow", + "beef", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "jsonwebtoken" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" +dependencies = [ + "base64 0.21.5", + "pem", + "ring 0.16.20", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "k256" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "keccak-asm" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb8515fff80ed850aea4a1595f2e519c003e2a00a82fe168ebf5269196caf444" +dependencies = [ + "digest 0.10.7", + "sha3-asm", +] + +[[package]] +name = "lalrpop" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da4081d44f4611b66c6dd725e6de3169f9f63905421e8626fcb86b6a898998b8" +dependencies = [ + "ascii-canvas", + "bit-set", + "diff", + "ena", + "is-terminal", + "itertools 0.10.5", + "lalrpop-util", + "petgraph", + "regex", + "regex-syntax 0.7.5", + "string_cache", + "term", + "tiny-keccak", + "unicode-xid", +] + +[[package]] +name = "lalrpop-util" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "linux-raw-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest 0.10.7", +] + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "memmap2" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45fd3a57831bf88bc63f8cebc0cf956116276e97fef3966103e96416209f7c92" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e" +dependencies = [ + "proc-macro-crate 2.0.0", + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[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 = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "parity-scale-codec" +version = "3.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets", +] + +[[package]] +name = "password-hash" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "path-slash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", + "hmac", + "password-hash", + "sha2", +] + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest 0.10.7", + "hmac", +] + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pest" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.0.2", +] + +[[package]] +name = "pharos" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +dependencies = [ + "futures", + "rustc_version 0.4.0", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared 0.11.2", + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "prettyplease" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +dependencies = [ + "proc-macro2", + "syn 2.0.38", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit 0.20.7", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c003ac8c77cb07bb74f5f198bce836a689bcd5a42574612bf14d17bfd08c20e" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.4.1", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax 0.7.5", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rayon" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[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 = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall 0.2.16", + "thiserror", +] + +[[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 0.8.2", +] + +[[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 0.8.2", +] + +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "base64 0.21.5", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-rustls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "rlp" +version = "0.5.2" +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 = "rollups-input-reader" +version = "0.1.0" +dependencies = [ + "async-recursion", + "ethers", + "futures", + "tokio", +] + +[[package]] +name = "ruint" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "bytes", + "fastrlp", + "num-bigint", + "num-traits", + "parity-scale-codec", + "primitive-types", + "proptest", + "rand", + "rlp", + "ruint-macro", + "serde", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.20", +] + +[[package]] +name = "rustix" +version = "0.38.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustls" +version = "0.21.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" +dependencies = [ + "log", + "ring 0.17.5", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +dependencies = [ + "base64 0.21.5", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.5", + "untrusted 0.9.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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "salsa20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[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 = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scrypt" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" +dependencies = [ + "hmac", + "pbkdf2 0.11.0", + "salsa20", + "sha2", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.5", + "untrusted 0.9.0", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +dependencies = [ + "serde", +] + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "serde" +version = "1.0.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bac61da6b35ad76b195eb4771210f947734321a8d81d7738e1580d953bc7a15e" +dependencies = [ + "cc", + "cfg-if", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", + "rand_core", +] + +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "solang-parser" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c425ce1c59f4b154717592f0bdf4715c3a1d55058883622d3157e1f0908a5b26" +dependencies = [ + "itertools 0.11.0", + "lalrpop", + "lalrpop-util", + "phf", + "thiserror", + "unicode-xid", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot", + "phf_shared 0.10.0", + "precomputed-hash", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "svm-rs" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0cc95be7cc2c384a2f57cac56548d2178650905ebe5725bc8970ccc25529060" +dependencies = [ + "dirs", + "fs2", + "hex", + "once_cell", + "reqwest", + "semver 1.0.20", + "serde", + "serde_json", + "sha2", + "thiserror", + "url", + "zip", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.4.1", + "rustix", + "windows-sys", +] + +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + +[[package]] +name = "termcolor" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "time" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +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.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.5", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "rustls", + "tokio", + "tokio-rustls", + "tungstenite", + "webpki-roots", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.21.0", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.0.2", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap 2.0.2", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +dependencies = [ + "indexmap 2.0.2", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "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-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand", + "rustls", + "sha1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", + "serde", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.38", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "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_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[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_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[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_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "winnow" +version = "0.5.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8434aeec7b290e8da5c3f0d628cb0eac6cabcb31d14bb74f779a08109a5914d6" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys", +] + +[[package]] +name = "ws_stream_wasm" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" +dependencies = [ + "async_io_stream", + "futures", + "js-sys", + "log", + "pharos", + "rustc_version 0.4.0", + "send_wrapper 0.6.0", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "aes", + "byteorder", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "flate2", + "hmac", + "pbkdf2 0.11.0", + "sha1", + "time", + "zstd", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.9+zstd.1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/offchain/Cargo.toml b/offchain/Cargo.toml new file mode 100644 index 00000000..68cd38b3 --- /dev/null +++ b/offchain/Cargo.toml @@ -0,0 +1,30 @@ +[workspace] +resolver = "2" +members = [ + "core", + "dave-compute", + "input-reader", +] + +[workspace.package] +version = "0.1.0" + +authors = [ + "Gabriel Coutinho de Paula ", + "Algebraic Sofia ", + "Stephen Chen ", +] +description = "A Cartesi validator reference implementation" +edition = "2021" +homepage = "https://github.com/cartesi/dave" +license-file = "LICENSE" +readme = "README.md" +repository = "https://github.com/cartesi/dave" + +[workspace.dependencies] +async-recursion = "1" +async-trait = "0.1.74" +ethers = "2.0.11" +futures = "0.3" +log = "0.4" +tokio = { version = "1", features = ["full"] } diff --git a/offchain/Dockerfile b/offchain/Dockerfile new file mode 100644 index 00000000..4b2d924b --- /dev/null +++ b/offchain/Dockerfile @@ -0,0 +1,14 @@ +FROM rust:latest + +RUN curl -sSL https://github.com/foundry-rs/foundry/releases/download/nightly/foundry_nightly_linux_$(dpkg --print-architecture).tar.gz | \ + tar -zx -C /usr/local/bin + +# Install protoc +WORKDIR /usr +RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v24.4/protoc-24.4-linux-x86_64.zip \ + && unzip protoc-24.4-linux-x86_64.zip \ + && rm protoc-24.4-linux-x86_64.zip + +# Copy source +#ADD . /source +WORKDIR /source \ No newline at end of file diff --git a/offchain/Dockerfile.compute b/offchain/Dockerfile.compute new file mode 100644 index 00000000..4da635f0 --- /dev/null +++ b/offchain/Dockerfile.compute @@ -0,0 +1,47 @@ +FROM rust:1.71.0-bookworm AS chef + +ENV CARGO_REGISTRIES_CARTESI_INDEX=https://github.com/cartesi/crates-index +RUN rustup component add rustfmt +RUN cargo install cargo-chef + +FROM chef AS planner +WORKDIR /app +COPY ./machine-json-rpc /app/machine-json-rpc +COPY ./offchain /app/offchain +WORKDIR /app/offchain +RUN cargo chef prepare --recipe-path recipe.json + +FROM chef AS builder +WORKDIR /app +COPY ./machine-json-rpc /app/machine-json-rpc +COPY --from=planner /app/offchain/recipe.json /app/offchain/recipe.json + +# Build dependencies - this is the caching Docker layer! +WORKDIR /app/offchain +RUN cargo chef cook --release --recipe-path recipe.json + +# Build application +COPY --from=ethereum/solc:0.8.23 /usr/bin/solc /usr/bin/solc +RUN chmod u+x /usr/bin/solc + +COPY ./offchain /app/offchain +COPY ./machine-emulator-sdk /app/machine-emulator-sdk +COPY ./permissionless-arbitration /app/permissionless-arbitration +RUN cargo build --release --bin dave-compute + +FROM --platform=linux/amd64 cartesi/machine-emulator:0.15.2 + +USER root +RUN apt-get update && \ + apt-get install -y procps curl git xxd +RUN curl -sSL https://github.com/foundry-rs/foundry/releases/download/nightly/foundry_nightly_linux_$(dpkg --print-architecture).tar.gz | \ + tar -zx -C /usr/local/bin + +COPY . /root +WORKDIR /root/permissionless-arbitration/lua_node/program +RUN ./gen_machine_simple.sh + +COPY --from=builder /app/offchain/target/release/dave-compute /root/target/release/dave-compute +WORKDIR /root + +ENTRYPOINT [ "/root/offchain/compute-entrypoint.sh" ] diff --git a/offchain/Dockerfile.compute.debootstrap b/offchain/Dockerfile.compute.debootstrap new file mode 100644 index 00000000..cf8ba1e6 --- /dev/null +++ b/offchain/Dockerfile.compute.debootstrap @@ -0,0 +1,47 @@ +FROM rust:1.71.0-bookworm AS chef + +ENV CARGO_REGISTRIES_CARTESI_INDEX=https://github.com/cartesi/crates-index +RUN rustup component add rustfmt +RUN cargo install cargo-chef + +FROM chef AS planner +WORKDIR /app +COPY ./machine-json-rpc /app/machine-json-rpc +COPY ./offchain /app/offchain +WORKDIR /app/offchain +RUN cargo chef prepare --recipe-path recipe.json + +FROM chef AS builder +WORKDIR /app +COPY ./machine-json-rpc /app/machine-json-rpc +COPY --from=planner /app/offchain/recipe.json /app/offchain/recipe.json + +# Build dependencies - this is the caching Docker layer! +WORKDIR /app/offchain +RUN cargo chef cook --release --recipe-path recipe.json + +# Build application +COPY --from=ethereum/solc:0.8.23 /usr/bin/solc /usr/bin/solc +RUN chmod u+x /usr/bin/solc + +COPY ./offchain /app/offchain +COPY ./machine-emulator-sdk /app/machine-emulator-sdk +COPY ./permissionless-arbitration /app/permissionless-arbitration +RUN cargo build --release --bin dave-compute + +FROM --platform=linux/amd64 cartesi/machine-emulator:0.15.2 + +USER root +RUN apt-get update && \ + apt-get install -y procps curl git xxd +RUN curl -sSL https://github.com/foundry-rs/foundry/releases/download/nightly/foundry_nightly_linux_$(dpkg --print-architecture).tar.gz | \ + tar -zx -C /usr/local/bin +RUN mkdir -p /root/permissionless-arbitration/lua_node/program +RUN curl -sSL https://web3.link/debootstrap-machine-sparsed.tar.gz | \ + tar -zx -C /root/permissionless-arbitration/lua_node/program + +COPY . /root +COPY --from=builder /app/offchain/target/release/dave-compute /root/target/release/dave-compute +WORKDIR /root + +ENTRYPOINT [ "/root/offchain/compute-entrypoint.sh" ] diff --git a/offchain/README.md b/offchain/README.md new file mode 100644 index 00000000..1651da94 --- /dev/null +++ b/offchain/README.md @@ -0,0 +1,13 @@ +# Dave Compute Node + +## Run example + +``` +docker build -t cartesi/dave-compute:dev -f Dockerfile.compute ../ && docker run --rm --env MACHINE_PATH="/root/permissionless-arbitration/lua_node/program/simple-program" cartesi/dave-compute:dev +``` + +## Run debootstraps + +``` +docker build -t cartesi/dave-compute-debootstrap:dev -f Dockerfile.compute.debootstrap ../ && docker run --rm --env MACHINE_PATH="/root/permissionless-arbitration/lua_node/program/debootstrap-machine-sparsed" cartesi/dave-compute-debootstrap:dev +``` diff --git a/offchain/compute-entrypoint.sh b/offchain/compute-entrypoint.sh new file mode 100755 index 00000000..5a7f3fc4 --- /dev/null +++ b/offchain/compute-entrypoint.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +/usr/bin/jsonrpc-remote-cartesi-machine --server-address=127.0.0.1:5002 >/dev/null 2>&1 & +# if integration test with lua node +cd /root/permissionless-arbitration && ./lua_node/single_dishonest_entrypoint.lua & +cd - && sleep 30 +# end of integration test +RUST_LOG="info" target/release/dave-compute diff --git a/offchain/core/Cargo.toml b/offchain/core/Cargo.toml new file mode 100644 index 00000000..33b2bf65 --- /dev/null +++ b/offchain/core/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "cartesi-compute-core" +version = "0.1.0" +edition = "2021" +build = "build.rs" + +[dependencies] +cartesi-machine-json-rpc = { path = "../../machine-json-rpc" } +async-recursion = { workspace = true } +async-trait = { workspace = true } +ethers = { workspace = true } +log = { workspace = true } +base64 = "0.21.3" +hex = "0.4.3" +sha3 = "0.10.8" +thiserror = "1.0.50" + +[build-dependencies] +convert_case = "0.6.0" +ethers-contract-abigen = "2.0.11" +foundry-compilers = "0.1.3" +serde_json = "1.0.107" diff --git a/offchain/core/build.rs b/offchain/core/build.rs new file mode 100644 index 00000000..7a93661d --- /dev/null +++ b/offchain/core/build.rs @@ -0,0 +1,75 @@ +use convert_case::{Case, Casing}; +use ethers_contract_abigen::Abigen; +use foundry_compilers::remappings::Remapping; +use foundry_compilers::{Project, ProjectPathsConfig}; +use serde_json; +use std::path::{Path, PathBuf}; + +fn main() -> Result<(), Box> { + generate_contract_bidings()?; + Ok(()) +} + +fn generate_contract_bidings() -> Result<(), Box> { + let project_path = Path::new(env!("CARGO_MANIFEST_DIR")); + let contract_rel_path = "../../permissionless-arbitration/contracts"; + let step_rel_path = "../../machine-emulator-sdk/solidity-step/"; + let contract_root_path = project_path.join(contract_rel_path); + let contract_src_files = vec![ + "LeafTournament".to_string(), + "NonLeafTournament".to_string(), + "RootTournament".to_string(), + "NonRootTournament".to_string(), + "Tournament".to_string(), + ]; + + let paths = ProjectPathsConfig::builder() + .root(contract_root_path.as_path()) + .remapping(Remapping { + context: None, + name: "step/".to_string(), + path: step_rel_path.to_string(), + }) + .build()?; + + let project = Project::builder() + .paths(paths) + .allowed_path(step_rel_path) + .build()?; + + project + .compile_files( + contract_src_files + .iter() + .map(|f| { + contract_root_path + .join("src/tournament/abstracts") + .join(format!("{}.sol", f)) + }) + .collect::>(), + )? + .artifacts() + .filter(|artifact| { + contract_src_files + .iter() + .any(|src| src.find(&artifact.0).is_some()) + }) + .for_each(|(contract, artifact)| { + let binding_file = format!("src/contract/{}.rs", contract.to_case(Case::Snake)); + Abigen::new( + &contract, + serde_json::to_string(artifact.abi.as_ref().expect("abi not found")) + .expect("fail to serialize abi"), + ) + .expect("fail to construct abi builder") + .generate() + .expect("fail to generate binding") + .write_to_file(project_path.join(binding_file)) + .expect("fail to write binding"); + }); + + // Tell Cargo that if a source file changes, to rerun this build script. + project.rerun_if_sources_changed(); + + Ok(()) +} diff --git a/offchain/core/src/arena/arena.rs b/offchain/core/src/arena/arena.rs new file mode 100644 index 00000000..fa808246 --- /dev/null +++ b/offchain/core/src/arena/arena.rs @@ -0,0 +1,695 @@ +//! This module defines the struct [Reader] that is responsible for the reading the states +//! of tournaments; and the struct [Sender] that is responsible for the sending transactions +//! to tournaments + +use std::{collections::HashMap, error::Error, str::FromStr, sync::Arc, time::Duration}; + +use async_recursion::async_recursion; +use async_trait::async_trait; + +use ethers::{ + middleware::SignerMiddleware, + providers::{Http, Middleware, Provider}, + signers::{LocalWallet, Signer}, + types::{Address, BlockNumber::Latest, Bytes, ValueOrArray::Value, U256}, +}; + +use crate::{ + arena::config::ArenaConfig, + contract::{ + leaf_tournament, non_leaf_tournament, non_root_tournament, root_tournament, tournament, + }, + machine::{constants, MachineProof}, + merkle::{Digest, MerkleProof}, +}; + +#[derive(Clone)] +pub struct Arena { + client: Arc, LocalWallet>>, +} + +impl Arena { + pub fn new(config: ArenaConfig) -> Result> { + let provider = Provider::::try_from(config.web3_rpc_url.clone())? + .interval(Duration::from_millis(10u64)); + let wallet = LocalWallet::from_str(config.web3_private_key.as_str())?; + let client = Arc::new(SignerMiddleware::new( + provider, + wallet.with_chain_id(config.web3_chain_id), + )); + + Ok(Self { client }) + } + + async fn created_tournament( + &self, + tournament_address: Address, + match_id: MatchID, + ) -> Result, Box> { + let tournament = + non_leaf_tournament::NonLeafTournament::new(tournament_address, self.client.clone()); + let events = tournament + .new_inner_tournament_filter() + .address(Value(tournament_address)) + .from_block(0) + .to_block(Latest) + .query() + .await?; + if let Some(event) = events.last() { + Ok(Some(TournamentCreatedEvent { + parent_match_id_hash: match_id.hash(), + new_tournament_address: event.1, + })) + } else { + Ok(None) + } + } + + async fn created_matches( + &self, + tournament_address: Address, + ) -> Result, Box> { + let tournament = tournament::Tournament::new(tournament_address, self.client.clone()); + let events: Vec = tournament + .match_created_filter() + .address(Value(tournament_address)) + .from_block(0) + .to_block(Latest) + .query() + .await? + .iter() + .map(|event| MatchCreatedEvent { + id: MatchID { + commitment_one: event.one.into(), + commitment_two: event.two.into(), + }, + left_hash: event.left_of_two.into(), + }) + .collect(); + Ok(events) + } + + async fn joined_commitments( + &self, + tournament_address: Address, + ) -> Result, Box> { + let tournament = tournament::Tournament::new(tournament_address, self.client.clone()); + let events = tournament + .commitment_joined_filter() + .address(Value(tournament_address)) + .from_block(0) + .to_block(Latest) + .query() + .await? + .iter() + .map(|c| CommitmentJoinedEvent { + root: Digest::from(c.root), + }) + .collect(); + Ok(events) + } + + async fn get_commitment( + &self, + tournament: Address, + commitment_hash: Digest, + ) -> Result> { + let tournament = tournament::Tournament::new(tournament, self.client.clone()); + let (clock_state, hash) = tournament + .get_commitment(commitment_hash.into()) + .call() + .await?; + let block_time = self + .client + .get_block(Latest) + .await? + .expect("cannot get last block") + .timestamp; + let clock_state = ClockState { + allowance: clock_state.allowance, + start_instant: clock_state.start_instant, + block_time, + }; + Ok(CommitmentState { + clock: clock_state, + final_state: Digest::from(hash), + latest_match: None, + }) + } + + pub async fn fetch_from_root( + &self, + root_tournament: Address, + ) -> Result, Box> { + self.fetch_tournament(TournamentState::new_root(root_tournament), HashMap::new()) + .await + } + + #[async_recursion] + async fn fetch_tournament( + &self, + tournament_state: TournamentState, + states: HashMap, + ) -> Result, Box> { + let tournament = tournament::Tournament::new(tournament_state.address, self.client.clone()); + let created_matches = self.created_matches(tournament_state.address).await?; + let commitments_joined = self.joined_commitments(tournament_state.address).await?; + + let mut commitment_states = HashMap::new(); + for commitment in commitments_joined { + let commitment_state = self + .get_commitment(tournament_state.address, commitment.root) + .await?; + commitment_states.insert(commitment.root, commitment_state); + } + + let mut matches = vec![]; + let mut new_states = states.clone(); + for match_event in created_matches { + let match_id = match_event.id; + let m = tournament.get_match(match_id.hash().into()).call().await?; + + let running_leaf_position = m.running_leaf_position.as_u64(); + let base = tournament_state.base_big_cycle; + let step = 1 << constants::LOG2_STEP[(tournament_state.level - 1) as usize]; + let leaf_cycle = base + (step * running_leaf_position); + let base_big_cycle = leaf_cycle >> constants::LOG2_UARCH_SPAN; + let prev_states = new_states.clone(); + let match_state; + + // if !Digest::from(m.other_parent).is_zeroed() { + (match_state, new_states) = self + .fetch_match( + MatchState { + id: match_id, + other_parent: m.other_parent.into(), + left_node: m.left_node.into(), + right_node: m.right_node.into(), + running_leaf_position, + current_height: m.current_height, + tournament_address: tournament_state.address, + level: m.level, + leaf_cycle, + base_big_cycle, + inner_tournament: None, + }, + prev_states, + tournament_state.level, + ) + .await?; + + commitment_states + .get_mut(&match_id.commitment_one) + .expect("cannot find commitment one state") + .latest_match = Some(matches.len()); + commitment_states + .get_mut(&match_id.commitment_two) + .expect("cannot find commitment two state") + .latest_match = Some(matches.len()); + matches.push(match_state); + } + // } + + let winner = match tournament_state.parent { + Some(_) => self.tournament_winner(tournament_state.address).await?, + None => { + self.root_tournament_winner(tournament_state.address) + .await? + } + }; + + let mut state = tournament_state.clone(); + state.winner = winner; + state.matches = matches; + state.commitment_states = commitment_states; + + new_states.insert(tournament_state.address, state); + + Ok(new_states) + } + + #[async_recursion] + async fn fetch_match( + &self, + match_state: MatchState, + states: HashMap, + tournament_level: u64, + ) -> Result<(MatchState, HashMap), Box> { + let mut state = match_state.clone(); + let created_tournament = self + .created_tournament(match_state.tournament_address, match_state.id) + .await?; + if let Some(inner) = created_tournament { + let inner_tournament = TournamentState::new_inner( + inner.new_tournament_address, + tournament_level - 1, + match_state.base_big_cycle, + match_state.tournament_address, + ); + let new_states = self.fetch_tournament(inner_tournament, states).await?; + state.inner_tournament = Some(inner.new_tournament_address); + + return Ok((state, new_states)); + } + + Ok((state, states)) + } + + async fn root_tournament_winner( + &self, + root_tournament: Address, + ) -> Result, Box> { + let root_tournament = + root_tournament::RootTournament::new(root_tournament, self.client.clone()); + let (finished, commitment, state) = root_tournament.arbitration_result().call().await?; + if finished { + Ok(Some(TournamentWinner::Root( + Digest::from(commitment), + Digest::from(state), + ))) + } else { + Ok(None) + } + } + + async fn tournament_winner( + &self, + tournament: Address, + ) -> Result, Box> { + let tournament = + non_root_tournament::NonRootTournament::new(tournament, self.client.clone()); + let (finished, parent_commitment, dangling_commitment) = + tournament.inner_tournament_winner().call().await?; + if finished { + Ok(Some(TournamentWinner::Inner( + Digest::from(parent_commitment), + Digest::from(dangling_commitment), + ))) + } else { + Ok(None) + } + } +} + +/// The [ArenaSender] trait defines the interface for the creation and management of tournaments. +#[async_trait] +pub trait ArenaSender: Send + Sync { + async fn join_tournament( + &self, + tournament: Address, + final_state: Digest, + proof: MerkleProof, + left_child: Digest, + right_child: Digest, + ) -> Result<(), Box>; + + async fn advance_match( + &self, + tournament: Address, + match_id: MatchID, + left_node: Digest, + right_node: Digest, + new_left_node: Digest, + new_right_node: Digest, + ) -> Result<(), Box>; + + async fn seal_inner_match( + &self, + tournament: Address, + match_id: MatchID, + left_leaf: Digest, + right_leaf: Digest, + initial_hash: Digest, + initial_hash_proof: MerkleProof, + ) -> Result<(), Box>; + + async fn win_inner_match( + &self, + tournament: Address, + child_tournament: Address, + left_node: Digest, + right_node: Digest, + ) -> Result<(), Box>; + + async fn seal_leaf_match( + &self, + tournament: Address, + match_id: MatchID, + left_leaf: Digest, + right_leaf: Digest, + initial_hash: Digest, + initial_hash_proof: MerkleProof, + ) -> Result<(), Box>; + + async fn win_leaf_match( + &self, + tournament: Address, + match_id: MatchID, + left_node: Digest, + right_node: Digest, + proofs: MachineProof, + ) -> Result<(), Box>; + + async fn eliminate_match( + &self, + tournament: Address, + match_id: MatchID, + ) -> Result<(), Box>; +} + +#[async_trait] +impl ArenaSender for Arena { + async fn join_tournament( + &self, + tournament: Address, + final_state: Digest, + proof: MerkleProof, + left_child: Digest, + right_child: Digest, + ) -> Result<(), Box> { + let tournament = tournament::Tournament::new(tournament, self.client.clone()); + let proof = proof.iter().map(|h| -> [u8; 32] { (*h).into() }).collect(); + tournament + .join_tournament( + final_state.into(), + proof, + left_child.into(), + right_child.into(), + ) + .send() + .await? + .await?; + Ok(()) + } + + async fn advance_match( + &self, + tournament: Address, + match_id: MatchID, + left_node: Digest, + right_node: Digest, + new_left_node: Digest, + new_right_node: Digest, + ) -> Result<(), Box> { + let tournament = tournament::Tournament::new(tournament, self.client.clone()); + let match_id = tournament::Id { + commitment_one: match_id.commitment_one.into(), + commitment_two: match_id.commitment_two.into(), + }; + tournament + .advance_match( + match_id, + left_node.into(), + right_node.into(), + new_left_node.into(), + new_right_node.into(), + ) + .send() + .await? + .await?; + Ok(()) + } + + async fn seal_inner_match( + &self, + tournament: Address, + match_id: MatchID, + left_leaf: Digest, + right_leaf: Digest, + initial_hash: Digest, + initial_hash_proof: MerkleProof, + ) -> Result<(), Box> { + let tournament = + non_leaf_tournament::NonLeafTournament::new(tournament, self.client.clone()); + let match_id = non_leaf_tournament::Id { + commitment_one: match_id.commitment_one.into(), + commitment_two: match_id.commitment_two.into(), + }; + let initial_hash_proof = initial_hash_proof + .iter() + .map(|h| -> [u8; 32] { (*h).into() }) + .collect(); + tournament + .seal_inner_match_and_create_inner_tournament( + match_id, + left_leaf.into(), + right_leaf.into(), + initial_hash.into(), + initial_hash_proof, + ) + .send() + .await? + .await?; + Ok(()) + } + + async fn win_inner_match( + &self, + tournament: Address, + child_tournament: Address, + left_node: Digest, + right_node: Digest, + ) -> Result<(), Box> { + let tournament = + non_leaf_tournament::NonLeafTournament::new(tournament, self.client.clone()); + tournament + .win_inner_match(child_tournament, left_node.into(), right_node.into()) + .send() + .await? + .await?; + Ok(()) + } + + async fn seal_leaf_match( + &self, + tournament: Address, + match_id: MatchID, + left_leaf: Digest, + right_leaf: Digest, + initial_hash: Digest, + initial_hash_proof: MerkleProof, + ) -> Result<(), Box> { + let tournament = leaf_tournament::LeafTournament::new(tournament, self.client.clone()); + let match_id = leaf_tournament::Id { + commitment_one: match_id.commitment_one.into(), + commitment_two: match_id.commitment_two.into(), + }; + let initial_hash_proof = initial_hash_proof + .iter() + .map(|h| -> [u8; 32] { (*h).into() }) + .collect(); + tournament + .seal_leaf_match( + match_id, + left_leaf.into(), + right_leaf.into(), + initial_hash.into(), + initial_hash_proof, + ) + .send() + .await? + .await?; + Ok(()) + } + + async fn win_leaf_match( + &self, + tournament: Address, + match_id: MatchID, + left_node: Digest, + right_node: Digest, + proofs: MachineProof, + ) -> Result<(), Box> { + let tournament = leaf_tournament::LeafTournament::new(tournament, self.client.clone()); + let match_id = leaf_tournament::Id { + commitment_one: match_id.commitment_one.into(), + commitment_two: match_id.commitment_two.into(), + }; + tournament + .win_leaf_match( + match_id, + left_node.into(), + right_node.into(), + Bytes::from(proofs), + ) + .send() + .await? + .await?; + Ok(()) + } + + async fn eliminate_match( + &self, + tournament: Address, + match_id: MatchID, + ) -> Result<(), Box> { + let tournament = tournament::Tournament::new(tournament, self.client.clone()); + let match_id = tournament::Id { + commitment_one: match_id.commitment_one.into(), + commitment_two: match_id.commitment_two.into(), + }; + tournament + .eliminate_match_by_timeout(match_id) + .send() + .await? + .await?; + Ok(()) + } +} + +/// This struct is used to communicate the creation of a new tournament. +#[derive(Clone, Copy)] +pub struct TournamentCreatedEvent { + pub parent_match_id_hash: Digest, + pub new_tournament_address: Address, +} + +/// This struct is used to communicate the enrollment of a new commitment. +#[derive(Clone, Copy)] +pub struct CommitmentJoinedEvent { + pub root: Digest, +} + +/// This struct is used to communicate the creation of a new match. +#[derive(Clone, Copy)] +pub struct MatchCreatedEvent { + pub id: MatchID, + pub left_hash: Digest, +} + +/// Struct used to identify a match. +#[derive(Clone, Copy)] +pub struct MatchID { + pub commitment_one: Digest, + pub commitment_two: Digest, +} + +impl MatchID { + /// Generates a new [Digest] + pub fn hash(&self) -> Digest { + self.commitment_one.join(&self.commitment_two) + } +} + +/// Struct used to communicate the state of a commitment. +#[derive(Clone, Copy)] +pub struct CommitmentState { + pub clock: ClockState, + pub final_state: Digest, + pub latest_match: Option, +} + +/// Struct used to communicate the state of a clock. +#[derive(Clone, Copy)] +pub struct ClockState { + pub allowance: u64, + pub start_instant: u64, + pub block_time: U256, +} + +impl ClockState { + pub fn has_time(&self) -> bool { + if self.start_instant == 0 { + true + } else { + self.deadline() > self.block_time.as_u64() + } + } + + pub fn time_since_timeout(&self) -> u64 { + if self.start_instant == 0 { + 0 + } else { + self.block_time.as_u64() - self.deadline() + } + } + + // deadline of clock if it's ticking + fn deadline(&self) -> u64 { + self.start_instant + self.allowance + } +} + +impl std::fmt::Display for ClockState { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + if self.start_instant == 0 { + write!(f, "clock paused, {} seconds left", self.allowance) + } else { + let time_elapsed = self.block_time.as_u64() - self.start_instant; + if self.allowance >= time_elapsed { + write!( + f, + "clock ticking, {} seconds left", + self.allowance - time_elapsed + ) + } else { + write!( + f, + "clock ticking, {} seconds overdue", + time_elapsed - self.allowance + ) + } + } + } +} + +/// Enum used to represent the winner of a tournament. +#[derive(Clone, PartialEq)] +pub enum TournamentWinner { + Root(Digest, Digest), + Inner(Digest, Digest), +} + +/// Struct used to communicate the state of a tournament. +#[derive(Clone)] +pub struct TournamentState { + pub address: Address, + pub base_big_cycle: u64, + pub level: u64, + pub parent: Option
, + pub commitment_states: HashMap, + pub matches: Vec, + pub winner: Option, +} + +impl TournamentState { + pub fn new_root(address: Address) -> Self { + TournamentState { + address, + base_big_cycle: 0, + level: constants::LEVELS, + parent: None, + commitment_states: HashMap::new(), + matches: vec![], + winner: None, + } + } + + pub fn new_inner(address: Address, level: u64, base_big_cycle: u64, parent: Address) -> Self { + TournamentState { + address, + base_big_cycle, + level, + parent: Some(parent), + commitment_states: HashMap::new(), + matches: vec![], + winner: None, + } + } +} + +/// Struct used to communicate the state of a match. +#[derive(Clone, Copy)] +pub struct MatchState { + pub id: MatchID, + pub other_parent: Digest, + pub left_node: Digest, + pub right_node: Digest, + pub running_leaf_position: u64, + pub current_height: u64, + pub level: u64, + pub leaf_cycle: u64, + pub base_big_cycle: u64, + pub tournament_address: Address, + pub inner_tournament: Option
, +} diff --git a/offchain/core/src/arena/config.rs b/offchain/core/src/arena/config.rs new file mode 100644 index 00000000..068c8d39 --- /dev/null +++ b/offchain/core/src/arena/config.rs @@ -0,0 +1,8 @@ +//! Module for configuration of an Arena. + +#[derive(Debug, Clone)] +pub struct ArenaConfig { + pub web3_rpc_url: String, + pub web3_chain_id: u64, + pub web3_private_key: String, +} diff --git a/offchain/core/src/arena/mod.rs b/offchain/core/src/arena/mod.rs new file mode 100644 index 00000000..edd38582 --- /dev/null +++ b/offchain/core/src/arena/mod.rs @@ -0,0 +1,9 @@ +//! This module defines the struct [Reader] that is responsible for the reading the states +//! of tournaments; and the struct [Sender] that is responsible for the sending transactions +//! to tournaments + +mod config; +pub use config::*; + +mod arena; +pub use arena::*; diff --git a/offchain/core/src/contract/mod.rs b/offchain/core/src/contract/mod.rs new file mode 100644 index 00000000..cd883957 --- /dev/null +++ b/offchain/core/src/contract/mod.rs @@ -0,0 +1,5 @@ +pub mod leaf_tournament; +pub mod non_leaf_tournament; +pub mod non_root_tournament; +pub mod root_tournament; +pub mod tournament; diff --git a/offchain/core/src/lib.rs b/offchain/core/src/lib.rs new file mode 100644 index 00000000..8db4c52d --- /dev/null +++ b/offchain/core/src/lib.rs @@ -0,0 +1,9 @@ +//! `cartesi-compute-core` is a crate that defines a lot of data structures for the creation of Merkle +//! trees and tournaments using the Cartesi Machine. + +pub mod arena; +pub mod contract; +pub mod machine; +pub mod merkle; +pub mod strategy; +pub mod utils; diff --git a/offchain/core/src/machine/commitment.rs b/offchain/core/src/machine/commitment.rs new file mode 100644 index 00000000..e7e294cf --- /dev/null +++ b/offchain/core/src/machine/commitment.rs @@ -0,0 +1,164 @@ +//! This module defines a struct [MachineCommitment] that is used to represent a `computation hash` +//! described on the paper https://arxiv.org/pdf/2212.12439.pdf. + +use std::{error::Error, ops::ControlFlow, sync::Arc}; + +use crate::{ + machine::{constants, MachineRpc}, + merkle::{Digest, MerkleBuilder, MerkleTree, UInt}, + utils::arithmetic, +}; + +/// The [MachineCommitment] struct represents a `computation hash`, that is a [MerkleTree] of a set +/// of steps of the Cartesi Machine. +#[derive(Clone, Debug)] +pub struct MachineCommitment { + pub implicit_hash: Digest, + pub merkle: Arc, +} + +/// Builds a [MachineCommitment] from a [MachineRpc] and a base cycle. +pub async fn build_machine_commitment( + machine: &mut MachineRpc, + base_cycle: u64, + log2_stride: u64, + log2_stride_count: u64, +) -> Result> { + if log2_stride >= constants::LOG2_UARCH_SPAN { + assert!( + log2_stride + log2_stride_count + <= constants::LOG2_EMULATOR_SPAN + constants::LOG2_UARCH_SPAN + ); + build_big_machine_commitment(machine, base_cycle, log2_stride, log2_stride_count).await + } else { + assert!(log2_stride == 0); + build_small_machine_commitment(machine, base_cycle, log2_stride_count).await + } +} + +/// Builds a [MachineCommitment] Hash for the Cartesi Machine using the big machine model. +pub async fn build_big_machine_commitment( + machine: &mut MachineRpc, + base_cycle: u64, + log2_stride: u64, + log2_stride_count: u64, +) -> Result> { + machine.run(base_cycle).await?; + let initial_state = machine.machine_state().await?; + + let mut builder = MerkleBuilder::default(); + let instruction_count = arithmetic::max_uint(log2_stride_count); + + for instruction in 0..=instruction_count { + let control_flow = advance_instruction( + instruction, + log2_stride, + machine, + base_cycle, + &mut builder, + instruction_count, + ) + .await?; + if let ControlFlow::Break(_) = control_flow { + break; + } + } + + let merkle = builder.build(); + + Ok(MachineCommitment { + implicit_hash: initial_state.root_hash, + merkle: Arc::new(merkle), + }) +} + +async fn advance_instruction( + instruction: u64, + log2_stride: u64, + machine: &mut MachineRpc, + base_cycle: u64, + builder: &mut MerkleBuilder, + instruction_count: u64, +) -> Result, Box> { + let cycle = (instruction + 1) << (log2_stride - constants::LOG2_UARCH_SPAN); + machine.run(base_cycle + cycle).await?; + let state = machine.machine_state().await?; + let control_flow = if state.halted { + builder.add_with_repetition( + state.root_hash, + UInt::from(instruction_count - instruction + 1), + ); + ControlFlow::Break(()) + } else { + builder.add(state.root_hash); + ControlFlow::Continue(()) + }; + Ok(control_flow) +} + +pub async fn build_small_machine_commitment( + machine: &mut MachineRpc, + base_cycle: u64, + log2_stride_count: u64, +) -> Result> { + machine.run(base_cycle).await?; + let initial_state = machine.machine_state().await?; + + let mut builder = MerkleBuilder::default(); + let instruction_count = arithmetic::max_uint(log2_stride_count - constants::LOG2_UARCH_SPAN); + let mut instruction = 0; + loop { + if instruction > instruction_count { + break; + } + + builder.add_tree(run_uarch_span(machine).await?); + instruction += 1; + + let state = machine.machine_state().await?; + if state.halted { + builder.add_tree_with_repetition( + run_uarch_span(machine).await?, + UInt::from(instruction_count - instruction + 1), + ); + break; + } + } + let merkle = builder.build(); + + Ok(MachineCommitment { + implicit_hash: initial_state.root_hash, + merkle: Arc::new(merkle), + }) +} + +async fn run_uarch_span(machine: &mut MachineRpc) -> Result> { + let (_, ucycle) = machine.position(); + assert!(ucycle == 0); + + machine.increment_uarch().await?; + + let mut builder = MerkleBuilder::default(); + let mut i = 0; + + let mut state = loop { + let mut state = machine.machine_state().await?; + builder.add_with_repetition(state.root_hash, 1); + + machine.increment_uarch().await?; + i += 1; + + state = machine.machine_state().await?; + if state.uhalted { + break state; + } + }; + + builder.add_with_repetition(state.root_hash, UInt::from(constants::UARCH_SPAN - i)); + + machine.ureset().await?; + state = machine.machine_state().await?; + builder.add_with_repetition(state.root_hash, 1); + + Ok(builder.build()) +} diff --git a/offchain/core/src/machine/commitment_builder.rs b/offchain/core/src/machine/commitment_builder.rs new file mode 100644 index 00000000..a63b80ce --- /dev/null +++ b/offchain/core/src/machine/commitment_builder.rs @@ -0,0 +1,56 @@ +//! The builder of machine commitments [MachineCommitmentBuilder] is responsible for building the +//! [MachineCommitment]. It is used by the [Arena] to build the commitments of the tournaments. + +use crate::machine::{build_machine_commitment, constants, MachineCommitment, MachineFactory}; +use std::{ + collections::{hash_map::Entry, HashMap}, + error::Error, +}; + +pub struct CachingMachineCommitmentBuilder { + machine_factory: MachineFactory, + machine_path: String, + commitments: HashMap>, +} + +impl CachingMachineCommitmentBuilder { + pub fn new(machine_factory: MachineFactory, machine_path: String) -> Self { + CachingMachineCommitmentBuilder { + machine_factory, + machine_path, + commitments: HashMap::new(), + } + } + + pub async fn build_commitment( + &mut self, + base_cycle: u64, + level: u64, + ) -> Result> { + assert!(level <= constants::LEVELS, "level out of bounds"); + + if let Entry::Vacant(e) = self.commitments.entry(level) { + e.insert(HashMap::new()); + } else if self.commitments[&level].contains_key(&base_cycle) { + return Ok(self.commitments[&level][&base_cycle].clone()); + } + + let l = constants::LEVELS - level; + let log2_stride = constants::LOG2_STEP[l as usize]; + let log2_stride_count = constants::HEIGHTS[l as usize]; + let mut machine = self + .machine_factory + .create_machine(&self.machine_path) + .await?; + let commitment = + build_machine_commitment(&mut machine, base_cycle, log2_stride, log2_stride_count) + .await?; + + self.commitments + .entry(level) + .or_default() + .insert(base_cycle, commitment.clone()); + + Ok(commitment) + } +} diff --git a/offchain/core/src/machine/constants.rs b/offchain/core/src/machine/constants.rs new file mode 100644 index 00000000..3559630e --- /dev/null +++ b/offchain/core/src/machine/constants.rs @@ -0,0 +1,13 @@ +use crate::utils::arithmetic; + +pub const LEVELS: u64 = 3; +pub const MAX_CYCLE: u64 = 63; + +pub const LOG2_STEP: [u64; 3] = [31, 16, 0]; +pub const HEIGHTS: [u64; 3] = [32, 15, 16]; + +pub const LOG2_UARCH_SPAN: u64 = 16; +pub const UARCH_SPAN: u64 = arithmetic::max_uint(LOG2_UARCH_SPAN); + +pub const LOG2_EMULATOR_SPAN: u64 = 47; +pub const EMULATOR_SPAN: u64 = arithmetic::max_uint(LOG2_EMULATOR_SPAN); diff --git a/offchain/core/src/machine/mod.rs b/offchain/core/src/machine/mod.rs new file mode 100644 index 00000000..21434dcf --- /dev/null +++ b/offchain/core/src/machine/mod.rs @@ -0,0 +1,14 @@ +//! Module for communication with the Cartesi machine using RPC and construction of computation +//! hashes. + +#[doc(hidden)] +pub mod constants; + +pub mod rpc; +pub use rpc::*; + +mod commitment; +pub use commitment::*; + +mod commitment_builder; +pub use commitment_builder::*; diff --git a/offchain/core/src/machine/rpc.rs b/offchain/core/src/machine/rpc.rs new file mode 100644 index 00000000..4af312ca --- /dev/null +++ b/offchain/core/src/machine/rpc.rs @@ -0,0 +1,316 @@ +//! Module for communication with the Cartesi machine using RPC. + +use base64::engine::general_purpose::STANDARD; +use base64::Engine; +use cartesi_machine_json_rpc::client::{ + AccessLog, AccessLogType, AccessType, Error, JsonRpcCartesiMachineClient, MachineRuntimeConfig, +}; +use sha3::{Digest as Keccak256Digest, Keccak256}; + +use crate::{machine::constants, merkle::Digest, utils::arithmetic}; + +#[derive(Debug)] +pub struct MachineState { + pub root_hash: Digest, + pub halted: bool, + pub uhalted: bool, +} + +impl std::fmt::Display for MachineState { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!( + f, + "{{root_hash = {:?}, halted = {}, uhalted = {}}}", + self.root_hash, self.halted, self.uhalted + ) + } +} + +pub type MachineProof = Vec; + +pub struct MachineRpc { + rpc_client: JsonRpcCartesiMachineClient, + root_hash: Digest, + start_cycle: u64, + cycle: u64, + ucycle: u64, +} + +impl MachineRpc { + pub async fn new(json_rpc_url: &str, snapshot_path: &str) -> Result { + let rpc_client = JsonRpcCartesiMachineClient::new(json_rpc_url.to_string()).await?; + + rpc_client + .load_machine(snapshot_path, &MachineRuntimeConfig::default()) + .await?; + + let root_hash = rpc_client.get_root_hash().await?; + let start_cycle = rpc_client.read_csr("mcycle".to_string()).await?; + + // Machine can never be advanced on the micro arch. + // Validators must verify this first + assert_eq!(rpc_client.read_csr("uarch_cycle".to_string()).await?, 0); + + Ok(MachineRpc { + rpc_client, + start_cycle, + root_hash: Digest::from(root_hash), + cycle: 0, + ucycle: 0, + }) + } + + pub fn root_hash(&self) -> Digest { + self.root_hash + } + + // pub async fn get_logs(&self, cycle: u64, ucycle: u64) -> Result { + pub async fn get_logs(&mut self, cycle: u64, ucycle: u64) -> Result { + self.run(cycle).await?; + self.run_uarch(ucycle).await?; + + if ucycle == constants::UARCH_SPAN { + self.run_uarch(constants::UARCH_SPAN).await?; + eprintln!("ureset, not implemented"); + } + + let access_log = AccessLogType { + annotations: true, + proofs: true, + }; + let logs = self.rpc_client.step(&access_log, false).await?; + + // let mut encoded = Vec::new(); + + // for a in &logs.accesses { + // assert_eq!(a.log2_size, 3); + // if a.r#type == AccessType::Read { + // encoded.push(a.read_data.clone()); + // } + + // encoded.push(STANDARD.decode(a.proof.target_hash.clone()).unwrap()); + + // let decoded_sibling_hashes: Result>, hex::FromHexError> = + // a.proof.sibling_hashes.iter().map(STANDARD.decode).collect(); + + // let mut decoded = decoded_sibling_hashes?; + // decoded.reverse(); + // encoded.extend_from_slice(&decoded.clone()); + + // assert_eq!( + // ver( + // STANDARD.decode(a.proof.target_hash.clone()).unwrap(), + // a.address, + // decoded.clone() + // ), + // STANDARD.decode(a.proof.root_hash.clone()).unwrap() + // ); + // } + // let data: Vec = encoded.iter().flatten().cloned().collect(); + + // let hex_data = hex::encode(data); + + // Ok(format!("\"{}\"", hex_data)) + + Ok(encode_access_log(&logs)) + } + + pub async fn generate_proof(&mut self, cycle: u64, ucycle: u64) -> Result { + self.rpc_client.run(cycle).await?; + self.rpc_client.run_uarch(ucycle).await?; + + if ucycle == constants::UARCH_SPAN { + self.rpc_client.run_uarch(constants::UARCH_SPAN).await?; + // TODO: log warn/error or retrn error. + eprintln!("ureset, not implemented"); + } + + let log_type = AccessLogType { + annotations: true, + proofs: true, + }; + let log = self.rpc_client.step(&log_type, false).await?; + + Ok(encode_access_log(&log)) + } + + pub async fn run(&mut self, cycle: u64) -> Result<(), Error> { + assert!(self.cycle <= cycle); + + let physical_cycle = add_and_clamp(self.start_cycle, cycle); + + loop { + let halted = self.rpc_client.read_iflags_h().await?; + if halted { + break; + } + + let mcycle = self.rpc_client.read_csr("mcycle".to_string()).await?; + if mcycle == physical_cycle { + break; + } + + self.rpc_client.run(physical_cycle).await?; + } + + self.cycle = cycle; + + Ok(()) + } + + pub async fn run_uarch(&mut self, ucycle: u64) -> Result<(), Error> { + assert!( + self.ucycle <= ucycle, + "{}", + format!("{}, {}", self.ucycle, ucycle) + ); + + self.rpc_client.run_uarch(ucycle).await?; + self.ucycle = ucycle; + + Ok(()) + } + + pub async fn increment_uarch(&mut self) -> Result<(), Error> { + self.rpc_client.run_uarch(self.ucycle + 1).await?; + self.ucycle += 1; + Ok(()) + } + + pub async fn ureset(&mut self) -> Result<(), Error> { + self.rpc_client.reset_uarch_state().await?; + self.cycle += 1; + self.ucycle = 0; + Ok(()) + } + + pub async fn machine_state(&self) -> Result { + let root_hash = self.rpc_client.get_root_hash().await?; + let halted = self.rpc_client.read_iflags_h().await?; + let uhalted = self.rpc_client.read_uarch_halt_flag().await?; + + Ok(MachineState { + root_hash: Digest::new(root_hash), + halted, + uhalted, + }) + } + + pub async fn write_memory(&self, address: u64, data: String) -> Result { + self.rpc_client.write_memory(address, data).await + } + + pub fn position(&self) -> (u64, u64) { + (self.cycle, self.ucycle) + } +} + +fn add_and_clamp(x: u64, y: u64) -> u64 { + if x < arithmetic::max_uint(64) - y { + x + y + } else { + arithmetic::max_uint(64) + } +} + +fn encode_access_log(log: &AccessLog) -> Vec { + let mut encoded = Vec::new(); + + for a in log.accesses.iter() { + assert_eq!(a.log2_size, 3); + if a.r#type == AccessType::Read { + encoded.push(a.read_data.clone()); + } + + encoded.push( + STANDARD + .decode(base64_hash_to_string(&a.proof.target_hash)) + .unwrap(), + ); + + let mut decoded_sibling_hashes: Vec> = a + .proof + .sibling_hashes + .iter() + .map(base64_hash_to_string) + .map(|s| STANDARD.decode(s).unwrap()) + .collect(); + + decoded_sibling_hashes.reverse(); + encoded.extend_from_slice(&decoded_sibling_hashes.clone()); + + assert_eq!( + ver( + STANDARD + .decode(base64_hash_to_string(&a.proof.target_hash)) + .unwrap(), + a.address, + decoded_sibling_hashes.clone() + ), + STANDARD + .decode(base64_hash_to_string(&a.proof.root_hash)) + .unwrap() + ); + } + + encoded.iter().flatten().cloned().collect() +} + +fn base64_hash_to_string(base64_hash: &cartesi_machine_json_rpc::interfaces::Base64Hash) -> String { + let mut res = base64_hash.clone(); + + if res.ends_with('\n') { + res.pop(); + } + + res +} + +fn ver(mut t: Vec, p: u64, s: Vec>) -> Vec { + let stride = p >> 3; + for (k, v) in s.iter().enumerate() { + if (stride >> k) % 2 == 0 { + let mut keccak = Keccak256::new(); + keccak.update(&t); + keccak.update(v); + t = keccak.finalize().to_vec(); + } else { + let mut keccak = Keccak256::new(); + keccak.update(v); + keccak.update(&t); + t = keccak.finalize().to_vec(); + } + } + t +} + +#[derive(Clone)] +pub struct MachineFactory { + rpc_host: String, + + #[allow(dead_code)] + rpc_port: u32, + + rpc_client: JsonRpcCartesiMachineClient, +} + +impl MachineFactory { + pub async fn new(rpc_host: String, rpc_port: u32) -> Result { + let rpc_url = format!("{}:{}", rpc_host, rpc_port); + let rpc_client = JsonRpcCartesiMachineClient::new(rpc_url).await?; + Ok(Self { + rpc_host, + rpc_port, + rpc_client, + }) + } + + pub async fn create_machine(&self, snapshot_path: &str) -> Result { + let fork_rpc_url = self.rpc_client.fork().await?; + let fork_rpc_port = fork_rpc_url.split(':').last().unwrap(); + let fork_rpc_url = format!("{}:{}", self.rpc_host, fork_rpc_port); + let machine_rpc = MachineRpc::new(fork_rpc_url.as_str(), snapshot_path).await?; + + Ok(machine_rpc) + } +} diff --git a/offchain/core/src/merkle/digest/keccak.rs b/offchain/core/src/merkle/digest/keccak.rs new file mode 100644 index 00000000..a53affc8 --- /dev/null +++ b/offchain/core/src/merkle/digest/keccak.rs @@ -0,0 +1,24 @@ +//! Keccak256 hash for the Digest Type. It's used to hash the data in the Digest. + +use sha3::{Keccak256, Digest as Keccak256Digest}; + +use super::Digest; + +impl Digest { + /// Computes the Keccak256 hash of the given data and returns a new Digest. + pub fn from_data(data: &[u8]) -> Digest { + let mut keccak = Keccak256::new(); + keccak.update(data); + let digest: [u8; 32] = keccak.finalize().into(); + Digest::from(digest) + } + + /// Joins the current Digest with another Digest to create a new Digest. + pub fn join(&self, digest: &Digest) -> Digest { + let mut keccak = Keccak256::new(); + keccak.update(self.data); + keccak.update(digest.data); + let digest: [u8; 32] = keccak.finalize().into(); + Digest::from(digest) + } +} \ No newline at end of file diff --git a/offchain/core/src/merkle/digest/mod.rs b/offchain/core/src/merkle/digest/mod.rs new file mode 100644 index 00000000..ab64b5b0 --- /dev/null +++ b/offchain/core/src/merkle/digest/mod.rs @@ -0,0 +1,79 @@ +//! Definition of the [Digest] type and its associated methods. A digest is the output of a hash +//! function. It's used to identify the data in the MerkleTree. + +use hex::FromHex; +use std::fmt; + +pub mod keccak; + +use hex; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum DigestError { + #[error("Invalid digest data length")] + InvalidDigestLength, +} + +/// The output of a hash function. +#[derive(Eq, Hash, PartialEq, Clone, Copy, Debug)] +pub struct Digest { + data: [u8; 32], +} + +impl Digest { + /// Creates a new [Digest] with the provided 32-byte data. + pub fn new(data: [u8; 32]) -> Self { + Digest { data } + } + + /// Attempts to create a [Digest] from a Vec containing 32 bytes of data. + pub fn from_digest(digest_data: &[u8]) -> Result { + if digest_data.len() != 32 { + return Err(DigestError::InvalidDigestLength); + } + + let mut data = [0u8; 32]; + data.copy_from_slice(digest_data); + Ok(Digest::new(data)) + } + + /// Attempts to create a [Digest] from a hexadecimal string. + pub fn from_digest_hex(digest_hex: &str) -> Result { + let data = Vec::from_hex(digest_hex).map_err(|_| DigestError::InvalidDigestLength)?; + Self::from_digest(&data) + } + + /// Converts the [Digest] to a hexadecimal string. + pub fn to_hex(&self) -> String { + hex::encode(self.data) + } + + /// Creates a [Digest] with all bytes set to zero. + pub fn zeroed() -> Self { + Digest::new([0; 32]) + } + + /// Checks if the [Digest] is zeroed. + pub fn is_zeroed(&self) -> bool { + self.data.iter().all(|&x| x == 0) + } +} + +impl From<[u8; 32]> for Digest { + fn from(data: [u8; 32]) -> Self { + Digest { data } + } +} + +impl From for [u8; 32] { + fn from(hash: Digest) -> Self { + hash.data + } +} + +impl fmt::Display for Digest { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.to_hex()) + } +} diff --git a/offchain/core/src/merkle/mod.rs b/offchain/core/src/merkle/mod.rs new file mode 100644 index 00000000..5562ca85 --- /dev/null +++ b/offchain/core/src/merkle/mod.rs @@ -0,0 +1,25 @@ +//! This module exposes a bunch of structures for creating and managing [MerkleTree]. To create a new +//! [MerkleTree] you need to use the [MerkleBuilder] struct. With a MerkleTree you can create a +//! [MerkleProof] and verify it. +//! +//! # Examples +//! ```rust +//! let mut builder = MerkleBuilder::default(); +//! builder.add(Digest::zeroed(), 2); +//! builder.add(Digest::zeroed(),0u128.wrapping_sub(2)); +//! let merkle = builder.build(); +//! assert_eq!(merkle.root_hash(), builder.iterated_merkle(Digest::zeroed(), 128)); +//! ``` +//! + +mod digest; +pub use digest::*; + +mod node; +pub use node::*; + +mod tree; +pub use tree::*; + +mod tree_builder; +pub use tree_builder::*; diff --git a/offchain/core/src/merkle/node.rs b/offchain/core/src/merkle/node.rs new file mode 100644 index 00000000..500166f9 --- /dev/null +++ b/offchain/core/src/merkle/node.rs @@ -0,0 +1,39 @@ +//! Module for a node in a Merkle tree. It can be either a leaf or an inner node. +//! Inner nodes have two children, which are also Merkle tree nodes but here +//! we only store their hashes. + +use crate::merkle::Digest; + +/// A node in a merkle tree. It can be either a leaf or an inner node. +#[derive(Clone, Debug)] +pub struct MerkleTreeNode { + pub digest: Digest, + children: Option<(Digest, Digest)>, +} + +impl MerkleTreeNode { + /// Creates a new Merkle tree node with the given digest. + pub fn new(left: Digest, right: Digest) -> Self { + MerkleTreeNode { + digest: left.join(&right), + children: Some((left, right)), + } + } + + pub fn from_digest(digest: Digest) -> Self { + MerkleTreeNode { + digest, + children: None, + } + } + + /// Sets the children of the node. + pub(crate) fn set_children(&mut self, left: Digest, right: Digest) { + self.children = Some((left, right)); + } + + /// Retrieves the children of the node. + pub fn children(&self) -> Option<(Digest, Digest)> { + self.children + } +} diff --git a/offchain/core/src/merkle/tree.rs b/offchain/core/src/merkle/tree.rs new file mode 100644 index 00000000..31ec82f8 --- /dev/null +++ b/offchain/core/src/merkle/tree.rs @@ -0,0 +1,208 @@ +//! This module contains the [MerkleTree] struct and related types like the +//! [MerkleProof]. + +use std::collections::HashMap; + +use crate::merkle::{Digest, MerkleTreeNode}; + +use super::UInt; + +/// A leaf of a [MerkleTree], it contains the offset of the leaf in the tree, +/// and the hash of the data. +#[derive(Clone, Debug)] +pub struct MerkleTreeLeaf { + pub node: Digest, + pub accumulated_count: UInt, + pub log2_size: Option, +} + +/// A [MerkleProof] is used to verify that a leaf is part of a [MerkleTree]. +pub type MerkleProof = Vec; + +struct ProofAccumulator { + pub leaf: Digest, + pub proof: MerkleProof, +} + +impl Default for ProofAccumulator { + fn default() -> Self { + ProofAccumulator { + leaf: Digest::zeroed(), + proof: Vec::new(), + } + } +} + +/// A [MerkleTree] is a binary tree where the leafs are the data and the nodes +/// are the hashes of the children. The root of the tree is the hash of the +/// entire tree. The tree is balanced, so the height of the tree is log2(n) +/// where n is the number of leafs. +#[derive(Clone, Debug)] +pub struct MerkleTree { + log2_size: u32, + root: Digest, + leafs: Vec, + nodes: HashMap, +} + +impl MerkleTree { + pub fn new( + log2_size: u32, + root: Digest, + leafs: Vec, + nodes: HashMap, + ) -> Self { + MerkleTree { + log2_size, + root, + leafs, + nodes, + } + } + + pub fn root_hash(&self) -> Digest { + self.root + } + + pub fn root_children(&self) -> (Digest, Digest) { + self.node_children(self.root) + .expect("root does not have children") + } + + pub fn node_children(&self, digest: Digest) -> Option<(Digest, Digest)> { + match self.nodes.get(&digest) { + Some(node) => node.children(), + None => None, + } + } + + pub fn nodes(&self) -> HashMap { + self.nodes.clone() + } + + pub fn log2_size(&self) -> u32 { + self.log2_size.clone() + } + + pub fn prove_leaf(&self, index: u64) -> (Digest, MerkleProof) { + let height = self.calculate_height(); + + assert!(index.wrapping_shr(height) == 0); + + let mut proof_acc = ProofAccumulator::default(); + + self.proof( + &mut proof_acc, + self.nodes.get(&self.root).expect("root does not exist"), + height as u64, + index, + ); + + (proof_acc.leaf, proof_acc.proof) + } + + fn calculate_height(&self) -> u32 { + let mut height = self.log2_size; + + if let Some(leaf) = self.leafs.get(0) { + if let Some(log2_size) = leaf.log2_size { + height = log2_size + self.log2_size; + } + } + + height + } + + fn proof( + &self, + proof_acc: &mut ProofAccumulator, + root: &MerkleTreeNode, + height: u64, + include_index: u64, + ) { + if height == 0 { + proof_acc.leaf = root.digest; + return; + } + + let new_height = height - 1; + let (left, right) = root.children().expect("root does not have children"); + let left = self.nodes.get(&left).expect("left child does not exist"); + let right = self.nodes.get(&right).expect("right child does not exist"); + + if (include_index.wrapping_shr(new_height as u32)) & 1 == 0 { + self.proof(proof_acc, left, new_height, include_index); + proof_acc.proof.push(left.digest); + } else { + self.proof(proof_acc, right, new_height, include_index); + proof_acc.proof.push(right.digest); + } + } + + pub fn last(&self) -> (Digest, MerkleProof) { + let mut proof = Vec::new(); + let mut children = Some(self.root_children()); + let mut old_right = self.root; + + while let Some((left, right)) = children { + proof.push(left); + old_right = right; + children = self.node_children(right); + } + + proof.reverse(); + + (old_right, proof) + } +} + +#[cfg(test)] +mod tests { + use crate::merkle::Digest; + + #[test] + pub fn test_tree() { + let mut builder = crate::merkle::MerkleBuilder::default(); + builder.add_with_repetition(Digest::zeroed(), 2); + builder.add_with_repetition(Digest::zeroed(), 2u128.pow(64) - 2); + let tree = builder.build(); + + let proof = tree.prove_leaf(0); + assert_eq!(proof.0, Digest::zeroed()); + } + + #[test] + pub fn proof_test() { + let mut builder = crate::merkle::MerkleBuilder::default(); + builder.add_with_repetition(Digest::zeroed(), 8); + let tree = builder.build(); + + let (leaf, proof) = tree.prove_leaf(0); + + let mut root = leaf; + + for node in proof { + root = Digest::join(&node, &root); + } + + assert_eq!(root, tree.root_hash()); + } + + #[test] + pub fn last_proof_test() { + let mut builder = crate::merkle::MerkleBuilder::default(); + builder.add_with_repetition(Digest::zeroed(), 2); + builder.add_with_repetition(Digest::zeroed(), 2u128.pow(64) - 2); + let tree = builder.build(); + + let (leaf, proof) = tree.last(); + + let mut root = leaf; + + for node in proof { + root = Digest::join(&node, &root); + } + + assert_eq!(root, tree.root_hash()); + } +} diff --git a/offchain/core/src/merkle/tree_builder.rs b/offchain/core/src/merkle/tree_builder.rs new file mode 100644 index 00000000..60973e16 --- /dev/null +++ b/offchain/core/src/merkle/tree_builder.rs @@ -0,0 +1,236 @@ +//! Module for building merkle trees from leafs. + +use std::collections::HashMap; + +use crate::merkle::{Digest, MerkleTree, MerkleTreeLeaf, MerkleTreeNode}; + +pub type UInt = u128; + +/// A [MerkleBuilder] is used to build a [MerkleTree] from its leafs. +#[derive(Debug, Default)] +pub struct MerkleBuilder { + leafs: Vec, + trees: Vec, + nodes: HashMap, + interned: HashMap>, +} + +impl MerkleBuilder { + /// Adds a new leaf to the merkle tree. The leaf is represented by a MerkleTree + pub fn add_tree(&mut self, tree: MerkleTree) { + self.add_tree_with_repetition(tree, 1); + } + + /// Adds a new leaf to the merkle tree. The leaf is represented by a MerkleTree and its repetition. + pub fn add_tree_with_repetition(&mut self, tree: MerkleTree, rep: UInt) { + assert!(rep != 0, "repetition is zero"); + + let root_hash = tree.root_hash(); + self.add_new_node(root_hash); + + let count = self.calculate_accumulated_count(rep); + + self.leafs.push(MerkleTreeLeaf { + node: root_hash, + accumulated_count: count, + log2_size: Some(tree.log2_size()), + }); + self.trees.push(tree); + } + + /// Adds a new leaf to the merkle tree. The leaf is represented by its digest. + pub fn add(&mut self, digest: Digest) { + self.add_with_repetition(digest, 1); + } + + /// Adds a new leaf to the merkle tree. The leaf is represented by its + /// digest and its repetition. + pub fn add_with_repetition(&mut self, digest: Digest, rep: UInt) { + assert!(rep != 0, "repetition is zero"); + + self.add_new_node(digest); + + let count = self.calculate_accumulated_count(rep); + + self.leafs.push(MerkleTreeLeaf { + node: digest, + accumulated_count: count, + log2_size: None, + }); + } + + fn calculate_accumulated_count(&mut self, rep: UInt) -> UInt { + if let Some(last) = self.leafs.last() { + assert!(last.accumulated_count != 0, "merkle builder is full"); + let accumulated_count = rep.wrapping_add(last.accumulated_count); + if rep >= accumulated_count { + assert_eq!(accumulated_count, 0); + } + accumulated_count + } else { + rep + } + } + + fn add_new_node(&mut self, digest: Digest) { + if !self.nodes.contains_key(&digest) { + let node = MerkleTreeNode::from_digest(digest); + self.nodes.insert(node.digest, node.clone()); + self.interned.insert(node.digest, vec![node.digest]); + } + } + + /// Builds the merkle tree from the leafs. + pub fn build(&mut self) -> MerkleTree { + let last = self.leafs.last().expect("no leafs in merkle builder"); + let count = last.accumulated_count; + + assert!(count.is_power_of_two(), "is not a power of two {}", count); + let log2_size = count.trailing_zeros(); + + let leafs_clone = self.leafs.clone(); + let root = self.build_merkle(leafs_clone.as_slice(), log2_size, 0); + + for tree in self.trees.clone() { + self.nodes.extend(tree.nodes()); + } + MerkleTree::new(log2_size, root.0, self.leafs.clone(), self.nodes.clone()) + } + + fn build_merkle( + &mut self, + leafs: &[MerkleTreeLeaf], + log2_size: u32, + stride: UInt, + ) -> (Digest, UInt, UInt) { + let first_time = stride * (UInt::from(1u8).wrapping_shl(log2_size)) + 1; + let last_time = (stride + 1) * (UInt::from(1u8).wrapping_shl(log2_size)); + + let first_cell = find_cell_containing(leafs, first_time); + let last_cell = find_cell_containing(leafs, last_time); + + if first_cell == last_cell { + let node = leafs[first_cell as usize].node; + let iterated = self.iterated_merkle(node, log2_size); + return (iterated, first_time, last_time); + } + + let left = self.build_merkle( + &leafs[first_cell as usize..(last_cell + 1) as usize], + log2_size - 1, + stride << 1, + ); + let right = self.build_merkle( + &leafs[first_cell as usize..(last_cell + 1) as usize], + log2_size - 1, + (stride << 1) + 1, + ); + + let result = self.join_nodes(left.0, right.0); + (result, first_time, last_time) + } + + /// Builds the iterated merkle tree from the given node and level. + pub fn iterated_merkle(&mut self, node: Digest, level: u32) -> Digest { + let iterated = self.interned.get(&node).expect("interned not found"); + if let Some(node) = iterated.get(level as usize) { + return *node; + } + self.build_iterated_merkle(node, level) + } + + fn build_iterated_merkle(&mut self, node: Digest, level: u32) -> Digest { + let iterated = self.interned.get(&node).expect("interned not found"); + let mut i = iterated.len() - 1; + let mut highest_level = *iterated.get(i).expect("iterated not found"); + + while i < level as usize { + highest_level = self.join_nodes(highest_level, highest_level); + i += 1; + self.interned.get_mut(&node).unwrap().push(highest_level); + } + + highest_level + } + + fn join_nodes(&mut self, left: Digest, right: Digest) -> Digest { + let digest = left.join(&right); + + if let Some(node) = self.nodes.get_mut(&digest) { + node.set_children(left, right); + } else { + let node = MerkleTreeNode::new(left, right); + self.nodes.insert(node.digest, node.clone()); + self.interned.insert(node.digest, vec![node.digest]); + }; + + digest + } + + pub fn nodes(&self) -> HashMap { + self.nodes.clone() + } + + pub fn interned(&self) -> HashMap> { + self.interned.clone() + } +} + +// Binary search to find the cell containing the element. +fn find_cell_containing(leafs: &[MerkleTreeLeaf], elem: UInt) -> UInt { + let mut left = 0; + let mut right = leafs.len() as UInt - 1; + + while left < right { + let needle = left + (right - left) / 2; + if leafs[needle as usize].accumulated_count.wrapping_sub(1) < elem.wrapping_sub(1) { + left = needle + 1; + } else { + right = needle; + } + } + + left +} + +#[cfg(test)] +mod tests { + use super::MerkleBuilder; + use crate::merkle::Digest; + + #[test] + fn test_merkle_builder_8() { + let mut builder = MerkleBuilder::default(); + builder.add_with_repetition(Digest::zeroed(), 2); + builder.add_with_repetition(Digest::zeroed(), 6); + let merkle = builder.build(); + assert_eq!( + merkle.root_hash(), + builder.iterated_merkle(Digest::zeroed(), 3) + ); + } + + #[test] + fn test_merkle_builder_64() { + let mut builder = MerkleBuilder::default(); + builder.add_with_repetition(Digest::zeroed(), 2); + builder.add_with_repetition(Digest::zeroed(), 2u128.pow(64) - 2); + let merkle = builder.build(); + assert_eq!( + merkle.root_hash(), + builder.iterated_merkle(Digest::zeroed(), 64) + ); + } + + #[test] + fn test_merkle_builder_128() { + let mut builder = MerkleBuilder::default(); + builder.add_with_repetition(Digest::zeroed(), 2); + builder.add_with_repetition(Digest::zeroed(), 0u128.wrapping_sub(2)); + let merkle = builder.build(); + assert_eq!( + merkle.root_hash(), + builder.iterated_merkle(Digest::zeroed(), 128) + ); + } +} diff --git a/offchain/core/src/strategy/gc.rs b/offchain/core/src/strategy/gc.rs new file mode 100644 index 00000000..7091632d --- /dev/null +++ b/offchain/core/src/strategy/gc.rs @@ -0,0 +1,89 @@ +use std::{collections::HashMap, error::Error}; + +use ::log::info; +use async_recursion::async_recursion; +use ethers::types::Address; + +use crate::arena::{ArenaSender, MatchState, TournamentState}; + +pub struct GarbageCollector { + arena_sender: A, + root_tournamet: Address, +} + +impl GarbageCollector { + pub fn new(arena_sender: A, root_tournamet: Address) -> Self { + Self { + arena_sender, + root_tournamet, + } + } + + pub async fn react( + &mut self, + tournament_states: HashMap, + ) -> Result<(), Box> { + self.react_tournament(self.root_tournamet, tournament_states) + .await + } + + #[async_recursion] + async fn react_tournament( + &mut self, + tournament_address: Address, + tournament_states: HashMap, + ) -> Result<(), Box> { + info!("Enter tournament at address: {}", tournament_address); + let tournament_state = tournament_states + .get(&tournament_address) + .expect("tournament state not found"); + + for m in tournament_state.matches.clone() { + self.react_match(&m, tournament_states.clone()).await?; + + let status_1 = tournament_state + .commitment_states + .get(&m.id.commitment_one) + .expect("status of commitment 1 not found"); + let status_2 = tournament_state + .commitment_states + .get(&m.id.commitment_two) + .expect("status of commitment 2 not found"); + if (!status_1.clock.has_time() + && (status_1.clock.time_since_timeout() > status_2.clock.allowance)) + || (!status_2.clock.has_time() + && (status_2.clock.time_since_timeout() > status_1.clock.allowance)) + { + info!( + "eliminate match for commitment {} and {} at tournament {} of level {}", + m.id.commitment_one, + m.id.commitment_two, + tournament_address, + tournament_state.level + ); + + self.arena_sender + .eliminate_match(tournament_address, m.id) + .await + .expect("fail to eliminate match"); + } + } + Ok(()) + } + + #[async_recursion] + async fn react_match( + &mut self, + match_state: &MatchState, + tournament_states: HashMap, + ) -> Result<(), Box> { + info!("Enter match at HEIGHT: {}", match_state.current_height); + if let Some(inner_tournament) = match_state.inner_tournament { + return self + .react_tournament(inner_tournament, tournament_states) + .await; + } + + Ok(()) + } +} diff --git a/offchain/core/src/strategy/mod.rs b/offchain/core/src/strategy/mod.rs new file mode 100644 index 00000000..b209b462 --- /dev/null +++ b/offchain/core/src/strategy/mod.rs @@ -0,0 +1,5 @@ +//! This module defines the struct [Player] that is responsible for reacting to the states +//! of tournaments; and the struct [GarbageCollector] that is responsible for collecting finished matches + +pub mod gc; +pub mod player; diff --git a/offchain/core/src/strategy/player.rs b/offchain/core/src/strategy/player.rs new file mode 100644 index 00000000..fe4eaf0c --- /dev/null +++ b/offchain/core/src/strategy/player.rs @@ -0,0 +1,360 @@ +use std::{collections::HashMap, error::Error}; + +use ::log::info; +use async_recursion::async_recursion; +use ethers::types::Address; + +use crate::{ + arena::{ArenaSender, MatchState, TournamentState, TournamentWinner}, + machine::{constants, CachingMachineCommitmentBuilder, MachineCommitment, MachineFactory}, + merkle::MerkleProof, +}; + +#[derive(Debug)] +pub enum PlayerTournamentResult { + TournamentWon, + TournamentLost, +} + +pub struct Player { + arena_sender: A, + machine_factory: MachineFactory, + machine_path: String, + commitment_builder: CachingMachineCommitmentBuilder, + root_tournamet: Address, +} + +impl Player { + pub fn new( + arena_sender: A, + machine_factory: MachineFactory, + machine_path: String, + commitment_builder: CachingMachineCommitmentBuilder, + root_tournamet: Address, + ) -> Self { + Self { + arena_sender, + machine_factory, + machine_path, + commitment_builder, + root_tournamet, + } + } + + pub async fn react( + &mut self, + tournament_states: HashMap, + ) -> Result, Box> { + self.react_tournament(HashMap::new(), self.root_tournamet, tournament_states) + .await + } + + #[async_recursion] + async fn react_tournament( + &mut self, + commitments: HashMap, + tournament_address: Address, + tournament_states: HashMap, + ) -> Result, Box> { + info!("Enter tournament at address: {}", tournament_address); + let tournament_state = tournament_states + .get(&tournament_address) + .expect("tournament state not found"); + let mut new_commitments = commitments.clone(); + + let commitment = new_commitments + .entry(tournament_state.address) + .or_insert( + self.commitment_builder + .build_commitment(tournament_state.base_big_cycle, tournament_state.level) + .await?, + ) + .clone(); + + if let Some(winner) = tournament_state.winner.clone() { + match winner { + TournamentWinner::Root(winner_commitment, winner_state) => { + info!( + "tournament finished, winner commitment: {}, state hash: {}", + winner_commitment, winner_state, + ); + if commitment.merkle.root_hash() == winner_commitment { + return Ok(Some(PlayerTournamentResult::TournamentWon)); + } else { + return Ok(Some(PlayerTournamentResult::TournamentLost)); + } + } + TournamentWinner::Inner(parent_commitment, _) => { + let old_commitment = commitments + .get( + &tournament_state + .parent + .expect("parent tournament state not found"), + ) + .expect("parent commitment not found"); + if parent_commitment != old_commitment.merkle.root_hash() { + info!("player lost tournament {}", tournament_state.address); + return Ok(Some(PlayerTournamentResult::TournamentLost)); + } else { + info!( + "win tournament {} of level {} for commitment {}", + tournament_state.address, + tournament_state.level, + commitment.merkle.root_hash(), + ); + let (left, right) = old_commitment.merkle.root_children(); + self.arena_sender + .win_inner_match( + tournament_state + .parent + .expect("parent tournament state not found"), + tournament_state.address, + left, + right, + ) + .await?; + + return Ok(None); + } + } + } + } + + let commitment_state = tournament_state + .commitment_states + .get(&commitment.merkle.root_hash()); + match commitment_state { + Some(c) => { + info!("{}", c.clock); + if let Some(m) = c.latest_match { + self.react_match( + &tournament_state + .matches + .get(m) + .expect("match state not found") + .clone(), + &commitment, + new_commitments, + tournament_state.level, + tournament_states, + ) + .await?; + } + } + None => { + self.join_tournament_if_needed(tournament_state, &commitment) + .await?; + } + } + + Ok(None) + } + + async fn join_tournament_if_needed( + &mut self, + tournament_state: &TournamentState, + commitment: &MachineCommitment, + ) -> Result<(), Box> { + let (left, right) = commitment.merkle.root_children(); + let (last, proof) = commitment.merkle.last(); + + info!( + "join tournament {} of level {} with commitment {}", + tournament_state.address, + tournament_state.level, + commitment.merkle.root_hash(), + ); + self.arena_sender + .join_tournament(tournament_state.address, last, proof, left, right) + .await + } + + #[async_recursion] + async fn react_match( + &mut self, + match_state: &MatchState, + commitment: &MachineCommitment, + commitments: HashMap, + tournament_level: u64, + tournament_states: HashMap, + ) -> Result<(), Box> { + info!("Enter match at HEIGHT: {}", match_state.current_height); + if match_state.current_height == 0 { + self.react_sealed_match( + match_state, + commitment, + commitments, + tournament_level, + tournament_states, + ) + .await + } else if match_state.current_height == 1 { + self.react_unsealed_match(match_state, commitment, tournament_level) + .await + } else { + self.react_running_match(match_state, commitment, tournament_level) + .await + } + } + + #[async_recursion] + async fn react_sealed_match( + &mut self, + match_state: &MatchState, + commitment: &MachineCommitment, + commitments: HashMap, + tournament_level: u64, + tournament_states: HashMap, + ) -> Result<(), Box> { + if tournament_level == 1 { + let (left, right) = commitment.merkle.root_children(); + + let finished = match_state.other_parent.is_zeroed(); + if finished { + return Ok(()); + } + + let cycle = match_state.running_leaf_position >> constants::LOG2_UARCH_SPAN; + let ucycle = match_state.running_leaf_position & constants::UARCH_SPAN; + let proof = self + .machine_factory + .create_machine(&self.machine_path) + .await? + .get_logs(cycle, ucycle) + .await?; + + info!( + "win leaf match in tournament {} of level {} for commitment {}", + match_state.tournament_address, + tournament_level, + commitment.merkle.root_hash(), + ); + self.arena_sender + .win_leaf_match( + match_state.tournament_address, + match_state.id, + left, + right, + proof, + ) + .await?; + } else { + self.react_tournament( + commitments, + match_state + .inner_tournament + .expect("inner tournament not found"), + tournament_states, + ) + .await?; + } + + Ok(()) + } + + async fn react_unsealed_match( + &mut self, + match_state: &MatchState, + commitment: &MachineCommitment, + tournament_level: u64, + ) -> Result<(), Box> { + let (left, right) = + if let Some(children) = commitment.merkle.node_children(match_state.other_parent) { + children + } else { + return Ok(()); + }; + + let (initial_hash, initial_hash_proof) = if match_state.running_leaf_position == 0 { + (commitment.implicit_hash, MerkleProof::default()) + } else { + commitment + .merkle + .prove_leaf(match_state.running_leaf_position) + }; + + if tournament_level == 1 { + info!( + "seal leaf match in tournament {} of level {} for commitment {}", + match_state.tournament_address, + tournament_level, + commitment.merkle.root_hash(), + ); + self.arena_sender + .seal_leaf_match( + match_state.tournament_address, + match_state.id, + left, + right, + initial_hash, + initial_hash_proof, + ) + .await?; + } else { + info!( + "seal inner match in tournament {} of level {} for commitment {}", + match_state.tournament_address, + tournament_level, + commitment.merkle.root_hash(), + ); + self.arena_sender + .seal_inner_match( + match_state.tournament_address, + match_state.id, + left, + right, + initial_hash, + initial_hash_proof, + ) + .await?; + } + + Ok(()) + } + + async fn react_running_match( + &mut self, + match_state: &MatchState, + commitment: &MachineCommitment, + tournament_level: u64, + ) -> Result<(), Box> { + let (left, right) = + if let Some(children) = commitment.merkle.node_children(match_state.other_parent) { + children + } else { + info!("not my turn to react"); + return Ok(()); + }; + let (new_left, new_right) = if left != match_state.left_node { + commitment + .merkle + .node_children(left) + .expect("left node does not have children") + } else { + commitment + .merkle + .node_children(right) + .expect("right node does not have children") + }; + + info!( + "advance match with current height {} in tournament {} of level {} for commitment {}", + match_state.current_height, + match_state.tournament_address, + tournament_level, + commitment.merkle.root_hash(), + ); + self.arena_sender + .advance_match( + match_state.tournament_address, + match_state.id, + left, + right, + new_left, + new_right, + ) + .await?; + + Ok(()) + } +} diff --git a/offchain/core/src/utils/arithmetic.rs b/offchain/core/src/utils/arithmetic.rs new file mode 100644 index 00000000..1f267569 --- /dev/null +++ b/offchain/core/src/utils/arithmetic.rs @@ -0,0 +1,4 @@ +pub const fn max_uint(k: u64) -> u64 { + assert!(k <= u64::BITS as u64); + (1u64.wrapping_shl(k as u32)).wrapping_sub(1) +} \ No newline at end of file diff --git a/offchain/core/src/utils/mod.rs b/offchain/core/src/utils/mod.rs new file mode 100644 index 00000000..965db629 --- /dev/null +++ b/offchain/core/src/utils/mod.rs @@ -0,0 +1 @@ +pub mod arithmetic; diff --git a/offchain/dave-compute/Cargo.toml b/offchain/dave-compute/Cargo.toml new file mode 100644 index 00000000..14968ff9 --- /dev/null +++ b/offchain/dave-compute/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "dave-compute" +version = { workspace = true } + +authors = { workspace = true } +description = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +license-file = { workspace = true } +readme = { workspace = true } +repository = { workspace = true } + +[dependencies] +cartesi-compute-core = { path = "../core" } +ethers = { workspace = true } +tokio = { workspace = true } +log = { workspace = true } +env_logger = "0.10" diff --git a/offchain/dave-compute/src/main.rs b/offchain/dave-compute/src/main.rs new file mode 100644 index 00000000..159f5147 --- /dev/null +++ b/offchain/dave-compute/src/main.rs @@ -0,0 +1,62 @@ +use cartesi_compute_core::arena::{Arena, ArenaConfig}; +use cartesi_compute_core::machine::{CachingMachineCommitmentBuilder, MachineFactory}; +use cartesi_compute_core::strategy::{gc::GarbageCollector, player::Player}; +use ethers::types::Address; +use log::info; +use std::str::FromStr; +use std::time::Duration; + +#[tokio::main] +async fn main() -> Result<(), Box> { + env_logger::init(); + info!("Hello from Dave!"); + let web3_rpc_url = String::from("http://127.0.0.1:8545"); + let web3_chain_id = 31337; + + let private_key = + String::from("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"); + + let arena_config = ArenaConfig { + web3_rpc_url, + web3_chain_id, + web3_private_key: private_key, + }; + + let arena = Arena::new(arena_config)?; + + let machine_path = std::env::var("MACHINE_PATH").expect("MACHINE_PATH is not set"); + // String::from("/root/permissionless-arbitration/lua_node/program/simple-program"); + + let machine_rpc_host = "http://127.0.0.1"; + let machine_rpc_port = 5002; + + let machine_factory = + MachineFactory::new(String::from(machine_rpc_host), machine_rpc_port).await?; + let root_tournament = Address::from_str("0xcafac3dd18ac6c6e92c921884f9e4176737c052c")?; + + let mut player = Player::new( + arena.clone(), + machine_factory.clone(), + machine_path.clone(), + CachingMachineCommitmentBuilder::new(machine_factory, machine_path), + root_tournament.clone(), + ); + + let mut gc = GarbageCollector::new(arena.clone(), root_tournament.clone()); + + loop { + let tournament_states = arena.fetch_from_root(root_tournament).await?; + let res = player.react(tournament_states).await?; + if let Some(r) = res { + info!("Tournament finished, {:?}", r); + break; + } + tokio::time::sleep(Duration::from_secs(1)).await; + + let tournament_states = arena.fetch_from_root(root_tournament).await?; + gc.react(tournament_states).await?; + tokio::time::sleep(Duration::from_secs(1)).await; + } + + Ok(()) +} diff --git a/offchain/docker-compose.yml b/offchain/docker-compose.yml new file mode 100644 index 00000000..9b3ffee6 --- /dev/null +++ b/offchain/docker-compose.yml @@ -0,0 +1,105 @@ +version: '3' + +services: + + anvil: + container_name: cartesi-compute-anvil + image: ghcr.io/foundry-rs/foundry:nightly + ports: + - "8545:8545" + entrypoint: 'anvil --host 0.0.0.0 --no-cors' + + machine: + container_name: cartesi-compute-machine + image: cartesi/machine-emulator:0.15.2 + ports: + - "5002:5002" + volumes: + - ./simulator/data:/data + entrypoint: "/usr/bin/jsonrpc-remote-cartesi-machine --server-address=0.0.0.0:5002" + + coordinator: + container_name: cartesi-compute-coordinator + build: + context: ./ + dockerfile: ./Dockerfile + ports: + - "50500:50500" + links: + - anvil + - machine + volumes: + - ./:/source + - ./simulator/data:/data + entrypoint: "target/debug/cartesi-compute-coordinator" + + simulator: + container_name: cartesi-compute-simulator + build: + context: ./ + dockerfile: ./Dockerfile + volumes: + - ./:/source + - ./simulator/data:/data + links: + - machine + - coordinator + - anvil + entrypoint: "tail -F /dev/null" + +# Anvil setup +# +# Available Accounts +# ================== +# +# (0) "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" (10000.000000000000000000 ETH) +# (1) "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" (10000.000000000000000000 ETH) +# (2) "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC" (10000.000000000000000000 ETH) +# (3) "0x90F79bf6EB2c4f870365E785982E1f101E93b906" (10000.000000000000000000 ETH) +# (4) "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65" (10000.000000000000000000 ETH) +# (5) "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc" (10000.000000000000000000 ETH) +# (6) "0x976EA74026E726554dB657fA54763abd0C3a0aa9" (10000.000000000000000000 ETH) +# (7) "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955" (10000.000000000000000000 ETH) +# (8) "0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f" (10000.000000000000000000 ETH) +# (9) "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720" (10000.000000000000000000 ETH) +# +# Private Keys +# ================== +# +# (0) 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 +# (1) 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d +# (2) 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a +# (3) 0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6 +# (4) 0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a +# (5) 0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba +# (6) 0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e +# (7) 0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356 +# (8) 0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97 +# (9) 0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6 +# Wallet +# ================== +# Mnemonic: test test test test test test test test test test test junk +# Derivation path: m/44'/60'/0'/0/ +# +# +# Chain ID +# ================== +# +# 31337 +# +# Base Fee +# ================== +# +# 1000000000 +# +# Gas Limit +# ================== +# +# 30000000 +# +# Genesis Timestamp +# ================== +# +# 1697715483 + + diff --git a/offchain/input-reader/Cargo.toml b/offchain/input-reader/Cargo.toml new file mode 100644 index 00000000..fba2270f --- /dev/null +++ b/offchain/input-reader/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "rollups-input-reader" +version = { workspace = true } + +authors = { workspace = true } +description = { workspace = true } +edition = { workspace = true } +homepage = { workspace = true } +license-file = { workspace = true } +readme = { workspace = true } +repository = { workspace = true } + +[dependencies] +async-recursion = { workspace = true } +ethers = { workspace = true } +futures = { workspace = true } +tokio = { workspace = true } diff --git a/offchain/input-reader/src/lib.rs b/offchain/input-reader/src/lib.rs new file mode 100644 index 00000000..b47a0ff5 --- /dev/null +++ b/offchain/input-reader/src/lib.rs @@ -0,0 +1,183 @@ +// (c) Cartesi and individual authors (see AUTHORS) +// SPDX-License-Identifier: Apache-2.0 (see LICENSE) + +use async_recursion::async_recursion; +use tokio::sync::Semaphore; + +use ethers::prelude::{Http, ProviderError}; +use ethers::providers::{Middleware, Provider}; +use ethers::types::{Address, BlockNumber, Filter, Log, U64}; + +struct PartitionProvider { + provider: Provider, + semaphore: Semaphore, + input_box: Address, +} + +#[derive(Debug)] +struct ProviderErr(Vec); + +impl std::fmt::Display for ProviderErr { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "Partition error: {:?}", self.0) + } +} + +impl std::error::Error for ProviderErr {} + +pub struct InputReader { + last_finalized: U64, + provider: PartitionProvider, +} + +impl InputReader { + pub fn new( + last_finalized_opt: Option, + input_box: Address, + provider_url: &str, + concurrency_opt: Option, + ) -> Result> { + Ok(Self { + last_finalized: last_finalized_opt.unwrap_or_default(), + provider: PartitionProvider { + input_box, + provider: Provider::::try_from(provider_url)?, + semaphore: Semaphore::new(concurrency_opt.unwrap_or_default()), + }, + }) + } + + pub async fn next(&mut self) -> Result, Box> { + let block_opt = self + .provider + .provider + .get_block(BlockNumber::Finalized) + .await + .map_err(|e| ProviderErr(vec![e.to_string()]))?; + + if let Some(block) = block_opt { + if let Some(current_finalized) = block.number { + println!("Last finalized block at number: {:?}", self.last_finalized); + println!("Current finalized block at number: {:?}", current_finalized); + + if current_finalized > self.last_finalized { + let logs = self + .provider + .get_events(self.last_finalized.as_u64(), current_finalized.as_u64()) + .await + .map_err(|err_arr| { + ProviderErr(err_arr.into_iter().map(|e| e.to_string()).collect()) + })?; + + // update last finalized block + self.last_finalized = current_finalized; + return Ok(logs); + } + } + } + + Ok(vec![]) + } +} + +// Below is a simplified version originated from https://github.com/cartesi/state-fold +// ParitionProvider will attempt to fetch events in smaller partition if the original request is too large +impl PartitionProvider { + async fn get_events( + &self, + start_block: u64, + end_block: u64, + ) -> Result, Vec> { + self.get_events_rec(start_block, end_block).await + } + + #[async_recursion] + async fn get_events_rec( + &self, + start_block: u64, + end_block: u64, + ) -> Result, Vec> { + // TODO: partition log queries if range too large + let filter = Filter::new() + .from_block(start_block) + .to_block(end_block) + .address(self.input_box); + + let res = { + // Make number of concurrent fetches bounded. + let _permit = self.semaphore.acquire().await; + self.provider.get_logs(&filter).await + }; + + match res { + Ok(l) => Ok(l), + Err(e) => { + if Self::should_retry_with_partition(&e) { + let middle = { + let blocks = 1 + end_block - start_block; + let half = blocks / 2; + start_block + half - 1 + }; + + let first_fut = self.get_events_rec(start_block, middle); + let second_fut = self.get_events_rec(middle + 1, end_block); + + let (first_res, second_res) = futures::join!(first_fut, second_fut); + + match (first_res, second_res) { + (Ok(mut first), Ok(second)) => { + first.extend(second); + Ok(first) + } + + (Err(mut first), Err(second)) => { + first.extend(second); + Err(first) + } + + (Err(err), _) | (_, Err(err)) => Err(err), + } + } else { + Err(vec![e]) + } + } + } + } + + fn should_retry_with_partition(err: &ProviderError) -> bool { + // infura limit error code: -32005 + let query_limit_error_codes = [-32005]; + for code in query_limit_error_codes { + let s = format!("{:?}", err); + if s.contains(&code.to_string()) { + return true; + } + } + + false + } +} + +#[tokio::test] + +async fn test_input_reader() -> Result<(), Box> { + use std::str::FromStr; + + let genesis: U64 = U64::from(17784733); + let input_box = Address::from_str("0x59b22D57D4f067708AB0c00552767405926dc768")?; + let infura_key = std::env::var("INFURA_KEY").expect("INFURA_KEY is not set"); + + let mut reader = InputReader::new( + Some(genesis), + input_box, + format!("https://mainnet.infura.io/v3/{}", infura_key).as_ref(), + Some(5), + )?; + + let res: Vec = reader.next().await?; + + // input box from mainnet shouldn't be empty + assert!(!res.is_empty(), "input box shouldn't be empty"); + + Ok(()) +} diff --git a/permissionless-arbitration/contracts/deploy_anvil.sh b/permissionless-arbitration/contracts/deploy_anvil.sh new file mode 100755 index 00000000..0252a3e1 --- /dev/null +++ b/permissionless-arbitration/contracts/deploy_anvil.sh @@ -0,0 +1,31 @@ +#!/bin/bash +RPC_URL="http://127.0.0.1:8545" +PK="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" +CONCRETE_FACTORIES=("SingleLevelTournamentFactory" \ + "TopTournamentFactory" \ + "MiddleTournamentFactory" \ + "BottomTournamentFactory") + +deployed_factories=() +for factory in ${CONCRETE_FACTORIES[@]}; do + deployed_at=`forge create $factory --rpc-url=$RPC_URL --private-key=$PK | \ + grep "Deployed to: " | \ + tr -d '\n' | \ + tail -c 42` + deployed_factories+=($deployed_at) +done + +deployed_at=`forge create TournamentFactory --rpc-url=$RPC_URL --private-key=$PK --constructor-args \ + ${deployed_factories[0]} \ + ${deployed_factories[1]} \ + ${deployed_factories[2]} \ + ${deployed_factories[3]} | \ + grep "Deployed to: " | \ + tr -d '\n' | \ + tail -c 42` + +cd ../lua_node/program/ +initial_hash=`xxd -p -c32 $MACHINE_PATH/hash` +cd - + +cast send --private-key=$PK --rpc-url=$RPC_URL $deployed_at "instantiateTop(bytes32)" 0x$initial_hash diff --git a/permissionless-arbitration/lua_node/Dockerfile b/permissionless-arbitration/lua_node/Dockerfile index 1960c302..09149169 100644 --- a/permissionless-arbitration/lua_node/Dockerfile +++ b/permissionless-arbitration/lua_node/Dockerfile @@ -1,7 +1,7 @@ FROM cartesi/machine-emulator:0.15.2 USER 0 -RUN apt-get -y update; apt-get -y install curl git; apt-get install -y procps +RUN apt-get -y update; apt-get -y install curl git; apt-get install -y procps xxd RUN curl -sSL https://github.com/foundry-rs/foundry/releases/download/nightly/foundry_nightly_linux_$(dpkg --print-architecture).tar.gz | \ tar -zx -C /usr/local/bin @@ -16,11 +16,14 @@ ADD ./permissionless-arbitration/contracts/src/ ./src/ RUN forge --version RUN forge build +ADD ./permissionless-arbitration/contracts/deploy_anvil.sh . + WORKDIR "/app/lua_node" COPY ./permissionless-arbitration/lua_node/ . -RUN chmod +x entrypoint.lua +RUN chmod +x multiplayers_entrypoint.lua +WORKDIR "/app/lua_node/program" +RUN ./gen_machine_simple.sh WORKDIR "/app" -ENTRYPOINT ["./lua_node/entrypoint.lua"] -# CMD ls contracts/lib/forge-std +ENTRYPOINT ["./lua_node/multiplayers_entrypoint.lua"] diff --git a/permissionless-arbitration/lua_node/README.md b/permissionless-arbitration/lua_node/README.md index e28c96ac..ab7512b6 100644 --- a/permissionless-arbitration/lua_node/README.md +++ b/permissionless-arbitration/lua_node/README.md @@ -3,5 +3,5 @@ ## Run example ``` -docker build -t nxn_playground:latest -f Dockerfile ../../ && docker run --rm nxn_playground:latest +docker build -t nxn_playground:latest -f Dockerfile ../../ && docker run --rm --env MACHINE_PATH="/app/lua_node/program/simple-program" nxn_playground:latest ``` diff --git a/permissionless-arbitration/lua_node/blockchain/constants.lua b/permissionless-arbitration/lua_node/blockchain/constants.lua index 3949135c..62561fbb 100644 --- a/permissionless-arbitration/lua_node/blockchain/constants.lua +++ b/permissionless-arbitration/lua_node/blockchain/constants.lua @@ -1,6 +1,7 @@ -- contains default 40 accounts of anvil test node local constants = { endpoint = "http://127.0.0.1:8545", + root_tournament = "0xcafac3dd18ac6c6e92c921884f9e4176737c052c", addresses = { "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", diff --git a/permissionless-arbitration/lua_node/blockchain/reader.lua b/permissionless-arbitration/lua_node/blockchain/reader.lua index 9bfd98bf..a25ff7e3 100644 --- a/permissionless-arbitration/lua_node/blockchain/reader.lua +++ b/permissionless-arbitration/lua_node/blockchain/reader.lua @@ -337,11 +337,4 @@ function Reader:root_tournament_winner(address) return ret end -function Reader:maximum_delay(address) - local sig = "maximumEnforceableDelay()(uint64)" - local ret = self:_call(address, sig, {}) - - return ret -end - return Reader diff --git a/permissionless-arbitration/lua_node/entrypoint.lua b/permissionless-arbitration/lua_node/multiplayers_entrypoint.lua similarity index 86% rename from permissionless-arbitration/lua_node/entrypoint.lua rename to permissionless-arbitration/lua_node/multiplayers_entrypoint.lua index 6ee46a7e..97cfd0d8 100755 --- a/permissionless-arbitration/lua_node/entrypoint.lua +++ b/permissionless-arbitration/lua_node/multiplayers_entrypoint.lua @@ -3,7 +3,7 @@ package.path = package.path .. ";/opt/cartesi/lib/lua/5.4/?.lua" package.path = package.path .. ";./lua_node/?.lua" package.cpath = package.cpath .. ";/opt/cartesi/lib/lua/5.4/?.so" -local machine_path = "lua_node/program/simple-program" +local machine_path = (os.getenv ("MACHINE_PATH")) -- amount of time to fastforward if `IDLE_LIMIT` is reached local FF_TIME = 30 -- max consecutive iterations of all players idling before the blockchain fastforwards @@ -22,25 +22,25 @@ local blockchain_constants = require "blockchain.constants" local Blockchain = require "blockchain.node" local Machine = require "computation.machine" -print "Hello, world!" -os.execute "cd lua_node/program && ./gen_machine_simple.sh" +print "Hello from Dave lua prototype!" local m = Machine:new_from_path(machine_path) local initial_hash = m:state().root_hash local blockchain = Blockchain:new() time.sleep(NODE_DELAY) -local contract = blockchain:deploy_contract(initial_hash) +local contract = blockchain_constants.root_tournament, blockchain:default_account() -- add more player instances here local cmds = { - string.format([[sh -c "echo $$ ; exec ./lua_node/player/honest_player.lua %d %s %s | tee honest.log"]], 1, contract, + [[sh -c "cd contracts && ./deploy_anvil.sh"]], + string.format([[sh -c "echo $$ ; exec ./lua_node/player/honest_player.lua %d %s %s | tee honest.log"]], 2, contract, machine_path), - string.format([[sh -c "echo $$ ; exec ./lua_node/player/dishonest_player.lua %d %s %s %s | tee dishonest.log"]], 2, + string.format([[sh -c "echo $$ ; exec ./lua_node/player/dishonest_player.lua %d %s %s %s | tee dishonest.log"]], 3, contract, machine_path, initial_hash), -- enable below for two extra idle players - -- string.format([[sh -c "echo $$ ; exec ./lua_node/player/idle_player.lua %d %s %s %s | tee idle_1.log"]], 3, + -- string.format([[sh -c "echo $$ ; exec ./lua_node/player/idle_player.lua %d %s %s %s | tee idle_1.log"]], 4, -- contract, machine_path, initial_hash), - -- string.format([[sh -c "echo $$ ; exec ./lua_node/player/idle_player.lua %d %s %s %s | tee idle_2.log"]], 4, + -- string.format([[sh -c "echo $$ ; exec ./lua_node/player/idle_player.lua %d %s %s %s | tee idle_2.log"]], 5, -- contract, machine_path, initial_hash) } local pid_reader = {} @@ -49,8 +49,10 @@ local pid_player = {} for i, cmd in ipairs(cmds) do local reader = io.popen(cmd) local pid = assert(reader):read() - pid_reader[pid] = reader - pid_player[pid] = i + if i > 1 then + pid_reader[pid] = reader + pid_player[pid] = i + end time.sleep(PLAYER_DELAY) end diff --git a/permissionless-arbitration/lua_node/player/dishonest_player.lua b/permissionless-arbitration/lua_node/player/dishonest_player.lua index cebf8c1d..721b1f87 100755 --- a/permissionless-arbitration/lua_node/player/dishonest_player.lua +++ b/permissionless-arbitration/lua_node/player/dishonest_player.lua @@ -36,5 +36,4 @@ while true do else helper.rm_player_idle(player_index) end - time.sleep(1) end diff --git a/permissionless-arbitration/lua_node/player/state.lua b/permissionless-arbitration/lua_node/player/state.lua index 7f009538..7c98ff88 100644 --- a/permissionless-arbitration/lua_node/player/state.lua +++ b/permissionless-arbitration/lua_node/player/state.lua @@ -61,10 +61,6 @@ function State:_fetch_match(match) match.finished = self.reader:match(match.tournament.address, match.match_id_hash)[1]:is_zero() - - if match.finished then - match.delay = tonumber(self.reader:maximum_delay(match.tournament.address)[1]) - end else local address = self.reader:read_tournament_created( match.tournament.address, diff --git a/permissionless-arbitration/lua_node/single_dishonest_entrypoint.lua b/permissionless-arbitration/lua_node/single_dishonest_entrypoint.lua new file mode 100755 index 00000000..cbacb757 --- /dev/null +++ b/permissionless-arbitration/lua_node/single_dishonest_entrypoint.lua @@ -0,0 +1,91 @@ +#!/usr/bin/lua +package.path = package.path .. ";/opt/cartesi/lib/lua/5.4/?.lua" +package.path = package.path .. ";./lua_node/?.lua" +package.cpath = package.cpath .. ";/opt/cartesi/lib/lua/5.4/?.so" + +local machine_path = (os.getenv ("MACHINE_PATH")) +-- amount of time to fastforward if `IDLE_LIMIT` is reached +local FF_TIME = 30 +-- max consecutive iterations of all players idling before the blockchain fastforwards +local IDLE_LIMIT = 5 +-- max consecutive iterations of no active players before the program exits +local INACTIVE_LIMIT = 10 +-- delay time for blockchain node to be ready +local NODE_DELAY = 2 +-- delay between each player +local PLAYER_DELAY = 3 + +local helper = require "utils.helper" +local blockchain_utils = require "blockchain.utils" +local time = require "utils.time" +local blockchain_constants = require "blockchain.constants" +local Blockchain = require "blockchain.node" +local Machine = require "computation.machine" + +print "Hello from Dave lua prototype!" + +local m = Machine:new_from_path(machine_path) +local initial_hash = m:state().root_hash +local blockchain = Blockchain:new() +time.sleep(NODE_DELAY) +local contract = blockchain_constants.root_tournament, blockchain:default_account() + +-- add more player instances here +local cmds = { + [[sh -c "cd contracts && ./deploy_anvil.sh"]], + string.format([[sh -c "echo $$ ; exec ./lua_node/player/dishonest_player.lua %d %s %s %s | tee dishonest.log"]], 2, + contract, machine_path, initial_hash), +} +local pid_reader = {} +local pid_player = {} + +for i, cmd in ipairs(cmds) do + local reader = io.popen(cmd) + local pid = assert(reader):read() + if i > 1 then + pid_reader[pid] = reader + pid_player[pid] = i + end + time.sleep(PLAYER_DELAY) +end + +-- gracefully end children processes +setmetatable(pid_reader, { + __gc = function(t) + helper.stop_players(t) + end +}) + +local no_active_players = 0 +local last_ts = [[01/01/2000 00:00:00]] +while true do + local players = 0 + + for pid, reader in pairs(pid_reader) do + local msg_out + players = players + 1 + last_ts, msg_out = helper.log_to_ts(reader, last_ts) + + -- close the reader and delete the reader entry when there's no more msg in the buffer + -- and the process has already ended + if msg_out == 0 and helper.is_zombie(pid) then + helper.log(pid_player[pid], string.format("player process %s is dead", pid)) + reader:close() + pid_reader[pid] = nil + pid_player[pid] = nil + end + end + + if players == 0 then + no_active_players = no_active_players + 1 + else + no_active_players = 0 + end + + if no_active_players == INACTIVE_LIMIT then + print("no active players, end program...") + break + end +end + +print "Good-bye, world!"