diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 79b3007d5..b0daecac8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,6 +28,12 @@ jobs: - uses: actions/checkout@v3 + - uses: actions/cache@v2 + with: + path: ~/.cargo + key: cargo-registry-${{ hashFiles('Cargo.lock') }} + restore-keys: cargo-registry- + - uses: actions-rs/toolchain@v1 with: toolchain: stable @@ -35,8 +41,6 @@ jobs: override: "true" default: "true" - - uses: Swatinem/rust-cache@v2 - - name: Build run: | cargo build --locked @@ -57,6 +61,13 @@ jobs: - name: Test - features run: cargo test --workspace ${{ matrix.args }} + - name: Cache cargo registry + if: always() + uses: actions/cache@v2 + with: + path: ~/.cargo + key: cargo-registry-${{ hashFiles('Cargo.lock') }} + build_target: name: Build targets @@ -76,6 +87,12 @@ jobs: - uses: actions/checkout@v3 + - uses: actions/cache@v2 + with: + path: ~/.cargo + key: cargo-registry-${{ hashFiles('Cargo.lock') }} + restore-keys: cargo-registry- + - uses: actions-rs/toolchain@v1 with: toolchain: stable @@ -83,8 +100,6 @@ jobs: override: "true" default: "true" - - uses: Swatinem/rust-cache@v2 - - name: Add dependencies run: | rustup target add wasm32-unknown-unknown @@ -110,6 +125,12 @@ jobs: - uses: actions/checkout@v3 + - uses: actions/cache@v2 + with: + path: ~/.cargo + key: cargo-registry-${{ hashFiles('Cargo.lock') }} + restore-keys: cargo-registry- + - uses: actions-rs/toolchain@v1 with: toolchain: stable @@ -118,8 +139,6 @@ jobs: override: "true" default: "true" - - uses: Swatinem/rust-cache@v2 - - name: Add dependencies run: | rustup target add wasm32-unknown-unknown diff --git a/Cargo.lock b/Cargo.lock index 880e71062..16699a36b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,7 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ - "gimli 0.27.0", + "gimli 0.27.1", ] [[package]] @@ -99,9 +99,9 @@ checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" [[package]] name = "arbitrary" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0224938f92e7aef515fac2ff2d18bd1115c1394ddf4a092e0c87e8be9499ee5" +checksum = "3e90af4de65aa7b293ef2d09daff88501eb254f58edde2e1ac02c82d873eadad" dependencies = [ "derive_arbitrary", ] @@ -170,9 +170,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.61" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "705339e0e4a9690e2908d2b3d049d85682cf19fbd5782494498fbf7003a6a282" +checksum = "eff18d764974428cf3a9328e23fc5c986f5fbed46e6cd4cdf42544df5d297ec1" dependencies = [ "proc-macro2", "quote", @@ -254,6 +254,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + [[package]] name = "bincode" version = "1.3.3" @@ -344,9 +350,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "bytecheck" @@ -484,9 +490,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" dependencies = [ "iana-time-zone", + "js-sys", "num-integer", "num-traits", "serde", + "time 0.1.45", + "wasm-bindgen", "winapi", ] @@ -523,9 +532,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.1.0" +version = "4.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa91278560fc226a5d9d736cc21e485ff9aad47d26b8ffe1f54cba868b684b9f" +checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76" dependencies = [ "bitflags", "clap_derive", @@ -551,9 +560,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" +checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade" dependencies = [ "os_str_bytes", ] @@ -570,9 +579,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7bef69dc86e3c610e4e7aed41035e2a7ed12e72dd7530f61327a6579a4390b" +checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e" dependencies = [ "crossbeam-utils", ] @@ -716,9 +725,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d0165d2900ae6778e36e80bbc4da3b5eefccee9ba939761f9c2882a5d9af3ff" +checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" [[package]] name = "crc32fast" @@ -881,9 +890,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.85" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5add3fc1717409d029b20c5b6903fc0c0b02fa6741d820054f4a2efa5e5816fd" +checksum = "322296e2f2e5af4270b54df9e85a02ff037e271af20ba3e7fe1575515dc840b8" dependencies = [ "cc", "cxxbridge-flags", @@ -893,9 +902,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.85" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c87959ba14bc6fbc61df77c3fcfe180fc32b93538c4f1031dd802ccb5f2ff0" +checksum = "017a1385b05d631e7875b1f151c9f012d37b53491e2a87f65bff5c262b2111d8" dependencies = [ "cc", "codespan-reporting", @@ -908,15 +917,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.85" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69a3e162fde4e594ed2b07d0f83c6c67b745e7f28ce58c6df5e6b6bef99dfb59" +checksum = "c26bbb078acf09bc1ecda02d4223f03bdd28bd4874edcb0379138efc499ce971" [[package]] name = "cxxbridge-macro" -version = "1.0.85" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e7e2adeb6a0d4a282e581096b06e1791532b7d576dcde5ccd9382acf55db8e6" +checksum = "357f40d1f06a24b60ae1fe122542c1fb05d28d32acb2aed064e84bc2ad1e252e" dependencies = [ "proc-macro2", "quote", @@ -968,7 +977,7 @@ dependencies = [ "hashbrown", "lock_api", "once_cell", - "parking_lot_core 0.9.5", + "parking_lot_core 0.9.6", ] [[package]] @@ -990,9 +999,9 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf460bbff5f571bfc762da5102729f59f338be7db17a21fade44c5c4f5005350" +checksum = "8beee4701e2e229e8098bbdecdca12449bc3e322f137d269182fa1291e20bd00" dependencies = [ "proc-macro2", "quote", @@ -1065,9 +1074,9 @@ checksum = "c00704156a7de8df8da0911424e30c2049957b0a714542a44e05fe693dd85313" [[package]] name = "ed25519" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ "signature", ] @@ -1088,9 +1097,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" dependencies = [ "serde", ] @@ -1449,9 +1458,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec" [[package]] name = "glob" @@ -1502,7 +1511,7 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" dependencies = [ - "base64", + "base64 0.13.1", "bitflags", "bytes", "headers-core", @@ -1756,9 +1765,9 @@ checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" [[package]] name = "io-lifetimes" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" +checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" dependencies = [ "libc", "windows-sys 0.42.0", @@ -1778,9 +1787,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.7.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e" +checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" [[package]] name = "is-terminal" @@ -1903,9 +1912,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "libloading" @@ -2377,6 +2386,7 @@ dependencies = [ "bs58", "byteorder", "chacha20poly1305 0.10.1", + "chrono", "dashmap", "either", "futures", @@ -2394,6 +2404,7 @@ dependencies = [ "thiserror", "tokio", "tracing", + "tracing-subscriber", "varuint", "walkdir", "wasmer", @@ -2410,6 +2421,7 @@ dependencies = [ "blake2 0.10.6", "bs58", "byteorder", + "chrono", "futures", "locutus-macros", "once_cell", @@ -2499,9 +2511,9 @@ dependencies = [ [[package]] name = "matches" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "memchr" @@ -2670,9 +2682,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a58d1d356c6597d08cde02c2f09d785b09e28711837b1ed667dc652c08a694" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -2688,19 +2700,28 @@ checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" [[package]] name = "nom" -version = "7.1.1" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", "minimal-lexical", ] +[[package]] +name = "nom8" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8" +dependencies = [ + "memchr", +] + [[package]] name = "notify" -version = "5.0.0" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2c66da08abae1c024c01d635253e402341b4060a12e99b31c7594063bf490a" +checksum = "58ea850aa68a06e48fdb069c0ec44d0d64c8dbffa49bf3b6f7f0a901fdea1ba9" dependencies = [ "bitflags", "crossbeam-channel", @@ -2711,7 +2732,7 @@ dependencies = [ "libc", "mio", "walkdir", - "winapi", + "windows-sys 0.42.0", ] [[package]] @@ -2755,9 +2776,9 @@ dependencies = [ [[package]] name = "object" -version = "0.30.0" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" dependencies = [ "memchr", ] @@ -2969,7 +2990,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.5", + "parking_lot_core 0.9.6", ] [[package]] @@ -2988,9 +3009,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" +checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" dependencies = [ "cfg-if 1.0.0", "libc", @@ -3025,9 +3046,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.5.1" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc8bed3549e0f9b0a2a78bf7c0018237a2cdf085eecbbc048e52612438e4e9d0" +checksum = "4ab62d2fa33726dbe6321cc97ef96d8cde531e3eeaf858a058de53a8a6d40d8f" dependencies = [ "thiserror", "ucd-trie", @@ -3035,9 +3056,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.5.1" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdc078600d06ff90d4ed238f0119d84ab5d43dbaad278b0e33a8820293b32344" +checksum = "8bf026e2d0581559db66d837fe5242320f525d85c76283c61f4d51a1238d65ea" dependencies = [ "pest", "pest_generator", @@ -3045,9 +3066,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.5.1" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28a1af60b1c4148bb269006a750cff8e2ea36aff34d2d96cf7be0b14d1bed23c" +checksum = "2b27bd18aa01d91c8ed2b61ea23406a676b42d82609c6e2581fba42f0c15f17f" dependencies = [ "pest", "pest_meta", @@ -3058,13 +3079,13 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.5.1" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec8605d59fc2ae0c6c1aefc0c7c7a9769732017c0ce07f7a9cfffa7b4404f20" +checksum = "9f02b677c1859756359fc9983c2e56a0237f18624a3789528804406b7e915e5d" dependencies = [ "once_cell", "pest", - "sha1 0.10.5", + "sha2 0.10.6", ] [[package]] @@ -3197,13 +3218,12 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-crate" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" +checksum = "66618389e4ec1c7afe67d51a9bf34ff9236480f8d51e7489b7d5ab0303c13f34" dependencies = [ "once_cell", - "thiserror", - "toml", + "toml_edit", ] [[package]] @@ -3238,9 +3258,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" dependencies = [ "unicode-ident", ] @@ -3427,9 +3447,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -3471,9 +3491,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" dependencies = [ "aho-corasick", "memchr", @@ -3624,7 +3644,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" dependencies = [ - "base64", + "base64 0.13.1", "bitflags", "serde", ] @@ -3671,9 +3691,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.5" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" +checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" dependencies = [ "bitflags", "errno", @@ -3685,9 +3705,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.7" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" dependencies = [ "log", "ring", @@ -3701,16 +3721,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9" dependencies = [ - "base64", + "base64 0.13.1", ] [[package]] name = "rustls-pemfile" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" dependencies = [ - "base64", + "base64 0.21.0", ] [[package]] @@ -3747,12 +3767,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "lazy_static", - "windows-sys 0.36.1", + "windows-sys 0.42.0", ] [[package]] @@ -3900,7 +3919,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30d904179146de381af4c93d3af6ca4984b3152db687dacb9c3c35e86f39809c" dependencies = [ - "base64", + "base64 0.13.1", "chrono", "hex", "indexmap", @@ -4101,9 +4120,9 @@ dependencies = [ [[package]] name = "sqlformat" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f87e292b4291f154971a43c3774364e2cbcaec599d3f5bf6fa9d122885dbc38a" +checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e" dependencies = [ "itertools", "nom", @@ -4154,7 +4173,7 @@ dependencies = [ "paste", "percent-encoding", "rustls", - "rustls-pemfile 1.0.1", + "rustls-pemfile 1.0.2", "sha2 0.10.6", "smallvec", "sqlformat", @@ -4363,9 +4382,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] @@ -4421,6 +4440,17 @@ dependencies = [ "threadpool", ] +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + [[package]] name = "time" version = "0.2.27" @@ -4503,9 +4533,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.24.1" +version = "1.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d9f76183f91ecfb55e1d7d5602bd1d979e38a3a522fe900241cf195624d67ae" +checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb" dependencies = [ "autocfg", "bytes", @@ -4594,14 +4624,31 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "indexmap", "serde", ] +[[package]] +name = "toml_datetime" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5" + +[[package]] +name = "toml_edit" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b" +dependencies = [ + "indexmap", + "nom8", + "toml_datetime", +] + [[package]] name = "tower-service" version = "0.3.2" @@ -4752,9 +4799,9 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "tungstenite" @@ -4762,7 +4809,7 @@ version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" dependencies = [ - "base64", + "base64 0.13.1", "byteorder", "bytes", "http", @@ -4781,7 +4828,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788" dependencies = [ - "base64", + "base64 0.13.1", "byteorder", "bytes", "http", @@ -4826,9 +4873,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" [[package]] name = "unicode-ident" @@ -5030,6 +5077,12 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -5117,18 +5170,18 @@ checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "wasm-encoder" -version = "0.20.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05632e0a66a6ed8cca593c24223aabd6262f256c3693ad9822c315285f010614" +checksum = "ef126be0e14bdf355ac1a8b41afc89195289e5c7179f80118e3abddb472f0810" dependencies = [ "leb128", ] [[package]] name = "wasmer" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740f96c9e5d49f0056d716977657f3f7f8eea9923b41f46d1046946707aa038f" +checksum = "840af6d21701220cb805dc7201af301cb99e9b4f646f48a41befbc1d949f0f90" dependencies = [ "bytes", "cfg-if 1.0.0", @@ -5152,9 +5205,9 @@ dependencies = [ [[package]] name = "wasmer-compiler" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "001d072dd9823e5a06052621eadb531627b4a508d74b67da4590a3d5d9332dc8" +checksum = "b86fab98beaaace77380cb04e681773739473860d1b8499ea6b14f920923e0c5" dependencies = [ "backtrace", "cfg-if 1.0.0", @@ -5176,9 +5229,9 @@ dependencies = [ [[package]] name = "wasmer-compiler-cranelift" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2974856a7ce40eb033efc9db3d480845385c27079b6e33ce51751f2f3c67e9bd" +checksum = "015eef629fc84889540dc1686bd7fa524b93da9fd2d275b16c49dbe96268e58f" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -5195,9 +5248,9 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36b23b52272494369a1f96428f0056425a85a66154610c988d971bbace8230f1" +checksum = "1ff577b7c1cfcd3d7c5b3a09fe1a499b73f7c17084845ff71225c8250a6a63a9" dependencies = [ "proc-macro-error", "proc-macro2", @@ -5207,9 +5260,9 @@ dependencies = [ [[package]] name = "wasmer-types" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bc6cd7a2d2d3bd901ff491f131188c1030694350685279e16e1233b9922846b" +checksum = "8b9600f9da966abae3be0b0a4560e7d1f2c88415a2d01ce362ac06063cb1c473" dependencies = [ "enum-iterator", "enumset", @@ -5222,9 +5275,9 @@ dependencies = [ [[package]] name = "wasmer-vbus" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec176e84475376a9797656bb93af022de92d26cc49ddf399a469e6e5a08ecf18" +checksum = "72b42f76b9f09c68084de3a35fdf4907609f4b5005ecf3767fa1839a669dcbdb" dependencies = [ "thiserror", "wasmer-vfs", @@ -5232,9 +5285,9 @@ dependencies = [ [[package]] name = "wasmer-vfs" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93036f2dcb73ab936982c97382953c57b699d473c62723d60b468d9641b43059" +checksum = "34bfbd243503d64aed4fc8a194657a561cae6c2d782dbcf649211d7f4db9e413" dependencies = [ "libc", "thiserror", @@ -5243,9 +5296,9 @@ dependencies = [ [[package]] name = "wasmer-vm" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67d0cd6c0ef4985d1ce9c7d7cccf34e910804417a230fa16ab7ee904efb4c34" +checksum = "9fc68a7f0a003e6cb63845b7510065097d289553201d64afb9a5e1744da3c6a0" dependencies = [ "backtrace", "cc", @@ -5267,9 +5320,9 @@ dependencies = [ [[package]] name = "wasmer-vnet" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "902792902cf6ba37d89bde95f73d6e0196a66b32237add430fca9704baf27270" +checksum = "9bc4fe3b48ccc620901bdcdfac98d8a76ef3487412c221752814750c2e7db4c1" dependencies = [ "bytes", "thiserror", @@ -5278,9 +5331,9 @@ dependencies = [ [[package]] name = "wasmer-wasi" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3bfd5ade6f2b8ded26067853a098ade9fd166e0c274bd53197959e8a6732c79" +checksum = "e893ecd57c63db83b17dacfaee90f660e1d7f5b26d2f9d88ea6aa2e8c4bc301d" dependencies = [ "bytes", "cfg-if 1.0.0", @@ -5302,9 +5355,9 @@ dependencies = [ [[package]] name = "wasmer-wasi-local-networking" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfa74234a5e3e1a2704b1ba56f31e2630eafd9c78a12ac34b21030ad57bb9f23" +checksum = "bd65882d8cee793848776f26e979b7ff3e139d927947d87304c940c89527a730" dependencies = [ "bytes", "tracing", @@ -5314,9 +5367,9 @@ dependencies = [ [[package]] name = "wasmer-wasi-types" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c90be03f7c20638657d30691721cc4604ef90c7c32816b645245c2cec940bb4c" +checksum = "e1afdec83c62d22bf7110b83d662a08f708332fd728a213399919a045a1061d4" dependencies = [ "byteorder", "time 0.2.27", @@ -5404,9 +5457,9 @@ checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" [[package]] name = "wast" -version = "50.0.0" +version = "52.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2cbb59d4ac799842791fe7e806fa5dbbf6b5554d538e51cc8e176db6ff0ae34" +checksum = "707a9fd59b0144c530f0a31f21737036ffea6ece492918cae0843dd09b6f9bc9" dependencies = [ "leb128", "memchr", @@ -5416,9 +5469,9 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.52" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "584aaf7a1ecf4d383bbe1a25eeab0cbb8ff96acc6796707ff65cde48f4632f15" +checksum = "91d73cbaa81acc2f8a3303e2289205c971d99c89245c2f56ab8765c4daabc2be" dependencies = [ "wast", ] @@ -5473,9 +5526,9 @@ dependencies = [ [[package]] name = "which" -version = "4.3.0" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" dependencies = [ "either", "libc", @@ -5532,19 +5585,6 @@ dependencies = [ "windows_x86_64_msvc 0.33.0", ] -[[package]] -name = "windows-sys" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", -] - [[package]] name = "windows-sys" version = "0.42.0" @@ -5552,19 +5592,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.0", + "windows_x86_64_msvc 0.42.1", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" [[package]] name = "windows_aarch64_msvc" @@ -5574,15 +5614,9 @@ checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" [[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" [[package]] name = "windows_i686_gnu" @@ -5592,15 +5626,9 @@ checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" [[package]] name = "windows_i686_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" [[package]] name = "windows_i686_msvc" @@ -5610,15 +5638,9 @@ checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" [[package]] name = "windows_x86_64_gnu" @@ -5628,21 +5650,15 @@ checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" [[package]] name = "windows_x86_64_msvc" @@ -5652,15 +5668,9 @@ checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" [[package]] name = "winreg" diff --git a/Cargo.toml b/Cargo.toml index 5c5126586..a7a01eb73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = ["crates/*"] [workspace.dependencies] clap = "4" chacha20poly1305 = "0.10" +chrono = { version = "0.4", default-features = true } either = "1.8" futures = "0.3" rand = { version = "0.8" } diff --git a/crates/locutus-core/Cargo.toml b/crates/locutus-core/Cargo.toml index 8302b2359..460bf3ee6 100644 --- a/crates/locutus-core/Cargo.toml +++ b/crates/locutus-core/Cargo.toml @@ -59,8 +59,8 @@ tracing-opentelemetry = { version = "0.18.0", optional = true } tracing-subscriber = { version = "0.3.16", optional = true } # internal deps -locutus-runtime = { path = "../locutus-runtime", version = "0.0.3" } locutus-stdlib = { path = "../locutus-stdlib", version = "0.0.3", features = ["net"] } +locutus-runtime = { path = "../locutus-runtime", version = "0.0.3" } [dev-dependencies] tracing = "0.1" diff --git a/crates/locutus-core/examples/p2p_network.rs b/crates/locutus-core/examples/p2p_network.rs index ae7228d14..91e354c6c 100644 --- a/crates/locutus-core/examples/p2p_network.rs +++ b/crates/locutus-core/examples/p2p_network.rs @@ -9,7 +9,7 @@ use libp2p::{ use locutus_core::*; use locutus_runtime::prelude::{ContractContainer, WasmAPIVersion, WrappedContract, WrappedState}; use locutus_stdlib::{ - api::{ClientError, ClientRequest, ContractRequest, HostResponse}, + client_api::{ClientError, ClientRequest, ContractRequest, HostResponse}, prelude::{ContractCode, Parameters}, }; use tokio::sync::mpsc::{channel, Receiver, Sender}; diff --git a/crates/locutus-core/src/client_events.rs b/crates/locutus-core/src/client_events.rs index e1794f0cc..73ae08fb8 100644 --- a/crates/locutus-core/src/client_events.rs +++ b/crates/locutus-core/src/client_events.rs @@ -1,7 +1,7 @@ use futures::future::BoxFuture; use locutus_runtime::ComponentKey; -use locutus_stdlib::api::ClientRequest; -use locutus_stdlib::api::{ClientError, HostResponse}; +use locutus_stdlib::client_api::ClientRequest; +use locutus_stdlib::client_api::{ClientError, HostResponse}; use std::fmt::Debug; use std::fmt::Display; @@ -124,7 +124,7 @@ pub(crate) mod test { use locutus_runtime::{ ContractCode, ContractContainer, Parameters, RelatedContracts, TryFromTsStd, WasmAPIVersion, }; - use locutus_stdlib::api::ContractRequest; + use locutus_stdlib::client_api::ContractRequest; use rand::{prelude::Rng, thread_rng}; use tokio::sync::watch::Receiver; diff --git a/crates/locutus-core/src/client_events/combinator.rs b/crates/locutus-core/src/client_events/combinator.rs index 2ade8e160..7b8290620 100644 --- a/crates/locutus-core/src/client_events/combinator.rs +++ b/crates/locutus-core/src/client_events/combinator.rs @@ -7,7 +7,7 @@ use std::{collections::HashMap, task::Poll}; use futures::future::BoxFuture; use futures::task::AtomicWaker; use futures::FutureExt; -use locutus_stdlib::api::{ErrorKind, HostResponse}; +use locutus_stdlib::client_api::{ErrorKind, HostResponse}; use tokio::sync::mpsc::{channel, Receiver, Sender}; use super::{BoxedClient, ClientError, HostResult}; @@ -246,7 +246,7 @@ where #[cfg(test)] mod test { - use locutus_stdlib::api::ClientRequest; + use locutus_stdlib::client_api::ClientRequest; use super::*; diff --git a/crates/locutus-core/src/client_events/websocket.rs b/crates/locutus-core/src/client_events/websocket.rs index bc51216e9..9908eb3a8 100644 --- a/crates/locutus-core/src/client_events/websocket.rs +++ b/crates/locutus-core/src/client_events/websocket.rs @@ -8,7 +8,7 @@ use std::{ use futures::{future::BoxFuture, stream::SplitSink, SinkExt, StreamExt}; use locutus_runtime::prelude::TryFromTsStd; -use locutus_stdlib::api::{ClientRequest, ContractRequest, ErrorKind, HostResponse}; +use locutus_stdlib::client_api::{ClientRequest, ContractRequest, ErrorKind, HostResponse}; use tokio::sync::mpsc::{channel, Receiver, Sender}; use warp::{filters::BoxedFilter, Filter, Reply}; diff --git a/crates/locutus-core/src/contract/handler.rs b/crates/locutus-core/src/contract/handler.rs index 62d808d47..a1923b67e 100644 --- a/crates/locutus-core/src/contract/handler.rs +++ b/crates/locutus-core/src/contract/handler.rs @@ -7,7 +7,7 @@ use std::time::{Duration, Instant}; use futures::future::BoxFuture; use locutus_runtime::{ContractContainer, ContractStore, Parameters, StateStorage, StateStore}; -use locutus_stdlib::api::{ClientRequest, HostResponse}; +use locutus_stdlib::client_api::{ClientRequest, HostResponse}; use serde::{Deserialize, Serialize}; use tokio::sync::mpsc; @@ -190,7 +190,7 @@ pub mod test { use locutus_runtime::{ContractStore, WasmAPIVersion}; use locutus_stdlib::{ - api::{ClientRequest, HostResponse}, + client_api::{ClientRequest, HostResponse}, prelude::ContractCode, }; diff --git a/crates/locutus-core/src/contract/storages/rocks_db.rs b/crates/locutus-core/src/contract/storages/rocks_db.rs index e214a496c..8e3ba21e3 100644 --- a/crates/locutus-core/src/contract/storages/rocks_db.rs +++ b/crates/locutus-core/src/contract/storages/rocks_db.rs @@ -7,7 +7,7 @@ use locutus_runtime::{ ContractContainer, ContractError, ContractExecError, ContractRuntimeInterface, ContractStore, Parameters, StateStorage, StateStore, StateStoreError, ValidateResult, }; -use locutus_stdlib::api::{ClientRequest, ContractRequest, ContractResponse, HostResponse}; +use locutus_stdlib::client_api::{ClientRequest, ContractRequest, ContractResponse, HostResponse}; use crate::contract::ContractKey; use crate::{config::CONFIG, contract::test::MockRuntime, WrappedState}; diff --git a/crates/locutus-core/src/contract/storages/sqlite.rs b/crates/locutus-core/src/contract/storages/sqlite.rs index 06c975079..42dedaaa4 100644 --- a/crates/locutus-core/src/contract/storages/sqlite.rs +++ b/crates/locutus-core/src/contract/storages/sqlite.rs @@ -6,7 +6,7 @@ use locutus_runtime::{ ContractContainer, ContractError, ContractExecError, ContractRuntimeInterface, ContractStore, Parameters, StateStorage, StateStore, StateStoreError, ValidateResult, }; -use locutus_stdlib::api::{ClientRequest, ContractRequest, ContractResponse, HostResponse}; +use locutus_stdlib::client_api::{ClientRequest, ContractRequest, ContractResponse, HostResponse}; use once_cell::sync::Lazy; use sqlx::{ sqlite::{SqliteConnectOptions, SqliteRow}, diff --git a/crates/locutus-core/src/contract/test.rs b/crates/locutus-core/src/contract/test.rs index 541bd5c06..e51d0fc24 100644 --- a/crates/locutus-core/src/contract/test.rs +++ b/crates/locutus-core/src/contract/test.rs @@ -4,7 +4,7 @@ use locutus_runtime::{ ContractKey, ContractRuntimeInterface, ContractStore, StateStorage, StateStore, UpdateModification, ValidateResult, }; -use locutus_stdlib::api::{ClientRequest, HostResponse}; +use locutus_stdlib::client_api::{ClientRequest, HostResponse}; use super::handler::{CHListenerHalve, ContractHandler, ContractHandlerChannel}; use crate::{config::CONFIG, WrappedState}; diff --git a/crates/locutus-core/src/executor.rs b/crates/locutus-core/src/executor.rs index 63337e015..521803d5b 100644 --- a/crates/locutus-core/src/executor.rs +++ b/crates/locutus-core/src/executor.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use blake2::digest::generic_array::GenericArray; use locutus_runtime::prelude::*; -use locutus_stdlib::api::{ +use locutus_stdlib::client_api::{ ClientError, ClientRequest, ComponentRequest, ContractRequest, ContractResponse, HostResponse, }; use tokio::sync::mpsc::UnboundedSender; diff --git a/crates/locutus-core/src/node.rs b/crates/locutus-core/src/node.rs index 87159b5fc..59bb17dfb 100644 --- a/crates/locutus-core/src/node.rs +++ b/crates/locutus-core/src/node.rs @@ -15,7 +15,7 @@ use libp2p::{ multiaddr::Protocol, Multiaddr, PeerId, }; -use locutus_stdlib::api::{ClientRequest, ContractRequest}; +use locutus_stdlib::client_api::{ClientRequest, ContractRequest}; #[cfg(test)] use self::in_memory_impl::NodeInMemory; diff --git a/crates/locutus-core/src/node/p2p_impl.rs b/crates/locutus-core/src/node/p2p_impl.rs index 6452b230a..1e50e365c 100644 --- a/crates/locutus-core/src/node/p2p_impl.rs +++ b/crates/locutus-core/src/node/p2p_impl.rs @@ -180,6 +180,7 @@ mod test { } } + #[ignore] #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn ping() -> Result<(), ()> { let peer1_port = get_free_port().unwrap(); diff --git a/crates/locutus-core/src/node/test.rs b/crates/locutus-core/src/node/test.rs index e3c07be1f..a3b41f10d 100644 --- a/crates/locutus-core/src/node/test.rs +++ b/crates/locutus-core/src/node/test.rs @@ -9,7 +9,7 @@ use itertools::Itertools; use libp2p::{identity, PeerId}; use locutus_runtime::prelude::ContractKey; use locutus_runtime::ContractContainer; -use locutus_stdlib::api::ClientRequest; +use locutus_stdlib::client_api::ClientRequest; use rand::Rng; use tokio::sync::watch::{channel, Receiver, Sender}; use tracing::{info, instrument}; @@ -360,7 +360,7 @@ fn group_locations_in_buckets( } distances .into_iter() - .map(move |(k, v)| ((k as f64 / (10.0f64).powi(scale)) as f64, v)) + .map(move |(k, v)| ((k as f64 / (10.0f64).powi(scale)), v)) } pub(crate) async fn check_connectivity( diff --git a/crates/locutus-core/src/operations/get.rs b/crates/locutus-core/src/operations/get.rs index 53dbefe76..498d57986 100644 --- a/crates/locutus-core/src/operations/get.rs +++ b/crates/locutus-core/src/operations/get.rs @@ -659,7 +659,7 @@ mod messages { #[cfg(test)] mod test { use locutus_runtime::{ContractContainer, WasmAPIVersion}; - use locutus_stdlib::api::ContractRequest; + use locutus_stdlib::client_api::ContractRequest; use std::collections::HashMap; use super::*; diff --git a/crates/locutus-core/src/operations/put.rs b/crates/locutus-core/src/operations/put.rs index d7c7629a8..d67bdeb97 100644 --- a/crates/locutus-core/src/operations/put.rs +++ b/crates/locutus-core/src/operations/put.rs @@ -788,7 +788,7 @@ mod messages { #[cfg(test)] mod test { use locutus_runtime::{WasmAPIVersion, WrappedContract}; - use locutus_stdlib::api::ContractRequest; + use locutus_stdlib::client_api::ContractRequest; use std::collections::HashMap; use crate::node::test::{check_connectivity, NodeSpecification, SimNetwork}; diff --git a/crates/locutus-core/src/operations/subscribe.rs b/crates/locutus-core/src/operations/subscribe.rs index 2ae52b0aa..cbc2a3328 100644 --- a/crates/locutus-core/src/operations/subscribe.rs +++ b/crates/locutus-core/src/operations/subscribe.rs @@ -442,7 +442,7 @@ mod messages { mod test { use std::collections::HashMap; - use locutus_stdlib::api::ContractRequest; + use locutus_stdlib::client_api::ContractRequest; use super::*; use crate::{ diff --git a/crates/locutus-dev/src/build.rs b/crates/locutus-dev/src/build.rs index 9393b6d52..f467587e0 100644 --- a/crates/locutus-dev/src/build.rs +++ b/crates/locutus-dev/src/build.rs @@ -562,7 +562,7 @@ mod test { let mut buf = vec![]; File::open(cwd.join("build").join("locutus").join(DEFAULT_OUTPUT_NAME))? .read_to_end(&mut buf)?; - let state = locutus_runtime::locutus_stdlib::contract_interface::State::from(buf); + let state = locutus_runtime::locutus_stdlib::prelude::State::from(buf); let mut web = WebApp::try_from(state.as_ref()).unwrap(); let target = env::temp_dir().join("locutus-unpack-state"); diff --git a/crates/locutus-dev/src/commands.rs b/crates/locutus-dev/src/commands.rs index 745e84499..303ed1309 100644 --- a/crates/locutus-dev/src/commands.rs +++ b/crates/locutus-dev/src/commands.rs @@ -4,7 +4,7 @@ use locutus_core::{locutus_runtime::StateDelta, ClientId, Config, Executor, Stor use locutus_runtime::{ ContractContainer, ContractInstanceId, ContractStore, Parameters, StateStore, }; -use locutus_stdlib::api::{ClientRequest, ContractRequest}; +use locutus_stdlib::client_api::{ClientRequest, ContractRequest}; use crate::{ config::{BaseConfig, PutConfig, UpdateConfig}, diff --git a/crates/locutus-dev/src/lib.rs b/crates/locutus-dev/src/lib.rs index 36abc6258..9bee16bfc 100644 --- a/crates/locutus-dev/src/lib.rs +++ b/crates/locutus-dev/src/lib.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use locutus_stdlib::api::ClientRequest; +use locutus_stdlib::client_api::ClientRequest; pub mod build; pub mod commands; diff --git a/crates/locutus-dev/src/local_node/commands.rs b/crates/locutus-dev/src/local_node/commands.rs index 734ad9a1f..3cd42cbd0 100644 --- a/crates/locutus-dev/src/local_node/commands.rs +++ b/crates/locutus-dev/src/local_node/commands.rs @@ -1,5 +1,5 @@ use locutus_core::ClientId; -use locutus_stdlib::api::{ClientRequest, ContractRequest, ContractResponse, HostResponse}; +use locutus_stdlib::client_api::{ClientRequest, ContractRequest, ContractResponse, HostResponse}; use crate::{CommandReceiver, DynError}; diff --git a/crates/locutus-dev/src/local_node/user_events.rs b/crates/locutus-dev/src/local_node/user_events.rs index df15a7515..f1f55c7e3 100644 --- a/crates/locutus-dev/src/local_node/user_events.rs +++ b/crates/locutus-dev/src/local_node/user_events.rs @@ -9,7 +9,9 @@ use either::Either; use futures::future::BoxFuture; use locutus_core::{ClientEventsProxy, ClientId, OpenRequest}; use locutus_runtime::prelude::*; -use locutus_stdlib::api::{ClientError, ClientRequest, ContractRequest, ErrorKind, HostResponse}; +use locutus_stdlib::client_api::{ + ClientError, ClientRequest, ContractRequest, ErrorKind, HostResponse, +}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use crate::{util, CommandSender, DynError}; diff --git a/crates/locutus-node/src/http_gateway.rs b/crates/locutus-node/src/http_gateway.rs index f32280f1e..dda6f528c 100644 --- a/crates/locutus-node/src/http_gateway.rs +++ b/crates/locutus-node/src/http_gateway.rs @@ -3,7 +3,7 @@ use futures::{future::BoxFuture, stream::SplitSink, FutureExt, SinkExt, StreamEx use locutus_core::locutus_runtime::TryFromTsStd; use locutus_core::*; use locutus_runtime::ContractKey; -use locutus_stdlib::api::{ +use locutus_stdlib::client_api::{ ClientError, ClientRequest, ContractRequest, ContractResponse, ErrorKind, HostResponse, }; use std::{ diff --git a/crates/locutus-node/src/lib.rs b/crates/locutus-node/src/lib.rs index c7fefa5de..55934a81a 100644 --- a/crates/locutus-node/src/lib.rs +++ b/crates/locutus-node/src/lib.rs @@ -4,7 +4,7 @@ pub(crate) mod web_handling; pub use http_gateway::HttpGateway; use locutus_core::{locutus_runtime::ContractKey, ClientId, HostResult}; -use locutus_stdlib::api::{ClientError, ClientRequest, HostResponse}; +use locutus_stdlib::client_api::{ClientError, ClientRequest, HostResponse}; type DynError = Box; @@ -37,7 +37,7 @@ pub mod local_node { use locutus_core::{ either, ClientEventsProxy, Executor, OpenRequest, RequestError, WebSocketProxy, }; - use locutus_stdlib::api::{ClientError, ErrorKind}; + use locutus_stdlib::client_api::{ClientError, ErrorKind}; use crate::{DynError, HttpGateway}; diff --git a/crates/locutus-node/src/web_handling.rs b/crates/locutus-node/src/web_handling.rs index 5665cb9b3..5108d3506 100644 --- a/crates/locutus-node/src/web_handling.rs +++ b/crates/locutus-node/src/web_handling.rs @@ -8,12 +8,12 @@ use locutus_runtime::{ }; use locutus_core::{ - locutus_runtime::locutus_stdlib::api::{ + locutus_runtime::locutus_stdlib::client_api::{ ClientRequest, ContractRequest, ContractResponse, HostResponse, }, *, }; -use locutus_stdlib::api::ErrorKind; +use locutus_stdlib::client_api::ErrorKind; use tokio::{fs::File, io::AsyncReadExt, sync::mpsc}; use warp::{ reject::{self, Reject}, diff --git a/crates/locutus-runtime/Cargo.toml b/crates/locutus-runtime/Cargo.toml index d8ec0e99e..597fcf636 100644 --- a/crates/locutus-runtime/Cargo.toml +++ b/crates/locutus-runtime/Cargo.toml @@ -15,7 +15,9 @@ async-trait = "0.1" bincode = "1" blake2 = { version = "0.10", features = [ "std" ] } bs58 = "0.4" +byteorder = "1" chacha20poly1305 = { workspace = true } +chrono = { workspace = true } dashmap = "^5.1" either = { workspace = true } futures = "0.3" @@ -35,7 +37,6 @@ thiserror = "1" walkdir = "2.3.2" wasmer = { workspace = true, default-features = false, features = [ "sys"] } varuint = "0.6" -byteorder = "1" # internal locutus-stdlib = { path = "../locutus-stdlib", features = ["archive"], version = "0.0.3" } @@ -50,6 +51,7 @@ trace = ["locutus-stdlib/trace"] [dev-dependencies] arbitrary = { version = "1", features = ["derive"] } +tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] } wasmer = { workspace = true, features = [ "sys-default"] } bincode = "1" once_cell = "1" diff --git a/crates/locutus-runtime/src/component.rs b/crates/locutus-runtime/src/component.rs index ebe794770..20c2e6f55 100644 --- a/crates/locutus-runtime/src/component.rs +++ b/crates/locutus-runtime/src/component.rs @@ -154,6 +154,9 @@ impl Runtime { outbound_msgs.push_back(msg); } } + OutboundComponentMsg::ContextUpdated(context) => { + last_context = context; + } } } Ok(last_context) @@ -170,8 +173,9 @@ impl ComponentRuntimeInterface for Runtime { if inbound.is_empty() { return Ok(results); } - let instance = self.prepare_component_call(key, 4096)?; - let process_func: TypedFunction = instance + let running = self.prepare_component_call(key, 4096)?; + let process_func: TypedFunction = running + .instance .exports .get_typed_function(&self.wasm_store, "process")?; @@ -202,14 +206,14 @@ impl ComponentRuntimeInterface for Runtime { .with_context(last_context.clone()), ), &process_func, - &instance, + &running.instance, )?, ); // Update the shared context for next messages last_context = self.get_outbound( key, - &instance, + &running.instance, &process_func, &mut outbound, &mut results, @@ -219,9 +223,15 @@ impl ComponentRuntimeInterface for Runtime { let mut outbound = VecDeque::from(self.exec_inbound( &InboundComponentMsg::UserResponse(response), &process_func, - &instance, + &running.instance, )?); - self.get_outbound(key, &instance, &process_func, &mut outbound, &mut results)?; + self.get_outbound( + key, + &running.instance, + &process_func, + &mut outbound, + &mut results, + )?; } InboundComponentMsg::GetSecretResponse(_) => { return Err(ComponentExecError::UnexpectedMessage("get secret response").into()) @@ -230,9 +240,15 @@ impl ComponentRuntimeInterface for Runtime { let mut outbound = VecDeque::from(self.exec_inbound( &InboundComponentMsg::RandomBytes(bytes), &process_func, - &instance, + &running.instance, )?); - self.get_outbound(key, &instance, &process_func, &mut outbound, &mut results)?; + self.get_outbound( + key, + &running.instance, + &process_func, + &mut outbound, + &mut results, + )?; } } } @@ -260,22 +276,14 @@ impl ComponentRuntimeInterface for Runtime { #[cfg(test)] mod test { use chacha20poly1305::aead::{AeadCore, KeyInit, OsRng}; - use locutus_stdlib::{ - contract_interface::ContractCode, - prelude::{ContractInstanceId, Parameters}, - }; + use locutus_stdlib::prelude::{ContractCode, ContractInstanceId, Parameters}; use serde::{Deserialize, Serialize}; - use std::{ - path::{Path, PathBuf}, - process::Command, - sync::{atomic::AtomicUsize, Arc}, - }; + use std::sync::Arc; use super::*; use crate::{component_store::ComponentStore, ContractStore, SecretsStore, WrappedContract}; const TEST_COMPONENT_1: &str = "test_component_1"; - static TEST_NO: AtomicUsize = AtomicUsize::new(0); #[derive(Debug, Serialize, Deserialize)] struct SecretsContext { @@ -294,59 +302,12 @@ mod test { MessageSigned(Vec), } - fn test_dir() -> PathBuf { - let test_dir = std::env::temp_dir().join("locutus-test").join(format!( - "component-api-test-{}", - TEST_NO.fetch_add(1, std::sync::atomic::Ordering::SeqCst) - )); - if !test_dir.exists() { - std::fs::create_dir_all(&test_dir).unwrap(); - } - test_dir - } - - fn get_test_component(name: &str) -> Result> { - const CONTRACTS_DIR: &str = env!("CARGO_MANIFEST_DIR"); - let contracts = PathBuf::from(CONTRACTS_DIR); - let mut dirs = contracts.ancestors(); - let path = dirs.nth(2).unwrap(); - let component_dir = path.join("tests").join(name.replace('_', "-")); - let mut component_build = component_dir - .join("build/locutus") - .join(name) - .with_extension("wasm"); - if !component_build.exists() { - let target = - std::env::var("CARGO_TARGET_DIR").map_err(|_| "CARGO_TARGET_DIR should be set")?; - println!("trying to compile the test contract, target: {target}"); - // attempt to compile it - const RUST_TARGET_ARGS: &[&str] = &["build", "--target"]; - const WASI_TARGET: &str = "wasm32-wasi"; - let cmd_args = RUST_TARGET_ARGS - .iter() - .copied() - .chain([WASI_TARGET]) - .collect::>(); - let mut child = Command::new("cargo") - .args(&cmd_args) - .current_dir(&component_dir) - .spawn()?; - child.wait()?; - let output_file = Path::new(&target) - .join("wasm32-wasi") - .join("debug") - .join(name) - .with_extension("wasm"); - println!("output file: {output_file:?}"); - component_build = output_file; - } - Ok(Component::try_from(component_build.as_path())?) - } - - fn set_up_runtime(name: &str) -> Result<(Component, Runtime), Box> { - let contracts_dir = test_dir(); - let components_dir = test_dir(); - let secrets_dir = test_dir(); + fn setup_runtime(name: &str) -> Result<(Component, Runtime), Box> { + const TEST_PREFIX: &str = "component-api"; + let _ = tracing_subscriber::fmt().with_env_filter("info").try_init(); + let contracts_dir = crate::tests::test_dir(TEST_PREFIX); + let components_dir = crate::tests::test_dir(TEST_PREFIX); + let secrets_dir = crate::tests::test_dir(TEST_PREFIX); let contract_store = ContractStore::new(contracts_dir, 10_000)?; let component_store = ComponentStore::new(components_dir, 10_000)?; @@ -355,7 +316,10 @@ mod test { let mut runtime = Runtime::build(contract_store, component_store, secret_store, false).unwrap(); - let component = get_test_component(name).unwrap(); + let component = { + let bytes = crate::tests::get_test_module(name)?; + Component::from(bytes) + }; let _ = runtime.component_store.store_component(component.clone()); let key = XChaCha20Poly1305::generate_key(&mut OsRng); @@ -375,7 +339,7 @@ mod test { Arc::new(ContractCode::from(vec![1])), Parameters::from(vec![]), ); - let (component, mut runtime) = set_up_runtime(TEST_COMPONENT_1)?; + let (component, mut runtime) = setup_runtime(TEST_COMPONENT_1)?; let app = ContractInstanceId::try_from(contract.key.to_string()).unwrap(); // CreateInboxRequest message parts diff --git a/crates/locutus-runtime/src/contract.rs b/crates/locutus-runtime/src/contract.rs index a983a947a..f867c67e3 100644 --- a/crates/locutus-runtime/src/contract.rs +++ b/crates/locutus-runtime/src/contract.rs @@ -75,29 +75,31 @@ impl ContractRuntimeInterface for crate::Runtime { related: RelatedContracts, ) -> RuntimeResult { let req_bytes = parameters.size() + state.size(); - let instance = self.prepare_contract_call(key, parameters, req_bytes)?; - let linear_mem = self.linear_mem(&instance)?; + let running = self.prepare_contract_call(key, parameters, req_bytes)?; + let linear_mem = self.linear_mem(&running.instance)?; let param_buf_ptr = { - let mut param_buf = self.init_buf(&instance, parameters)?; + let mut param_buf = self.init_buf(&running.instance, parameters)?; param_buf.write(parameters)?; param_buf.ptr() }; let state_buf_ptr = { - let mut state_buf = self.init_buf(&instance, state)?; + let mut state_buf = self.init_buf(&running.instance, state)?; state_buf.write(state)?; state_buf.ptr() }; let related_buf_ptr = { let serialized = bincode::serialize(&related)?; - let mut related_buf = self.init_buf(&instance, &serialized)?; + let mut related_buf = self.init_buf(&running.instance, &serialized)?; related_buf.write(serialized)?; related_buf.ptr() }; - let validate_func: TypedFunction<(i64, i64, i64), FfiReturnTy> = instance - .exports - .get_typed_function(&self.wasm_store, "validate_state")?; + let validate_func: TypedFunction<(i64, i64, i64), FfiReturnTy> = + running + .instance + .exports + .get_typed_function(&self.wasm_store, "validate_state")?; let is_valid = unsafe { ContractInterfaceResult::from_raw( validate_func.call( @@ -122,21 +124,22 @@ impl ContractRuntimeInterface for crate::Runtime { ) -> RuntimeResult { // todo: if we keep this hot in memory on next calls overwrite the buffer with new delta let req_bytes = parameters.size() + delta.size(); - let instance = self.prepare_contract_call(key, parameters, req_bytes)?; - let linear_mem = self.linear_mem(&instance)?; + let running = self.prepare_contract_call(key, parameters, req_bytes)?; + let linear_mem = self.linear_mem(&running.instance)?; let param_buf_ptr = { - let mut param_buf = self.init_buf(&instance, parameters)?; + let mut param_buf = self.init_buf(&running.instance, parameters)?; param_buf.write(parameters)?; param_buf.ptr() }; let delta_buf_ptr = { - let mut delta_buf = self.init_buf(&instance, delta)?; + let mut delta_buf = self.init_buf(&running.instance, delta)?; delta_buf.write(delta)?; delta_buf.ptr() }; - let validate_func: TypedFunction<(i64, i64), FfiReturnTy> = instance + let validate_func: TypedFunction<(i64, i64), FfiReturnTy> = running + .instance .exports .get_typed_function(&self.wasm_store, "validate_delta")?; let is_valid = unsafe { @@ -166,29 +169,31 @@ impl ContractRuntimeInterface for crate::Runtime { // - the delta may not be necessarily the same size let req_bytes = parameters.size() + state.size() + update_data.iter().map(|e| e.size()).sum::(); - let instance = self.prepare_contract_call(key, parameters, req_bytes)?; - let linear_mem = self.linear_mem(&instance)?; + let running = self.prepare_contract_call(key, parameters, req_bytes)?; + let linear_mem = self.linear_mem(&running.instance)?; let param_buf_ptr = { - let mut param_buf = self.init_buf(&instance, parameters)?; + let mut param_buf = self.init_buf(&running.instance, parameters)?; param_buf.write(parameters)?; param_buf.ptr() }; let state_buf_ptr = { - let mut state_buf = self.init_buf(&instance, state)?; + let mut state_buf = self.init_buf(&running.instance, state)?; state_buf.write(state.clone())?; state_buf.ptr() }; let update_data_buf_ptr = { let serialized = bincode::serialize(update_data)?; - let mut update_data_buf = self.init_buf(&instance, &serialized)?; + let mut update_data_buf = self.init_buf(&running.instance, &serialized)?; update_data_buf.write(serialized)?; update_data_buf.ptr() }; - let validate_func: TypedFunction<(i64, i64, i64), FfiReturnTy> = instance - .exports - .get_typed_function(&self.wasm_store, "update_state")?; + let validate_func: TypedFunction<(i64, i64, i64), FfiReturnTy> = + running + .instance + .exports + .get_typed_function(&self.wasm_store, "update_state")?; let update_res = unsafe { ContractInterfaceResult::from_raw( validate_func.call( @@ -212,21 +217,22 @@ impl ContractRuntimeInterface for crate::Runtime { state: &WrappedState, ) -> RuntimeResult> { let req_bytes = parameters.size() + state.size(); - let instance = self.prepare_contract_call(key, parameters, req_bytes)?; - let linear_mem = self.linear_mem(&instance)?; + let running = self.prepare_contract_call(key, parameters, req_bytes)?; + let linear_mem = self.linear_mem(&running.instance)?; let param_buf_ptr = { - let mut param_buf = self.init_buf(&instance, parameters)?; + let mut param_buf = self.init_buf(&running.instance, parameters)?; param_buf.write(parameters)?; param_buf.ptr() }; let state_buf_ptr = { - let mut state_buf = self.init_buf(&instance, state)?; + let mut state_buf = self.init_buf(&running.instance, state)?; state_buf.write(state.clone())?; state_buf.ptr() }; - let summary_func: TypedFunction<(i64, i64), FfiReturnTy> = instance + let summary_func: TypedFunction<(i64, i64), FfiReturnTy> = running + .instance .exports .get_typed_function(&self.wasm_store, "summarize_state")?; @@ -254,26 +260,27 @@ impl ContractRuntimeInterface for crate::Runtime { summary: &StateSummary<'a>, ) -> RuntimeResult> { let req_bytes = parameters.size() + state.size() + summary.size(); - let instance = self.prepare_contract_call(key, parameters, req_bytes)?; - let linear_mem = self.linear_mem(&instance)?; + let running = self.prepare_contract_call(key, parameters, req_bytes)?; + let linear_mem = self.linear_mem(&running.instance)?; let param_buf_ptr = { - let mut param_buf = self.init_buf(&instance, parameters)?; + let mut param_buf = self.init_buf(&running.instance, parameters)?; param_buf.write(parameters)?; param_buf.ptr() }; let state_buf_ptr = { - let mut state_buf = self.init_buf(&instance, state)?; + let mut state_buf = self.init_buf(&running.instance, state)?; state_buf.write(state.clone())?; state_buf.ptr() }; let summary_buf_ptr = { - let mut summary_buf = self.init_buf(&instance, summary)?; + let mut summary_buf = self.init_buf(&running.instance, summary)?; summary_buf.write(summary)?; summary_buf.ptr() }; - let get_state_delta_func: TypedFunction<(i64, i64, i64), FfiReturnTy> = instance + let get_state_delta_func: TypedFunction<(i64, i64, i64), FfiReturnTy> = running + .instance .exports .get_typed_function(&self.wasm_store, "get_state_delta")?; @@ -299,88 +306,14 @@ impl ContractRuntimeInterface for crate::Runtime { #[cfg(test)] mod test { - use locutus_stdlib::prelude::WrappedContract; - use super::*; - use crate::component_store::ComponentStore; - use crate::{ - secrets_store::SecretsStore, ContractContainer, ContractStore, Runtime, WasmAPIVersion, - }; - use std::{ - path::{Path, PathBuf}, - process::Command, - sync::atomic::AtomicUsize, - }; + use crate::{secrets_store::SecretsStore, tests::setup_test_contract, ComponentStore, Runtime}; const TEST_CONTRACT_1: &str = "test_contract_1"; - static TEST_NO: AtomicUsize = AtomicUsize::new(0); - - fn test_dir() -> PathBuf { - let test_dir = std::env::temp_dir().join("locutus-test").join(format!( - "contract-api-test-{}", - TEST_NO.fetch_add(1, std::sync::atomic::Ordering::SeqCst) - )); - if !test_dir.exists() { - std::fs::create_dir_all(&test_dir).unwrap(); - } - test_dir - } - - fn get_test_contract(name: &str) -> Result> { - const CONTRACTS_DIR: &str = env!("CARGO_MANIFEST_DIR"); - let contracts = PathBuf::from(CONTRACTS_DIR); - let mut dirs = contracts.ancestors(); - let path = dirs.nth(2).unwrap(); - let contract_dir = path.join("tests").join(name.replace('_', "-")); - let mut contract_build = contract_dir - .join("build/locutus") - .join(name) - .with_extension("wasm"); - - if !contract_build.exists() { - let target = - std::env::var("CARGO_TARGET_DIR").map_err(|_| "CARGO_TARGET_DIR should be set")?; - println!("trying to compile the test contract, target: {target}"); - // attempt to compile it - const RUST_TARGET_ARGS: &[&str] = &["build", "--target"]; - const WASI_TARGET: &str = "wasm32-wasi"; - let cmd_args = RUST_TARGET_ARGS - .iter() - .copied() - .chain([WASI_TARGET]) - .collect::>(); - let mut child = Command::new("cargo") - .args(&cmd_args) - .current_dir(&contract_dir) - .spawn()?; - child.wait()?; - let output_file = Path::new(&target) - .join("wasm32-wasi") - .join("debug") - .join(name) - .with_extension("wasm"); - println!("output file: {output_file:?}"); - contract_build = output_file; - } - - Ok( - WrappedContract::try_from((contract_build.as_path(), Parameters::from(vec![]))) - .expect("contract found"), - ) - } - - fn set_up_test_contract(name: &str) -> RuntimeResult<(ContractStore, ContractKey)> { - let mut store = ContractStore::new(test_dir(), 10_000)?; - let contract = - ContractContainer::Wasm(WasmAPIVersion::V1(get_test_contract(name).unwrap())); - let key = contract.key(); - store.store_contract(contract)?; - Ok((store, key)) - } #[test] fn validate_state() -> Result<(), Box> { - let (store, key) = set_up_test_contract(TEST_CONTRACT_1)?; + let (store, key) = setup_test_contract(TEST_CONTRACT_1)?; let mut runtime = Runtime::build( store, ComponentStore::default(), @@ -411,7 +344,7 @@ mod test { #[test] fn validate_delta() -> Result<(), Box> { - let (store, key) = set_up_test_contract(TEST_CONTRACT_1)?; + let (store, key) = setup_test_contract(TEST_CONTRACT_1)?; let mut runtime = Runtime::build( store, ComponentStore::default(), @@ -440,7 +373,7 @@ mod test { #[test] fn update_state() -> Result<(), Box> { - let (store, key) = set_up_test_contract(TEST_CONTRACT_1)?; + let (store, key) = setup_test_contract(TEST_CONTRACT_1)?; let mut runtime = Runtime::build( store, ComponentStore::default(), @@ -465,7 +398,7 @@ mod test { #[test] fn summarize_state() -> Result<(), Box> { - let (store, key) = set_up_test_contract(TEST_CONTRACT_1)?; + let (store, key) = setup_test_contract(TEST_CONTRACT_1)?; let mut runtime = Runtime::build( store, ComponentStore::default(), @@ -486,7 +419,7 @@ mod test { #[test] fn get_state_delta() -> Result<(), Box> { - let (store, key) = set_up_test_contract(TEST_CONTRACT_1)?; + let (store, key) = setup_test_contract(TEST_CONTRACT_1)?; let mut runtime = Runtime::build( store, ComponentStore::default(), diff --git a/crates/locutus-runtime/src/lib.rs b/crates/locutus-runtime/src/lib.rs index a399c7f52..f4f7accad 100644 --- a/crates/locutus-runtime/src/lib.rs +++ b/crates/locutus-runtime/src/lib.rs @@ -5,10 +5,13 @@ mod component_store; mod contract; mod contract_store; pub(crate) mod error; +mod native_api; mod runtime; mod secrets_store; mod state_store; mod store; +#[cfg(test)] +pub(crate) mod tests; pub mod util; type DynError = Box; diff --git a/crates/locutus-runtime/src/native_api.rs b/crates/locutus-runtime/src/native_api.rs new file mode 100644 index 000000000..931235238 --- /dev/null +++ b/crates/locutus-runtime/src/native_api.rs @@ -0,0 +1,45 @@ +//! Implementation of native API's exported and available in the WASM modules. + +use dashmap::DashMap; +use once_cell::sync::Lazy; + +/// This is a map of starting addresses of the instance memory space. +/// +/// A hackish way of having the information necessary to compute the address +/// at which bytes must be written when calling host functions from the WASM modules. +pub(crate) static MEM_ADDR: Lazy> = Lazy::new(DashMap::default); + +type InstanceId = i64; + +#[inline(always)] +fn compute_ptr(ptr: i64, start_ptr: i64) -> *mut T { + (start_ptr + ptr) as _ +} + +pub(crate) mod time { + use super::*; + use chrono::{DateTime, Utc as UtcOriginal}; + use wasmer::{Function, Imports}; + + pub(crate) fn prepare_export(store: &mut wasmer::Store, imports: &mut Imports) { + let utc_now = Function::new_typed(store, utc_now); + imports.register_namespace("locutus_time", [("utc_now".to_owned(), utc_now.into())]); + } + + fn utc_now(id: i64, ptr: i64) { + if id == -1 { + panic!("unset module id"); + } + let start_ptr = *MEM_ADDR + .get(&id) + .expect("instance mem space not recorded") + .value(); + let now = UtcOriginal::now(); + let ptr = compute_ptr::>(ptr, start_ptr); + // eprintln!("{ptr:p} ({}) outside", ptr as i64); + unsafe { + let ptr = ptr as *mut DateTime; + ptr.write(now); + }; + } +} diff --git a/crates/locutus-runtime/src/runtime.rs b/crates/locutus-runtime/src/runtime.rs index 8e62bf300..6df11631a 100644 --- a/crates/locutus-runtime/src/runtime.rs +++ b/crates/locutus-runtime/src/runtime.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::{collections::HashMap, sync::atomic::AtomicI64}; use locutus_stdlib::{ buf::{BufferBuilder, BufferMut}, @@ -8,9 +8,41 @@ use wasmer::{imports, Bytes, Imports, Instance, Memory, MemoryType, Module, Stor use crate::{ component_store::ComponentStore, contract_store::ContractStore, error::RuntimeInnerError, - secrets_store::SecretsStore, RuntimeResult, + native_api, secrets_store::SecretsStore, RuntimeResult, }; +static INSTANCE_ID: AtomicI64 = AtomicI64::new(0); + +pub(crate) struct RunningInstance { + pub id: i64, + pub instance: Instance, +} + +impl Drop for RunningInstance { + fn drop(&mut self) { + let _ = native_api::MEM_ADDR.remove(&self.id); + } +} + +impl RunningInstance { + fn new(rt: &mut Runtime, instance: Instance) -> RuntimeResult { + let memory = rt + .host_memory + .as_ref() + .map(Ok) + .unwrap_or_else(|| instance.exports.get_memory("memory"))?; + let set_id: TypedFunction = instance + .exports + .get_typed_function(&rt.wasm_store, "__locutus_set_id") + .unwrap(); + let id = INSTANCE_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + set_id.call(&mut rt.wasm_store, id).unwrap(); + let ptr = memory.view(&rt.wasm_store).data_ptr() as i64; + native_api::MEM_ADDR.insert(id, ptr); + Ok(Self { instance, id }) + } +} + #[derive(thiserror::Error, Debug)] pub enum ContractExecError { #[error(transparent)] @@ -58,7 +90,7 @@ impl Runtime { host_mem: bool, ) -> RuntimeResult { let mut store = Self::instance_store(); - let (host_memory, top_level_imports) = if host_mem { + let (host_memory, mut top_level_imports) = if host_mem { let mem = Self::instance_host_mem(&mut store)?; let imports = imports! { "env" => { @@ -69,6 +101,7 @@ impl Runtime { } else { (None, imports! {}) }; + native_api::time::prepare_export(&mut store, &mut top_level_imports); Ok(Self { wasm_store: store, @@ -122,7 +155,7 @@ impl Runtime { key: &ContractKey, parameters: &Parameters, req_bytes: usize, - ) -> RuntimeResult { + ) -> RuntimeResult { let module = if let Some(module) = self.contract_modules.get(key) { module } else { @@ -141,14 +174,14 @@ impl Runtime { .clone(); let instance = self.prepare_instance(&module)?; self.set_instance_mem(req_bytes, &instance)?; - Ok(instance) + RunningInstance::new(self, instance) } pub(crate) fn prepare_component_call( &mut self, key: &ComponentKey, req_bytes: usize, - ) -> RuntimeResult { + ) -> RuntimeResult { let module = if let Some(module) = self.component_modules.get(key) { module } else { @@ -163,7 +196,7 @@ impl Runtime { .clone(); let instance = self.prepare_instance(&module)?; self.set_instance_mem(req_bytes, &instance)?; - Ok(instance) + RunningInstance::new(self, instance) } fn set_instance_mem(&mut self, req_bytes: usize, instance: &Instance) -> RuntimeResult<()> { @@ -243,17 +276,13 @@ impl Runtime { // #[cfg(not(test))] // fn instance_store() -> Store { // use wasmer::Universal; - // if cfg!(target_arch = "aarch64") { // use wasmer::Cranelift; - // Store::new(&Universal::new(Cranelift::new()).engine()) // } else { // use wasmer_compiler_llvm::LLVM; - // Store::new(&Universal::new(LLVM::new()).engine()) // } - // // use wasmer::Dylib; // // Store::new(&Dylib::headless().engine()) // } diff --git a/crates/locutus-runtime/src/tests/mod.rs b/crates/locutus-runtime/src/tests/mod.rs new file mode 100644 index 000000000..701761b50 --- /dev/null +++ b/crates/locutus-runtime/src/tests/mod.rs @@ -0,0 +1,81 @@ +use std::{ + path::{Path, PathBuf}, + process::Command, + sync::{atomic::AtomicUsize, Arc}, +}; + +use locutus_stdlib::prelude::{ + ContractCode, ContractContainer, ContractKey, WasmAPIVersion, WrappedContract, +}; + +use crate::ContractStore; + +mod time; + +static TEST_NO: AtomicUsize = AtomicUsize::new(0); + +pub(crate) fn test_dir(prefix: &str) -> PathBuf { + let test_dir = std::env::temp_dir().join("locutus-test").join(format!( + "{prefix}-test-{}", + TEST_NO.fetch_add(1, std::sync::atomic::Ordering::SeqCst) + )); + if !test_dir.exists() { + std::fs::create_dir_all(&test_dir).unwrap(); + } + test_dir +} + +pub(crate) fn get_test_module(name: &str) -> Result, Box> { + let module_path = { + const CONTRACTS_DIR: &str = env!("CARGO_MANIFEST_DIR"); + let contracts = PathBuf::from(CONTRACTS_DIR); + let mut dirs = contracts.ancestors(); + let path = dirs.nth(2).unwrap(); + path.join("tests").join(name.replace('_', "-")) + }; + let mut contract_build_path = module_path + .join("build/locutus") + .join(name) + .with_extension("wasm"); + if !contract_build_path.exists() { + const TARGET_DIR_VAR: &str = "CARGO_TARGET_DIR"; + let target = std::env::var(TARGET_DIR_VAR).map_err(|_| "CARGO_TARGET_DIR should be set")?; + println!("trying to compile the test contract, target: {target}"); + // attempt to compile it + const RUST_TARGET_ARGS: &[&str] = &["build", "--target"]; + const WASI_TARGET: &str = "wasm32-wasi"; + let cmd_args = RUST_TARGET_ARGS + .iter() + .copied() + .chain([WASI_TARGET]) + .collect::>(); + let mut child = Command::new("cargo") + .args(&cmd_args) + .current_dir(&module_path) + .spawn()?; + child.wait()?; + let output_file = Path::new(&target) + .join("wasm32-wasi") + .join("debug") + .join(name) + .with_extension("wasm"); + println!("output file: {output_file:?}"); + contract_build_path = output_file; + } + Ok(std::fs::read(contract_build_path)?) +} + +pub fn setup_test_contract( + name: &str, +) -> Result<(ContractStore, ContractKey), Box> { + let _ = tracing_subscriber::fmt().with_env_filter("info").try_init(); + let mut store = ContractStore::new(crate::tests::test_dir("contract"), 10_000)?; + let contract_bytes = WrappedContract::new( + Arc::new(ContractCode::from(get_test_module(name)?)), + vec![].into(), + ); + let contract = ContractContainer::Wasm(WasmAPIVersion::V1(contract_bytes)); + let key = contract.key(); + store.store_contract(contract)?; + Ok((store, key)) +} diff --git a/crates/locutus-runtime/src/tests/time.rs b/crates/locutus-runtime/src/tests/time.rs new file mode 100644 index 000000000..b2ca43493 --- /dev/null +++ b/crates/locutus-runtime/src/tests/time.rs @@ -0,0 +1,27 @@ +//! A test WASM module that checkes that the `time` module in the std lib works correctly. + +use wasmer::TypedFunction; + +use crate::{ComponentStore, Runtime, SecretsStore}; + +#[test] +fn now() -> Result<(), Box> { + let (store, key) = super::setup_test_contract("test_contract_2")?; + let mut runtime = Runtime::build( + store, + ComponentStore::default(), + SecretsStore::default(), + false, + ) + .unwrap(); + runtime.enable_wasi = true; + + let module = runtime.prepare_contract_call(&key, &vec![].into(), 1_000)?; + let f: TypedFunction<(), ()> = module + .instance + .exports + .get_function("time_func")? + .typed(&runtime.wasm_store)?; + f.call(&mut runtime.wasm_store)?; + Ok(()) +} diff --git a/crates/locutus-stdlib/Cargo.toml b/crates/locutus-stdlib/Cargo.toml index 82d417944..c5ae318c1 100644 --- a/crates/locutus-stdlib/Cargo.toml +++ b/crates/locutus-stdlib/Cargo.toml @@ -15,6 +15,7 @@ bincode = "1" byteorder = "1" blake2 = { version = "0.10", features = [ "std" ] } bs58 = "0.4" +chrono = { workspace = true, default-features = false, features = ["alloc", "serde"] } futures = { workspace = true } once_cell = "1" rmpv = { version = "1"} diff --git a/crates/locutus-stdlib/src/api.rs b/crates/locutus-stdlib/src/client_api.rs similarity index 62% rename from crates/locutus-stdlib/src/api.rs rename to crates/locutus-stdlib/src/client_api.rs index c0792a2c8..c64813962 100644 --- a/crates/locutus-stdlib/src/api.rs +++ b/crates/locutus-stdlib/src/client_api.rs @@ -1,3 +1,15 @@ +//! A node client API. Intended to be used from applications (web or otherwise) using the +//! node capabilities to execute contract, component, etc. instructions and communicating +//! over the network. +//! +//! Communication, independent of the transport, revolves around the [`ClientRequest`] +//! and [`HostResponse`] types. +//! +//! Currently the clients available are: +//! - `websocket`: +//! - `regular` (native): Using TCP transport directly, for native applications programmed in Rust. +//! - `browser` (wasm): Via wasm-bindgen (and by extension web-sys). +//! (In order to use this client from JS/Typescript refer to the Typescript std lib). mod client_events; #[cfg(target_family = "unix")] diff --git a/crates/locutus-stdlib/src/api/browser.rs b/crates/locutus-stdlib/src/client_api/browser.rs similarity index 100% rename from crates/locutus-stdlib/src/api/browser.rs rename to crates/locutus-stdlib/src/client_api/browser.rs diff --git a/crates/locutus-stdlib/src/api/client_events.rs b/crates/locutus-stdlib/src/client_api/client_events.rs similarity index 100% rename from crates/locutus-stdlib/src/api/client_events.rs rename to crates/locutus-stdlib/src/client_api/client_events.rs diff --git a/crates/locutus-stdlib/src/api/regular.rs b/crates/locutus-stdlib/src/client_api/regular.rs similarity index 99% rename from crates/locutus-stdlib/src/api/regular.rs rename to crates/locutus-stdlib/src/client_api/regular.rs index b9292a0e2..9a96f2a22 100644 --- a/crates/locutus-stdlib/src/api/regular.rs +++ b/crates/locutus-stdlib/src/client_api/regular.rs @@ -198,7 +198,7 @@ async fn process_response( #[cfg(test)] mod test { - use crate::api::HostResponse; + use crate::client_api::HostResponse; use super::*; use std::{net::Ipv4Addr, sync::atomic::AtomicU16, time::Duration}; diff --git a/crates/locutus-stdlib/src/component_interface.rs b/crates/locutus-stdlib/src/component_interface.rs index c9fe3a197..6d3704ec4 100644 --- a/crates/locutus-stdlib/src/component_interface.rs +++ b/crates/locutus-stdlib/src/component_interface.rs @@ -1,6 +1,7 @@ use std::{ borrow::{Borrow, Cow}, fmt::Display, + ops::Deref, path::Path, }; @@ -13,6 +14,8 @@ use crate::prelude::ContractInstanceId; const APPLICATION_HASH_SIZE: usize = 32; const COMPONENT_HASH_LENGTH: usize = 32; +type Secret = Vec; + /// Executable component #[derive(Debug, Serialize, Deserialize, Clone)] #[serde_as] @@ -109,10 +112,16 @@ impl SecretsId { } } +impl Display for SecretsId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.encode()) + } +} + pub trait ComponentInterface { /// Process inbound message, producing zero or more outbound messages in response /// Note that all state for the component must be stored using the secret mechanism. - fn process(messages: InboundComponentMsg) -> Result, ComponentError>; + fn process(message: InboundComponentMsg) -> Result, ComponentError>; } #[serde_as] @@ -147,6 +156,7 @@ impl Display for ComponentKey { } } +#[non_exhaustive] #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct ComponentContext(pub Vec); @@ -229,7 +239,8 @@ impl InboundComponentMsg<'_> { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct GetSecretResponse { pub key: SecretsId, - pub value: Option>, + pub value: Option, + #[serde(skip)] pub context: ComponentContext, } @@ -260,9 +271,10 @@ impl ApplicationMessage { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct UserInputResponse<'a> { - request_id: u32, + pub request_id: u32, #[serde(borrow)] - response: ClientResponse<'a>, + pub response: ClientResponse<'a>, + pub context: ComponentContext, } impl UserInputResponse<'_> { @@ -270,15 +282,18 @@ impl UserInputResponse<'_> { UserInputResponse { request_id: self.request_id, response: self.response.into_owned(), + context: self.context, } } } #[derive(Serialize, Deserialize, Debug)] pub enum OutboundComponentMsg { - // from the apps + // for the apps ApplicationMessage(ApplicationMessage), RequestUserInput(#[serde(deserialize_with = "deser_func")] UserInputRequest<'static>), + // todo: remove when context can be accessed from the component environment and we pass it as reference + ContextUpdated(ComponentContext), // from the node GetSecretRequest(GetSecretRequest), SetSecretRequest(SetSecretRequest), @@ -309,6 +324,7 @@ impl OutboundComponentMsg { OutboundComponentMsg::RandomBytesRequest(_) => false, OutboundComponentMsg::SetSecretRequest(_) => false, OutboundComponentMsg::RequestUserInput(_) => true, + OutboundComponentMsg::ContextUpdated(_) => true, } } @@ -356,7 +372,7 @@ pub struct GetSecretRequest { pub struct SetSecretRequest { pub key: SecretsId, /// Sets or unsets (if none) a value associated with the key. - pub value: Option>, + pub value: Option, } #[serde_as] @@ -367,6 +383,16 @@ pub struct NotificationMessage<'a>( Cow<'a, [u8]>, ); +impl TryFrom<&serde_json::Value> for NotificationMessage<'static> { + type Error = (); + + fn try_from(json: &serde_json::Value) -> Result, ()> { + // todo: validate format when we have a better idea of what we want here + let bytes = serde_json::to_vec(json).unwrap(); + Ok(Self(Cow::Owned(bytes))) + } +} + impl NotificationMessage<'_> { pub fn into_owned(self) -> NotificationMessage<'static> { NotificationMessage(self.0.into_owned().into()) @@ -381,7 +407,18 @@ pub struct ClientResponse<'a>( Cow<'a, [u8]>, ); +impl Deref for ClientResponse<'_> { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + impl ClientResponse<'_> { + pub fn new(response: Vec) -> Self { + Self(response.into()) + } pub fn into_owned(self) -> ClientResponse<'static> { ClientResponse(self.0.into_owned().into()) } @@ -389,12 +426,12 @@ impl ClientResponse<'_> { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct UserInputRequest<'a> { - request_id: u32, + pub request_id: u32, #[serde(borrow)] /// An interpretable message by the notification system. - message: NotificationMessage<'a>, + pub message: NotificationMessage<'a>, /// If a response is required from the user they can be chosen from this list. - responses: Vec>, + pub responses: Vec>, } impl UserInputRequest<'_> { diff --git a/crates/locutus-stdlib/src/contract_interface.rs b/crates/locutus-stdlib/src/contract_interface.rs index 24b5650e7..ba0dde7fa 100644 --- a/crates/locutus-stdlib/src/contract_interface.rs +++ b/crates/locutus-stdlib/src/contract_interface.rs @@ -65,6 +65,7 @@ impl WsApiError { pub struct UpdateModification<'a> { #[serde(borrow)] pub new_state: Option>, + /// Request an other contract so updates can be resolved. pub related: Vec, } diff --git a/crates/locutus-stdlib/src/global.rs b/crates/locutus-stdlib/src/global.rs new file mode 100644 index 000000000..683fbc23d --- /dev/null +++ b/crates/locutus-stdlib/src/global.rs @@ -0,0 +1,9 @@ +/// An instance ID, this is usually modified by the runtime when instancing a module. +pub(crate) static mut INSTANCE_ID: i64 = -1i64; + +#[no_mangle] +extern "C" fn __locutus_set_id(id: i64) { + unsafe { + INSTANCE_ID = id; + } +} diff --git a/crates/locutus-stdlib/src/lib.rs b/crates/locutus-stdlib/src/lib.rs index 300d71686..754fa6bd6 100644 --- a/crates/locutus-stdlib/src/lib.rs +++ b/crates/locutus-stdlib/src/lib.rs @@ -1,4 +1,6 @@ //! Standard library provided by the Freenet project to be able to write Locutus-compatible contracts. +#[doc(hidden)] +pub mod buf; #[cfg(all( feature = "net", any( @@ -10,10 +12,11 @@ target_family = "unix" ) ))] -pub mod api; -pub mod buf; +pub mod client_api; mod component_interface; -pub mod contract_interface; +mod contract_interface; +pub(crate) mod global; +pub mod time; mod versioning; #[cfg(feature = "xz2")] pub mod web; diff --git a/crates/locutus-stdlib/src/time.rs b/crates/locutus-stdlib/src/time.rs new file mode 100644 index 000000000..f67d1bb4e --- /dev/null +++ b/crates/locutus-stdlib/src/time.rs @@ -0,0 +1,22 @@ +//! Temporal quantification. + +use std::mem::MaybeUninit; + +use chrono::{DateTime, Utc}; + +pub fn now() -> DateTime { + let mut uninit = MaybeUninit::>::uninit(); + let ptr = uninit.as_mut_ptr() as usize as i64; + // eprintln!("{ptr} inside"); + unsafe { + utc_now(crate::global::INSTANCE_ID, ptr); + uninit.assume_init(); + std::mem::transmute(uninit) + } +} + +#[link(wasm_import_module = "locutus_time")] +extern "C" { + #[doc(hidden)] + fn utc_now(id: i64, ptr: i64); +} diff --git a/modules/antiflood-tokens/Cargo.lock b/modules/antiflood-tokens/Cargo.lock new file mode 100644 index 000000000..f026a1402 --- /dev/null +++ b/modules/antiflood-tokens/Cargo.lock @@ -0,0 +1,1398 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf6ccdb167abbf410dcb915cabd428929d7f6a04980b54a11f26a39f1c7f7107" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +dependencies = [ + "serde", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "blake2" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b12e5fd123190ce1c2e559308a94c9bacad77907d4c6005d9e58fe1a0689e55e" +dependencies = [ + "digest 0.10.6", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bumpalo" +version = "3.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cc" +version = "1.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" + +[[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.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-integer", + "num-traits", + "serde", + "time 0.1.45", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +dependencies = [ + "libc", +] + +[[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 = "curve25519-dalek" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "cxx" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a41a86530d0fe7f5d9ea779916b7cadd2d4f9add748b99c2c029cbbdfaf453" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06416d667ff3e3ad2df1cd8cd8afae5da26cf9cec4d0825040f88b5ca659a2f0" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "820a9a2af1669deeef27cb271f476ffd196a2c4b6731336011e0ba63e2c7cf71" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08a6e2fcc370a089ad3b4aaf54db3b1b4cee38ddabce5896b33eb693275f470" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "darling" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer 0.10.3", + "crypto-common", + "subtle", +] + +[[package]] +name = "ed25519" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" +dependencies = [ + "serde", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand", + "serde", + "serde_bytes", + "sha2", + "zeroize", +] + +[[package]] +name = "filetime" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b9663d381d07ae25dc88dbdf27df458faa83a9b25336bcac83d5e452b5fc9d3" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "windows-sys", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" + +[[package]] +name = "futures-executor" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" + +[[package]] +name = "futures-macro" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + +[[package]] +name = "futures-task" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" + +[[package]] +name = "futures-util" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" +dependencies = [ + "ahash", + "serde", +] + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "iana-time-zone" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "itoa" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" + +[[package]] +name = "js-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +dependencies = [ + "wasm-bindgen", +] + +[[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.137" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" + +[[package]] +name = "link-cplusplus" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] + +[[package]] +name = "locutus-aft-allocation-record" +version = "0.1.0" +dependencies = [ + "bincode", + "chrono", + "ed25519-dalek", + "hashbrown 0.13.1", + "locutus-aft-interface", + "locutus-stdlib", + "serde", +] + +[[package]] +name = "locutus-aft-generator" +version = "0.1.0" +dependencies = [ + "bincode", + "bs58", + "chrono", + "ed25519-dalek", + "hashbrown 0.13.1", + "locutus-aft-interface", + "locutus-stdlib", + "serde", + "serde_json", +] + +[[package]] +name = "locutus-aft-interface" +version = "0.1.0" +dependencies = [ + "bincode", + "bs58", + "chrono", + "ed25519-dalek", + "hashbrown 0.13.1", + "locutus-stdlib", + "serde", + "strum", + "thiserror", +] + +[[package]] +name = "locutus-macros" +version = "0.0.3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "locutus-stdlib" +version = "0.0.3" +dependencies = [ + "arrayvec", + "bincode", + "blake2", + "bs58", + "byteorder", + "chrono", + "futures", + "locutus-macros", + "once_cell", + "rmp-serde", + "rmpv", + "semver", + "serde", + "serde_bytes", + "serde_json", + "serde_with", + "tar", + "thiserror", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[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.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "paste" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "rmp" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44519172358fd6d58656c86ab8e7fbc9e1490c3e8f14d35ed78ca0dd07403c9f" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "rmp-serde" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5b13be192e0220b8afb7222aa5813cb62cc269ebb5cac346ca6487681d2913e" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + +[[package]] +name = "rmpv" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de8813b3a2f95c5138fe5925bfb8784175d88d6bff059ba8ce090aa891319754" +dependencies = [ + "num-traits", + "rmp", +] + +[[package]] +name = "rustversion" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "scratch" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + +[[package]] +name = "semver" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +dependencies = [ + "serde", +] + +[[package]] +name = "serde" +version = "1.0.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25bf4a5a814902cd1014dbccfa4d4560fb8432c779471e96e035602519f82eef" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap", + "serde", + "serde_json", + "serde_with_macros", + "time 0.3.17", +] + +[[package]] +name = "serde_with_macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3452b4c0f6c1e357f73fdb87cd1efabaa12acf328c7a528e252893baeb3f4aa" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "tar" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "time" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[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 = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasm-bindgen" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +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.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +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.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + +[[package]] +name = "xattr" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" +dependencies = [ + "libc", +] + +[[package]] +name = "zeroize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] diff --git a/modules/antiflood-tokens/Cargo.toml b/modules/antiflood-tokens/Cargo.toml new file mode 100644 index 000000000..96116f7ae --- /dev/null +++ b/modules/antiflood-tokens/Cargo.toml @@ -0,0 +1,13 @@ +[workspace] +resolver = "2" +members = ["components/token-generator", "contracts/token-allocation-record", "interfaces"] + +[workspace.dependencies] +bincode = { version = "1" } +bs58 = "0.4" +chrono = { version = "0.4", default-features = false, features = ["alloc", "serde"] } +ed25519-dalek = { version = "1", no-default-features = true, features = ["serde"] } +hashbrown = { version = "0.13", features = ["serde"] } +locutus-stdlib = { version = "0.0.3", path = "../../crates/locutus-stdlib" } +serde = { version = "1", features = ["derive"] } +serde_json = { version = "1" } \ No newline at end of file diff --git a/modules/antiflood-tokens/README.md b/modules/antiflood-tokens/README.md new file mode 100644 index 000000000..e3ed45b83 --- /dev/null +++ b/modules/antiflood-tokens/README.md @@ -0,0 +1,23 @@ +# Description + +... + +# Functioning + +Some characteristics to take into account: + +- Tokens are "generated" (or available) by the component all the time. Past slots may have been + allocated or not, in which case they are stillf ree to use. + +Example of how the AFT module can be used, in the context of a mailing application: + +1. Alice (sender) has Bob (receiver) public key and wants to send an email to Bob. +2. Bob's inbox contract specifies the token assignment criteria (tier, recency, etc.). + - Bob is able to change that setting and those setting must be accesible publically. + The contract must keep track of when changes have been done to the criteria to not invalidate old messages. + Messages should be indexed, and we can use that to keep track of what settings should apply to each message. + - Tokens max allowed age is specified by the inbox contract of the receiver. +3. The AFT component verifies that Alice agrees with allocating tokens for Bob's messages (or all messages). After which the message is sent to Bob, with the allocated token attached. +4. Bob's inbox contract uses the related contract mechanism to verify that Alice's token assignment is present on Alice's token record to avoid double-spending. +5. The AFT generator contract and its signature match the message. +6. Bob periodically reads his inbox and clears his inbox contract once the messages are downloaded/read. diff --git a/modules/antiflood-tokens/components/token-generator/Cargo.toml b/modules/antiflood-tokens/components/token-generator/Cargo.toml new file mode 100644 index 000000000..3246643f3 --- /dev/null +++ b/modules/antiflood-tokens/components/token-generator/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "locutus-aft-generator" +version = "0.1.0" +edition = "2021" + +[dependencies] +bincode = { workspace = true } +bs58 = { workspace = true } +chrono = { workspace = true } +hashbrown = { workspace = true } +locutus-stdlib = { workspace = true } +ed25519-dalek = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } + +locutus-aft-interface = { path = "../../interfaces" } + +[lib] +crate-type = ["cdylib"] diff --git a/modules/antiflood-tokens/components/token-generator/src/lib.rs b/modules/antiflood-tokens/components/token-generator/src/lib.rs new file mode 100644 index 000000000..19a8186ba --- /dev/null +++ b/modules/antiflood-tokens/components/token-generator/src/lib.rs @@ -0,0 +1,417 @@ +use chrono::{DateTime, Duration, Utc}; +use ed25519_dalek::{Keypair, Signer}; +use hashbrown::{HashMap, HashSet}; +use locutus_aft_interface::{AllocationCriteria, TokenAllocationRecord, TokenAssignment}; +use locutus_stdlib::{prelude::*, time}; +use serde::{Deserialize, Serialize}; + +#[cfg(test)] +mod tests; + +type Assignee = ed25519_dalek::PublicKey; + +struct TokenComponent; + +impl ComponentInterface for TokenComponent { + fn process(message: InboundComponentMsg) -> Result, ComponentError> { + match message { + InboundComponentMsg::ApplicationMessage(ApplicationMessage { + app, + payload, + context, + processed, + .. + }) => { + if processed { + return Err(ComponentError::Other( + "cannot process an already processed message".into(), + )); + } + let mut context = Context::try_from(context)?; + let msg = TokenComponentMessage::try_from(&*payload)?; + match msg { + TokenComponentMessage::RequestNewToken(req) => { + allocate_token(&mut context, app, req) + } + TokenComponentMessage::Failure { .. } => Err(ComponentError::Other( + "unexpected message type: failure".into(), + )), + TokenComponentMessage::AllocatedToken { .. } => Err(ComponentError::Other( + "unexpected message type: allocated token".into(), + )), + } + } + InboundComponentMsg::UserResponse(UserInputResponse { + request_id, + response, + context, + }) => { + let mut context = Context::try_from(context)?; + context.waiting_for_user_input.remove(&request_id); + let response = serde_json::from_slice(&response) + .map_err(|err| ComponentError::Deser(format!("{err}")))?; + context.user_response.insert(request_id, response); + let context: ComponentContext = (&context).try_into()?; + Ok(vec![OutboundComponentMsg::ContextUpdated(context)]) + } + InboundComponentMsg::GetSecretResponse(GetSecretResponse { + key, + value, + context, + }) => { + let mut context = Context::try_from(context)?; + let secret = value.ok_or_else(|| { + ComponentError::Other(format!("secret not found for key: {key}")) + })?; + let keypair = Keypair::from_bytes(&secret) + .map_err(|err| ComponentError::Deser(format!("{err}")))?; + context.key_pair = Some(keypair); + let context: ComponentContext = (&context).try_into()?; + Ok(vec![OutboundComponentMsg::ContextUpdated(context)]) + } + InboundComponentMsg::RandomBytes(_) => Err(ComponentError::Other( + "unexpected message type: radom bytes".into(), + )), + } + } +} + +const RESPONSES: &[&str] = &["true", "false"]; + +fn user_input(criteria: &AllocationCriteria, assignee: &Assignee) -> NotificationMessage<'static> { + let assignee = bs58::encode(assignee).into_string(); + let notification_json = serde_json::json!({ + "user": assignee, + "token": { + "tier": criteria.frequency, + "max_age": format!("{} seconds", criteria.max_age.as_secs()) + } + }); + NotificationMessage::try_from(¬ification_json).unwrap() +} + +fn allocate_token( + context: &mut Context, + app: ContractInstanceId, + req: RequestNewToken, +) -> Result, ComponentError> { + let RequestNewToken { + request_id, + component_id, + criteria, + mut records, + assignee, + } = req; + let request = context + .waiting_for_user_input + .iter() + .find(|p| **p == request_id) + .copied(); + let response = context.user_response.get(&request_id); + match (&context.key_pair, request, response) { + (None, _, _) => { + // lacks keys; ask for keys + let context: ComponentContext = (&*context).try_into()?; + let request_secret = { + GetSecretRequest { + key: component_id.clone(), + context: context.clone(), + processed: false, + } + .into() + }; + let req_allocation = { + let msg = TokenComponentMessage::RequestNewToken(RequestNewToken { + request_id, + component_id, + criteria, + records, + assignee, + }); + OutboundComponentMsg::ApplicationMessage( + ApplicationMessage::new(app, msg.serialize()?, false).with_context(context), + ) + }; + Ok(vec![request_secret, req_allocation]) + } + (Some(_), None, None) => { + // request user input and add to waiting queue + context.waiting_for_user_input.insert(request_id); + let context: ComponentContext = (&*context).try_into()?; + let message = user_input(&criteria, &assignee); + let req_allocation = { + let msg = TokenComponentMessage::RequestNewToken(RequestNewToken { + request_id, + component_id, + criteria, + records, + assignee, + }); + OutboundComponentMsg::ApplicationMessage( + ApplicationMessage::new(app, msg.serialize()?, false).with_context(context), + ) + }; + let request_user_input = OutboundComponentMsg::RequestUserInput(UserInputRequest { + request_id, + responses: RESPONSES + .iter() + .map(|s| ClientResponse::new(s.as_bytes().to_vec())) + .collect(), + message, + }); + Ok(vec![request_user_input, req_allocation]) + } + (Some(_), Some(_), _) => { + // waiting for response + let context: ComponentContext = (&*context).try_into()?; + let req_allocation = { + let msg = TokenComponentMessage::RequestNewToken(RequestNewToken { + request_id, + component_id, + criteria, + records, + assignee, + }); + OutboundComponentMsg::ApplicationMessage( + ApplicationMessage::new(app, msg.serialize()?, false).with_context(context), + ) + }; + Ok(vec![req_allocation]) + } + (Some(keypair), _, Some(response)) => { + // got response, check if allocation is allowed and return to application + let application_response = match response { + Response::Allowed => { + let context: ComponentContext = (&*context).try_into()?; + let Some(assignment) = records.assign(assignee, &criteria, keypair) else { + let msg = TokenComponentMessage::Failure(FailureReason::NoFreeSlot { component_id, criteria } ); + return Ok(vec![OutboundComponentMsg::ApplicationMessage( + ApplicationMessage::new(app, msg.serialize()?, true).with_context(context), + )]); + }; + let msg = TokenComponentMessage::AllocatedToken { + component_id, + assignment, + records, + }; + OutboundComponentMsg::ApplicationMessage( + ApplicationMessage::new(app, msg.serialize()?, true).with_context(context), + ) + } + Response::NotAllowed => { + let context: ComponentContext = (&*context).try_into()?; + let msg = TokenComponentMessage::Failure(FailureReason::UserPermissionDenied); + OutboundComponentMsg::ApplicationMessage( + ApplicationMessage::new(app, msg.serialize()?, true).with_context(context), + ) + } + }; + context.user_response.remove(&request_id); + Ok(vec![application_response]) + } + } +} + +#[derive(Debug, Serialize, Deserialize)] +enum TokenComponentMessage { + RequestNewToken(RequestNewToken), + AllocatedToken { + component_id: SecretsId, + assignment: TokenAssignment, + /// An updated version of the record with the newly allocated token included + records: TokenAllocationRecord, + }, + Failure(FailureReason), +} + +impl TokenComponentMessage { + fn serialize(self) -> Result, ComponentError> { + bincode::serialize(&self).map_err(|err| ComponentError::Deser(format!("{err}"))) + } +} + +#[derive(Debug, Serialize, Deserialize)] +enum FailureReason { + /// The user didn't accept to allocate the tokens. + UserPermissionDenied, + /// No free slot to allocate with the requested criteria + NoFreeSlot { + component_id: SecretsId, + criteria: AllocationCriteria, + }, +} + +#[derive(Debug, Serialize, Deserialize)] +struct RequestNewToken { + request_id: u32, + component_id: SecretsId, + criteria: AllocationCriteria, + records: TokenAllocationRecord, + assignee: Assignee, +} + +#[derive(Debug, Serialize, Deserialize, Default)] +struct Context { + waiting_for_user_input: HashSet, + user_response: HashMap, + /// The token generator instance key pair (pub + secret key). + key_pair: Option, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum Response { + Allowed, + NotAllowed, +} + +impl TryFrom for Context { + type Error = ComponentError; + + fn try_from(value: ComponentContext) -> Result { + bincode::deserialize(&value.0).map_err(|err| ComponentError::Deser(format!("{err}"))) + } +} + +impl TryFrom<&Context> for ComponentContext { + type Error = ComponentError; + + fn try_from(value: &Context) -> Result { + bincode::serialize(value) + .map(ComponentContext::new) + .map_err(|err| ComponentError::Deser(format!("{err}"))) + } +} + +impl TryFrom<&[u8]> for TokenComponentMessage { + type Error = ComponentError; + + fn try_from(payload: &[u8]) -> Result { + bincode::deserialize(payload).map_err(|err| ComponentError::Deser(format!("{err}"))) + } +} + +/// This should be used by applications to assign tokens previously requested to this component. +pub trait TokenAssignmentExt { + fn append_unchecked(&mut self, assignment: TokenAssignment); +} + +/// This is used internally by the component to allocate new tokens on behave of the requesting client app. +/// +/// Conflicting assignments for the same time slot are not permitted and indicate that the generator is broken or malicious. +trait TokenAssignmentInternal { + fn assign( + &mut self, + assignee: Assignee, + criteria: &AllocationCriteria, + private_key: &Keypair, + ) -> Option; + + /// Given a datetime, get the newest free slot for this criteria. + fn next_free_assignment( + &self, + criteria: &AllocationCriteria, + current: DateTime, + ) -> Option>; +} + +impl TokenAssignmentExt for TokenAllocationRecord { + fn append_unchecked(&mut self, assignment: TokenAssignment) { + match self.get_mut_tier(&assignment.tier) { + Some(list) => { + list.push(assignment); + list.sort_unstable(); + } + None => { + self.insert(assignment.tier, vec![assignment]); + } + } + } +} + +impl TokenAssignmentInternal for TokenAllocationRecord { + /// Assigns the next theoretical free slot. This could be out of sync due to other concurrent requests so it may fail + /// to validate at the node. In that case the application should retry again, after refreshing the ledger version. + fn assign( + &mut self, + assignee: Assignee, + criteria: &AllocationCriteria, + keys: &Keypair, + ) -> Option { + let current = time::now(); + let time_slot = self.next_free_assignment(criteria, current)?; + let assignment = { + let msg = TokenAssignment::to_be_signed(&time_slot, &assignee, criteria.frequency); + let signature = keys.sign(&msg); + TokenAssignment { + tier: criteria.frequency, + time_slot, + assignee, + signature, + } + }; + self.append_unchecked(assignment.clone()); + Some(assignment) + } + + fn next_free_assignment( + &self, + criteria: &AllocationCriteria, + current: DateTime, + ) -> Option> { + let normalized = criteria.frequency.normalize_to_next(current); + let max_age = Duration::from_std(criteria.max_age).unwrap(); + // todo: add optimization branch where we check if all slots have been allocated upfront + match self.get_tier(&criteria.frequency) { + Some(currently_assigned) => { + let mut oldest_valid_observed = None; + let mut first_valid = None; + for (_idx, assignment) in currently_assigned.iter().enumerate() { + // dbg!( + // oldest_valid_observed.map(|a: &TokenAssignment| a.time_slot), + // first_valid, + // assignment.time_slot + // ); + if assignment.time_slot >= (normalized - max_age) { + match (oldest_valid_observed, first_valid) { + (None, None) => { + oldest_valid_observed = Some(assignment); + let oldest_valid = normalized - max_age; + if assignment.time_slot != oldest_valid { + first_valid = Some(oldest_valid); + } else { + let prev = assignment.previous_slot(); + if prev > oldest_valid { + first_valid = Some(prev); + } else { + first_valid = Some(assignment.next_slot()); + } + } + } + (Some(_), Some(first_valid_date)) => { + if first_valid_date == assignment.time_slot { + let next = assignment.next_slot(); + if next > normalized { + first_valid = None; + } else { + first_valid = Some(next); + } + } + } + _ => unreachable!(), + } + } + } + + if oldest_valid_observed.is_none() { + // first slot for the tier free + return Some(normalized - max_age); + } + if first_valid.is_some() { + return first_valid; + } + None + } + None => Some(normalized - max_age), + } + } +} diff --git a/modules/antiflood-tokens/components/token-generator/src/tests.rs b/modules/antiflood-tokens/components/token-generator/src/tests.rs new file mode 100644 index 000000000..65c4e98ce --- /dev/null +++ b/modules/antiflood-tokens/components/token-generator/src/tests.rs @@ -0,0 +1,132 @@ +use super::*; + +mod token_assignment { + use super::*; + use chrono::{NaiveDate, Timelike}; + use ed25519_dalek::{PublicKey, Signature}; + use locutus_aft_interface::Tier; + + fn get_assignment_date(y: i32, m: u32, d: u32) -> DateTime { + let naive = NaiveDate::from_ymd_opt(y, m, d) + .unwrap() + .and_hms_opt(0, 0, 0) + .unwrap(); + DateTime::::from_utc(naive, Utc) + } + + const TEST_TIER: Tier = Tier::Day1; + const MAX_DURATION_1Y: std::time::Duration = std::time::Duration::from_secs(365 * 24 * 3600); + + fn test_assignee() -> PublicKey { + PublicKey::from_bytes(&[1; ed25519_dalek::PUBLIC_KEY_LENGTH]).unwrap() + } + + #[test] + fn free_spot_first() { + let records = TokenAllocationRecord::new(HashMap::from_iter([( + TEST_TIER, + vec![TokenAssignment { + tier: TEST_TIER, + time_slot: get_assignment_date(2023, 1, 25), + assignee: test_assignee(), + signature: Signature::from([1; 64]), + }], + )])); + let assignment = records.next_free_assignment( + &AllocationCriteria::new(TEST_TIER, MAX_DURATION_1Y).unwrap(), + get_assignment_date(2023, 1, 27), + ); + assert_eq!(assignment.unwrap(), get_assignment_date(2022, 1, 27)); + } + + #[test] + fn free_spot_skip_first() { + let records = TokenAllocationRecord::new(HashMap::from_iter([( + TEST_TIER, + vec![ + TokenAssignment { + tier: TEST_TIER, + time_slot: get_assignment_date(2022, 1, 27), + assignee: test_assignee(), + signature: Signature::from([1; 64]), + }, + TokenAssignment { + tier: TEST_TIER, + time_slot: get_assignment_date(2023, 1, 26), + assignee: test_assignee(), + signature: Signature::from([1; 64]), + }, + ], + )])); + let assignment = records.next_free_assignment( + &AllocationCriteria::new(TEST_TIER, MAX_DURATION_1Y).unwrap(), + get_assignment_date(2023, 1, 27).with_minute(1).unwrap(), + ); + assert_eq!(assignment.unwrap(), get_assignment_date(2022, 1, 28)); + } + + #[test] + fn free_spot_skip_gap_1() { + let records = TokenAllocationRecord::new(HashMap::from_iter([( + TEST_TIER, + vec![ + TokenAssignment { + tier: TEST_TIER, + time_slot: get_assignment_date(2022, 1, 27), + assignee: test_assignee(), + signature: Signature::from([1; 64]), + }, + TokenAssignment { + tier: TEST_TIER, + time_slot: get_assignment_date(2022, 1, 29), + assignee: test_assignee(), + signature: Signature::from([1; 64]), + }, + ], + )])); + let assignment = records.next_free_assignment( + &AllocationCriteria::new(TEST_TIER, MAX_DURATION_1Y).unwrap(), + get_assignment_date(2023, 1, 27), + ); + assert_eq!(assignment.unwrap(), get_assignment_date(2022, 1, 28)); + + let records = TokenAllocationRecord::new(HashMap::from_iter([( + TEST_TIER, + vec![ + TokenAssignment { + tier: TEST_TIER, + time_slot: get_assignment_date(2022, 1, 27), + assignee: test_assignee(), + signature: Signature::from([1; 64]), + }, + TokenAssignment { + tier: TEST_TIER, + time_slot: get_assignment_date(2022, 1, 28), + assignee: test_assignee(), + signature: Signature::from([1; 64]), + }, + TokenAssignment { + tier: TEST_TIER, + time_slot: get_assignment_date(2022, 1, 30), + assignee: test_assignee(), + signature: Signature::from([1; 64]), + }, + ], + )])); + let assignment = records.next_free_assignment( + &AllocationCriteria::new(TEST_TIER, MAX_DURATION_1Y).unwrap(), + get_assignment_date(2023, 1, 27).with_minute(1).unwrap(), + ); + assert_eq!(assignment.unwrap(), get_assignment_date(2022, 1, 29)); + } + + #[test] + fn free_spot_new() { + let records = TokenAllocationRecord::new(HashMap::new()); + let assignment = records.next_free_assignment( + &AllocationCriteria::new(TEST_TIER, MAX_DURATION_1Y).unwrap(), + get_assignment_date(2023, 1, 27).with_minute(1).unwrap(), + ); + assert_eq!(assignment.unwrap(), get_assignment_date(2022, 1, 28)); + } +} diff --git a/modules/antiflood-tokens/contracts/token-allocation-record/Cargo.toml b/modules/antiflood-tokens/contracts/token-allocation-record/Cargo.toml new file mode 100644 index 000000000..5a745e241 --- /dev/null +++ b/modules/antiflood-tokens/contracts/token-allocation-record/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "locutus-aft-allocation-record" +version = "0.1.0" +edition = "2021" + +[dependencies] +bincode = { workspace = true } +chrono = { workspace = true } +hashbrown = {workspace = true } +locutus-stdlib = { workspace = true } +ed25519-dalek = { workspace = true } +serde = { workspace = true } + +locutus-aft-interface = { path = "../../interfaces" } + +[lib] +crate-type = ["cdylib"] diff --git a/modules/antiflood-tokens/contracts/token-allocation-record/src/lib.rs b/modules/antiflood-tokens/contracts/token-allocation-record/src/lib.rs new file mode 100644 index 000000000..068d64197 --- /dev/null +++ b/modules/antiflood-tokens/contracts/token-allocation-record/src/lib.rs @@ -0,0 +1,177 @@ +use ed25519_dalek::Verifier; +use locutus_aft_interface::{ + AllocationError, TokenAllocationRecord, TokenAllocationSummary, TokenAssignment, + TokenParameters, +}; +use locutus_stdlib::prelude::*; + +struct TokenAllocContract; + +impl ContractInterface for TokenAllocContract { + fn validate_state( + parameters: Parameters<'static>, + state: State<'static>, + _related: RelatedContracts<'static>, + ) -> Result { + let assigned_tokens = TokenAllocationRecord::try_from(state)?; + let params = TokenParameters::try_from(parameters)?; + for (_tier, assignments) in (&assigned_tokens).into_iter() { + for assignment in assignments { + if !assignment.is_valid(¶ms) { + return Ok(ValidateResult::Invalid); + } + } + } + Ok(ValidateResult::Valid) + } + + /// The contract verifies that the release times for a tier matches the tier. + /// + /// For example, a 15:30 UTC release time isn't permitted for hour_1 tier, but 15:00 UTC is permitted. + fn validate_delta( + parameters: Parameters<'static>, + delta: StateDelta<'static>, + ) -> Result { + let assigned_token = TokenAssignment::try_from(delta)?; + let params = TokenParameters::try_from(parameters)?; + Ok(assigned_token.is_valid(¶ms)) + } + + fn update_state( + parameters: Parameters<'static>, + state: State<'static>, + data: Vec>, + ) -> Result, ContractError> { + let mut assigned_tokens = TokenAllocationRecord::try_from(state)?; + let params = TokenParameters::try_from(parameters)?; + for update in data { + match update { + UpdateData::State(s) => { + let new_assigned_tokens = TokenAllocationRecord::try_from(s)?; + assigned_tokens + .merge(new_assigned_tokens, ¶ms) + .map_err(|err| { + tracing::error!("{err}"); + ContractError::InvalidUpdate + })?; + } + UpdateData::Delta(d) => { + let new_assigned_token = TokenAssignment::try_from(d)?; + assigned_tokens + .append(new_assigned_token, ¶ms) + .map_err(|err| { + tracing::error!("{err}"); + ContractError::InvalidUpdate + })?; + } + UpdateData::StateAndDelta { state, delta } => { + let new_assigned_tokens = TokenAllocationRecord::try_from(state)?; + assigned_tokens + .merge(new_assigned_tokens, ¶ms) + .map_err(|err| { + tracing::error!("{err}"); + ContractError::InvalidUpdate + })?; + let new_assigned_token = TokenAssignment::try_from(delta)?; + assigned_tokens + .append(new_assigned_token, ¶ms) + .map_err(|err| { + tracing::error!("{err}"); + ContractError::InvalidUpdate + })?; + } + _ => unreachable!(), + } + } + let update = assigned_tokens.try_into()?; + Ok(UpdateModification::valid(update)) + } + + fn summarize_state( + _parameters: Parameters<'static>, + state: State<'static>, + ) -> Result, ContractError> { + let assigned_tokens = TokenAllocationRecord::try_from(state)?; + let summary = assigned_tokens.summarize(); + summary.try_into() + } + + fn get_state_delta( + _parameters: Parameters<'static>, + state: State<'static>, + summary: StateSummary<'static>, + ) -> Result, ContractError> { + let assigned_tokens = TokenAllocationRecord::try_from(state)?; + let summary = TokenAllocationSummary::try_from(summary)?; + let delta = assigned_tokens.delta(&summary); + delta.try_into() + } +} + +trait TokenAssignmentExt { + fn is_valid(&self, params: &TokenParameters) -> bool; +} + +impl TokenAssignmentExt for TokenAssignment { + fn is_valid(&self, params: &TokenParameters) -> bool { + if !self.tier.is_valid_slot(self.time_slot) { + return false; + } + let msg = TokenAssignment::to_be_signed(&self.time_slot, &self.assignee, self.tier); + if params + .generator_public_key + .verify(&msg, &self.signature) + .is_err() + { + // not signed by the private key of this generator + return false; + } + true + } +} + +trait TokenAllocationRecordExt { + fn merge(&mut self, other: Self, params: &TokenParameters) -> Result<(), AllocationError>; + fn append( + &mut self, + assignment: TokenAssignment, + params: &TokenParameters, + ) -> Result<(), AllocationError>; +} + +impl TokenAllocationRecordExt for TokenAllocationRecord { + fn merge(&mut self, other: Self, params: &TokenParameters) -> Result<(), AllocationError> { + for (_, assignments) in other.into_iter() { + for assignment in assignments { + self.append(assignment, params)?; + } + } + Ok(()) + } + + fn append( + &mut self, + assignment: TokenAssignment, + params: &TokenParameters, + ) -> Result<(), AllocationError> { + match self.get_mut_tier(&assignment.tier) { + Some(list) => { + if list.binary_search(&assignment).is_err() { + if assignment.is_valid(params) { + list.push(assignment); + list.sort_unstable(); + Ok(()) + } else { + Err(AllocationError::invalid_assignment(assignment)) + } + } else { + Err(AllocationError::allocated_slot(&assignment)) + } + } + None => { + self.insert(assignment.tier, vec![assignment]); + Ok(()) + } + } + } +} diff --git a/modules/antiflood-tokens/interfaces/Cargo.toml b/modules/antiflood-tokens/interfaces/Cargo.toml new file mode 100644 index 000000000..669344ade --- /dev/null +++ b/modules/antiflood-tokens/interfaces/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "locutus-aft-interface" +version = "0.1.0" +edition = "2021" + +[dependencies] +bincode = { workspace = true } +bs58 = { workspace = true } +chrono = { workspace = true } +hashbrown = {workspace = true } +locutus-stdlib = { workspace = true } +ed25519-dalek = { workspace = true } +serde = { workspace = true } +strum = { version = "0.24", features = ["derive"] } +thiserror = "1" diff --git a/modules/antiflood-tokens/interfaces/src/lib.rs b/modules/antiflood-tokens/interfaces/src/lib.rs new file mode 100644 index 000000000..1bfe634ef --- /dev/null +++ b/modules/antiflood-tokens/interfaces/src/lib.rs @@ -0,0 +1,652 @@ +use std::fmt::Display; + +use chrono::{DateTime, Datelike, Duration, NaiveDate, SubsecRound, Timelike, Utc}; +use ed25519_dalek::{PublicKey, Signature}; +use hashbrown::HashMap; +use locutus_stdlib::prelude::*; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use strum::Display; + +type Assignment = ed25519_dalek::PublicKey; + +/// Contracts making use of the allocation must implement a type with this trait that allows +/// extracting the criteria for the given contract. +pub trait TokenAllocation: DeserializeOwned { + fn get_criteria(&self) -> AllocationCriteria; +} + +#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash, Display)] +#[strum(serialize_all = "lowercase")] +#[repr(u8)] +pub enum Tier { + Min1, + Min5, + Min10, + Min30, + Hour1, + Hour3, + Hour6, + Hour12, + Day1, + Day7, + Day15, + Day30, + Day90, + Day180, + Day365, +} + +impl Tier { + pub fn is_valid_slot(&self, dt: DateTime) -> bool { + match self { + Tier::Min1 => { + let vns = dt.nanosecond() == 0; + let vs = dt.second() == 0; + vns && vs + } + Tier::Min5 => Self::check_is_correct_minute(dt, 5), + Tier::Min10 => Self::check_is_correct_minute(dt, 10), + Tier::Min30 => Self::check_is_correct_minute(dt, 30), + Tier::Hour1 => { + let vns = dt.nanosecond() == 0; + let vs = dt.second() == 0; + let vm = dt.minute() == 0; + vns && vs && vm + } + Tier::Hour3 => Self::check_is_correct_hour(dt, 3), + Tier::Hour6 => Self::check_is_correct_hour(dt, 6), + Tier::Hour12 => Self::check_is_correct_hour(dt, 12), + Tier::Day1 => { + let vns = dt.nanosecond() == 0; + let vs = dt.second() == 0; + let vm = dt.minute() == 0; + let vh = dt.hour() == 0; + vns && vs && vm && vh + } + Tier::Day7 => Self::check_is_correct_day(dt, 7), + Tier::Day15 => Self::check_is_correct_day(dt, 15), + Tier::Day30 => Self::check_is_correct_day(dt, 30), + Tier::Day90 => Self::check_is_correct_day(dt, 90), + Tier::Day180 => Self::check_is_correct_day(dt, 180), + Tier::Day365 => Self::check_is_correct_day(dt, 365), + } + } + + fn check_is_correct_minute(dt: DateTime, base_min: u32) -> bool { + dt.second() == 0 && dt.nanosecond() == 0 && dt.minute() % base_min == 0 + } + + fn check_is_correct_hour(dt: DateTime, base_hour: u32) -> bool { + dt.minute() == 0 && dt.second() == 0 && dt.nanosecond() == 0 && dt.hour() % base_hour == 0 + } + + fn check_is_correct_day(dt: DateTime, base_day: i64) -> bool { + let year = get_date(dt.year() - 1, 12, 31); + let delta = dt - year; + dt.hour() == 0 + && dt.minute() == 0 + && dt.second() == 0 + && dt.nanosecond() == 0 + && delta.num_days() % base_day == 0 + } + + pub fn tier_duration(&self) -> std::time::Duration { + match self { + Tier::Min1 => Duration::minutes(1).to_std().unwrap(), + Tier::Min5 => Duration::minutes(5).to_std().unwrap(), + Tier::Min10 => Duration::minutes(10).to_std().unwrap(), + Tier::Min30 => Duration::minutes(30).to_std().unwrap(), + Tier::Hour1 => Duration::hours(1).to_std().unwrap(), + Tier::Hour3 => Duration::hours(3).to_std().unwrap(), + Tier::Hour6 => Duration::hours(6).to_std().unwrap(), + Tier::Hour12 => Duration::hours(12).to_std().unwrap(), + Tier::Day1 => Duration::days(1).to_std().unwrap(), + Tier::Day7 => Duration::days(7).to_std().unwrap(), + Tier::Day15 => Duration::days(15).to_std().unwrap(), + Tier::Day30 => Duration::days(30).to_std().unwrap(), + Tier::Day90 => Duration::days(90).to_std().unwrap(), + Tier::Day180 => Duration::days(180).to_std().unwrap(), + Tier::Day365 => Duration::days(365).to_std().unwrap(), + } + } + + /// Normalized the datetime to be the next valid date from the provided one compatible with the tier. + /// + /// The base reference datetime used for normalization for day tiers, is from the first day of the year (Gregorian calendar). + /// For the hour tiers, the first hour of the day; and for minute tiers, the first minute of the hour. + pub fn normalize_to_next(&self, mut time: DateTime) -> DateTime { + match self { + Tier::Min1 => { + let is_rounded = time.hour() == 0 && time.second() == 0 && time.nanosecond() == 0; + if !is_rounded { + let duration = chrono::Duration::from_std(self.tier_duration()).unwrap(); + time = time.with_second(0).unwrap(); + time = time.trunc_subsecs(0); + time += duration; + } + time + } + Tier::Min5 => self.normalize_to_next_minute(time, 5), + Tier::Min10 => self.normalize_to_next_minute(time, 10), + Tier::Min30 => self.normalize_to_next_minute(time, 15), + Tier::Hour1 => { + let is_rounded = time.hour() == 0 + && time.minute() == 0 + && time.second() == 0 + && time.nanosecond() == 0; + if !is_rounded { + let duration = chrono::Duration::from_std(self.tier_duration()).unwrap(); + time = time.with_second(0).unwrap().with_minute(0).unwrap(); + time = time.trunc_subsecs(0); + time += duration; + } + time + } + Tier::Hour3 => self.normalize_to_next_hour(time, 3), + Tier::Hour6 => self.normalize_to_next_hour(time, 6), + Tier::Hour12 => self.normalize_to_next_hour(time, 12), + Tier::Day1 => { + let is_rounded = time.hour() == 0 + && time.minute() == 0 + && time.second() == 0 + && time.nanosecond() == 0; + if !is_rounded { + let duration = chrono::Duration::from_std(self.tier_duration()).unwrap(); + time = time.with_second(0).unwrap().with_minute(0).unwrap(); + time = time.trunc_subsecs(0); + time += duration; + } + time + } + Tier::Day7 => self.normalize_to_next_day(time, 7), + Tier::Day15 => self.normalize_to_next_day(time, 15), + Tier::Day30 => self.normalize_to_next_day(time, 30), + Tier::Day90 => self.normalize_to_next_day(time, 90), + Tier::Day180 => self.normalize_to_next_day(time, 180), + Tier::Day365 => self.normalize_to_next_day(time, 365), + } + } + + fn normalize_to_next_minute(&self, mut time: DateTime, base_minute: u32) -> DateTime { + let is_rounded = + time.minute() % base_minute == 0 && time.second() == 0 && time.nanosecond() == 0; + if !is_rounded { + time = time.with_second(0).unwrap(); + time = time.trunc_subsecs(0); + let minutes_in_time = time.minute(); + let remainder_minutes = minutes_in_time % base_minute; + if remainder_minutes != 0 { + let duration = chrono::Duration::from_std(self.tier_duration()).unwrap(); + time = time.with_minute(time.minute() - remainder_minutes).unwrap(); + time += duration; + } + } + time + } + + fn normalize_to_next_hour(&self, mut time: DateTime, base_hour: u32) -> DateTime { + let is_rounded = time.hour() % base_hour == 0 + && time.minute() == 0 + && time.second() == 0 + && time.nanosecond() == 0; + if !is_rounded { + time = time.with_second(0).unwrap().with_minute(0).unwrap(); + time = time.trunc_subsecs(0); + let hours_in_time = time.hour(); + let remainder_hours = hours_in_time % base_hour; + if remainder_hours != 0 { + let duration = chrono::Duration::from_std(self.tier_duration()).unwrap(); + time = time.with_hour(time.hour() - remainder_hours).unwrap(); + time += duration; + } + } + time + } + + fn normalize_to_next_day(&self, mut time: DateTime, base_day: i64) -> DateTime { + let year = get_date(time.year() - 1, 12, 31); + let delta = time - year; + let is_rounded = time.hour() == 0 + && time.minute() == 0 + && time.second() == 0 + && time.nanosecond() == 0 + && delta.num_days() % base_day == 0; + if !is_rounded { + time = time.with_second(0).unwrap().with_minute(0).unwrap(); + time = time.trunc_subsecs(0); + let days_in_time = delta.num_days(); + let remainder_days = (days_in_time % base_day) as u32; + if remainder_days != 0 { + let duration = chrono::Duration::from_std(self.tier_duration()).unwrap(); + time = time.with_day(time.day() - remainder_days).unwrap(); + time += duration; + } + } + time + } +} + +fn get_date(y: i32, m: u32, d: u32) -> DateTime { + let naive = NaiveDate::from_ymd_opt(y, m, d) + .unwrap() + .and_hms_opt(0, 0, 0) + .unwrap(); + DateTime::::from_utc(naive, Utc) +} + +#[cfg(test)] +mod tier_tests { + use super::*; + + #[test] + fn is_correct_minute() { + let day7_tier = Tier::Day7; + assert!(day7_tier.is_valid_slot(get_date(2023, 1, 7))); + assert!(!day7_tier.is_valid_slot(get_date(2023, 1, 8))); + + let day30_tier = Tier::Day30; + assert!(day30_tier.is_valid_slot(get_date(2023, 1, 30))); + assert!(day30_tier.is_valid_slot(get_date(2023, 3, 1))); + assert!(!day30_tier.is_valid_slot(get_date(2023, 3, 30))); + } + + #[test] + fn is_correct_hour() { + let hour3_tier = Tier::Hour3; + assert!(hour3_tier.is_valid_slot(get_date(2023, 1, 7).with_hour(6).unwrap())); + assert!(!hour3_tier.is_valid_slot(get_date(2023, 1, 8).with_hour(7).unwrap())); + + let hour12_tier = Tier::Hour12; + assert!(hour12_tier.is_valid_slot(get_date(2023, 1, 30).with_hour(12).unwrap())); + assert!(hour12_tier.is_valid_slot(get_date(2023, 3, 1))); + assert!(!hour12_tier.is_valid_slot(get_date(2023, 3, 30).with_hour(13).unwrap())); + } + + #[test] + fn is_correct_day() { + let day7_tier = Tier::Day7; + assert!(day7_tier.is_valid_slot(get_date(2023, 1, 7))); + assert!(!day7_tier.is_valid_slot(get_date(2023, 1, 8))); + + let day30_tier = Tier::Day30; + assert!(day30_tier.is_valid_slot(get_date(2023, 1, 30))); + assert!(day30_tier.is_valid_slot(get_date(2023, 3, 1))); + assert!(!day30_tier.is_valid_slot(get_date(2023, 3, 30))); + } + + #[test] + fn minute_tier_normalization() { + let min5_tier = Tier::Min5; + let min5_normalized = + min5_tier.normalize_to_next(get_date(2023, 1, 1).with_minute(37).unwrap()); + assert_eq!( + min5_normalized, + get_date(2023, 1, 1).with_minute(40).unwrap() + ); + let min5_normalized = + min5_tier.normalize_to_next(get_date(2023, 1, 1).with_minute(8).unwrap()); + assert_eq!( + min5_normalized, + get_date(2023, 1, 1).with_minute(10).unwrap() + ); + + let min10_tier = Tier::Min10; + let min10_normalized = + min10_tier.normalize_to_next(get_date(2023, 1, 1).with_minute(22).unwrap()); + assert_eq!( + min10_normalized, + get_date(2023, 1, 1).with_minute(30).unwrap() + ); + let min10_tier = Tier::Min10; + let min10_normalized = + min10_tier.normalize_to_next(get_date(2023, 1, 1).with_minute(38).unwrap()); + assert_eq!( + min10_normalized, + get_date(2023, 1, 1).with_minute(40).unwrap() + ); + } + + #[test] + fn hour_tier_normalization() { + let hour6_tier = Tier::Hour6; + let hour6_normalized = + hour6_tier.normalize_to_next(get_date(2023, 1, 1).with_hour(4).unwrap()); + assert_eq!(hour6_normalized, get_date(2023, 1, 1).with_hour(6).unwrap()); + let hour6_normalized = + hour6_tier.normalize_to_next(get_date(2023, 1, 1).with_hour(17).unwrap()); + assert_eq!( + hour6_normalized, + get_date(2023, 1, 1).with_hour(18).unwrap() + ); + + let hour12_tier = Tier::Hour12; + let hour12_normalized = + hour12_tier.normalize_to_next(get_date(2023, 1, 1).with_hour(4).unwrap()); + assert_eq!( + hour12_normalized, + get_date(2023, 1, 1).with_hour(12).unwrap() + ); + let hour12_normalized = + hour12_tier.normalize_to_next(get_date(2023, 1, 1).with_hour(17).unwrap()); + assert_eq!(hour12_normalized, get_date(2023, 1, 2)); + } + + #[test] + fn day_tier_normalization() { + let day7_tier = Tier::Day7; + let day7_normalized = day7_tier.normalize_to_next(get_date(2023, 1, 17)); + assert_eq!(day7_normalized, get_date(2023, 1, 21)); + let day15_normalized = day7_tier.normalize_to_next(get_date(2023, 1, 31)); + assert_eq!(day15_normalized, get_date(2023, 2, 4)); + + let day15_tier = Tier::Day15; + let day15_normalized = day15_tier.normalize_to_next(get_date(2023, 1, 17)); + assert_eq!(day15_normalized, get_date(2023, 1, 30)); + let day15_normalized = day15_tier.normalize_to_next(get_date(2023, 1, 31)); + assert_eq!(day15_normalized, get_date(2023, 2, 14)); + } +} + +#[non_exhaustive] +#[derive(Serialize, Deserialize)] +pub struct TokenParameters { + pub generator_public_key: PublicKey, +} + +impl TryFrom> for TokenParameters { + type Error = ContractError; + fn try_from(params: Parameters<'_>) -> Result { + let this = bincode::deserialize_from(params.as_ref()) + .map_err(|err| ContractError::Deser(format!("{err}")))?; + Ok(this) + } +} + +#[derive(Debug, thiserror::Error)] +#[error(transparent)] +pub struct AllocationError(Box); + +impl AllocationError { + pub fn invalid_assignment(assignment: TokenAssignment) -> Self { + Self(Box::new(AllocationErrorInner::InvalidAssignment( + assignment, + ))) + } + + pub fn allocated_slot(assignment: &TokenAssignment) -> Self { + Self(Box::new(AllocationErrorInner::AllocatedSlot { + tier: assignment.tier, + slot: assignment.time_slot, + })) + } +} + +impl From for AllocationError { + fn from(value: AllocationErrorInner) -> Self { + Self(Box::new(value)) + } +} + +#[derive(Debug, thiserror::Error)] +#[allow(clippy::large_enum_variant)] +enum AllocationErrorInner { + #[error("the following slot for {tier} has already been allocated: {slot}")] + AllocatedSlot { tier: Tier, slot: DateTime }, + #[error("the max age allowed is 730 days")] + IncorrectMaxAge, + #[error("the following assignment is incorrect: {0}")] + InvalidAssignment(TokenAssignment), +} + +#[non_exhaustive] +#[derive(Debug, Serialize, Deserialize)] +pub struct AllocationCriteria { + pub frequency: Tier, + /// Maximum age of the allocated token. + pub max_age: std::time::Duration, +} + +impl AllocationCriteria { + pub fn new(frequency: Tier, max_age: std::time::Duration) -> Result { + if max_age <= std::time::Duration::from_secs(3600 * 24 * 365 * 2) { + Ok(Self { frequency, max_age }) + } else { + Err(AllocationErrorInner::IncorrectMaxAge.into()) + } + } +} + +#[non_exhaustive] +#[derive(Debug, Serialize, Deserialize)] +pub struct TokenAllocationRecord { + /// A list of issued tokens. + /// + /// This is categorized by tiers and then sorted by time slot. + tokens_by_tier: HashMap>, +} + +impl TokenAllocationRecord { + pub fn get_tier(&self, tier: &Tier) -> Option<&[TokenAssignment]> { + self.tokens_by_tier.get(tier).map(|t| t.as_slice()) + } + + pub fn get_mut_tier(&mut self, tier: &Tier) -> Option<&mut Vec> { + self.tokens_by_tier.get_mut(tier) + } + + pub fn new(mut tokens: HashMap>) -> Self { + for (_, assignments) in &mut tokens { + assignments.sort_unstable(); + } + Self { + tokens_by_tier: tokens, + } + } + + pub fn insert(&mut self, tier: Tier, assignments: Vec) { + self.tokens_by_tier.insert(tier, assignments); + } + + pub fn summarize(&self) -> TokenAllocationSummary { + let mut by_tier = HashMap::with_capacity(self.tokens_by_tier.len()); + for (tier, assignments) in &self.tokens_by_tier { + let mut assignments_ts = Vec::with_capacity(assignments.len()); + for a in assignments { + let ts = a.time_slot.timestamp(); + assignments_ts.push(ts); + } + by_tier.insert(*tier, assignments_ts); + } + TokenAllocationSummary(by_tier) + } + + pub fn delta(&self, summary: &TokenAllocationSummary) -> TokenAllocationRecord { + let mut delta = HashMap::new(); + for (tier, summary_assignments) in &summary.0 { + let mut missing = vec![]; + if let Some(assigned) = self.tokens_by_tier.get(tier) { + for a in assigned { + let ts = a.time_slot.timestamp(); + if summary_assignments.binary_search(&ts).is_err() { + missing.push(a.clone()); + } + } + delta.insert(*tier, missing); + } + } + TokenAllocationRecord { + tokens_by_tier: delta, + } + } +} + +impl<'a> IntoIterator for &'a TokenAllocationRecord { + type Item = (&'a Tier, &'a Vec); + + type IntoIter = hashbrown::hash_map::Iter<'a, Tier, Vec>; + + fn into_iter(self) -> Self::IntoIter { + self.tokens_by_tier.iter() + } +} + +impl IntoIterator for TokenAllocationRecord { + type Item = (Tier, Vec); + + type IntoIter = hashbrown::hash_map::IntoIter>; + + fn into_iter(self) -> Self::IntoIter { + self.tokens_by_tier.into_iter() + } +} + +impl TryFrom> for TokenAllocationRecord { + type Error = ContractError; + + fn try_from(state: State<'_>) -> Result { + let this = bincode::deserialize_from(state.as_ref()) + .map_err(|err| ContractError::Deser(format!("{err}")))?; + Ok(this) + } +} + +impl TryFrom for State<'static> { + type Error = ContractError; + + fn try_from(state: TokenAllocationRecord) -> Result { + let serialized = + bincode::serialize(&state).map_err(|err| ContractError::Deser(format!("{err}")))?; + Ok(State::from(serialized)) + } +} + +impl TryFrom for StateDelta<'static> { + type Error = ContractError; + + fn try_from(state: TokenAllocationRecord) -> Result { + let serialized = + bincode::serialize(&state).map_err(|err| ContractError::Deser(format!("{err}")))?; + Ok(StateDelta::from(serialized)) + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct TokenAllocationSummary(HashMap>); + +impl TryFrom> for TokenAllocationSummary { + type Error = ContractError; + + fn try_from(state: StateSummary<'_>) -> Result { + let this = bincode::deserialize_from(state.as_ref()) + .map_err(|err| ContractError::Deser(format!("{err}")))?; + Ok(this) + } +} + +impl TryFrom for StateSummary<'static> { + type Error = ContractError; + + fn try_from(summary: TokenAllocationSummary) -> Result { + let serialized = + bincode::serialize(&summary).map_err(|err| ContractError::Deser(format!("{err}")))?; + Ok(StateSummary::from(serialized)) + } +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[must_use] +pub struct TokenAssignment { + pub tier: Tier, + pub time_slot: DateTime, + /// The assignment, the recipient decides whether this assignment is valid based on this field. + /// This will often be a PublicKey. + pub assignee: Assignment, + /// `(tier, issue_time, assigned_to)` must be signed by `generator_public_key` + pub signature: Signature, +} + +impl TokenAssignment { + const TIER_SIZE: usize = std::mem::size_of::(); + const TS_SIZE: usize = std::mem::size_of::(); + const ASSIGNEE_SIZE: usize = ed25519_dalek::PUBLIC_KEY_LENGTH; + + pub const SIGNED_MSG_SIZE: usize = Self::TIER_SIZE + Self::TS_SIZE + Self::ASSIGNEE_SIZE; + + /// The `(tier, issue_time, assigned_to)` tuple that has to be verified as bytes. + pub fn to_be_signed( + issue_time: &DateTime, + assigned_to: &Assignment, + tier: Tier, + ) -> [u8; Self::SIGNED_MSG_SIZE] { + let mut cursor = Self::TIER_SIZE; + let mut to_be_signed = [0; Self::SIGNED_MSG_SIZE]; + + to_be_signed[..Self::TIER_SIZE].copy_from_slice(&(tier as u8).to_be_bytes()); + let timestamp = issue_time.timestamp(); + to_be_signed[cursor..cursor + Self::TS_SIZE].copy_from_slice(×tamp.to_le_bytes()); + cursor += Self::TS_SIZE; + to_be_signed[cursor..].copy_from_slice(assigned_to.as_bytes()); + + to_be_signed + } + + pub fn next_slot(&self) -> DateTime { + self.time_slot + Duration::from_std(self.tier.tier_duration()).unwrap() + } + + pub fn previous_slot(&self) -> DateTime { + self.time_slot - Duration::from_std(self.tier.tier_duration()).unwrap() + } +} + +#[test] +fn to_be_signed_test() { + let _to_be_signed = TokenAssignment::to_be_signed( + &get_date(2021, 7, 28), + &ed25519_dalek::PublicKey::from_bytes(&[1; ed25519_dalek::PUBLIC_KEY_LENGTH]).unwrap(), + Tier::Day90, + ); + // dbg!(_to_be_signed); +} + +impl PartialEq for TokenAssignment { + fn eq(&self, other: &Self) -> bool { + self.tier == other.tier && self.time_slot == other.time_slot + } +} + +impl Eq for TokenAssignment {} + +impl PartialOrd for TokenAssignment { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.time_slot.cmp(&other.time_slot)) + } +} + +impl Ord for TokenAssignment { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.time_slot.cmp(&other.time_slot) + } +} + +impl TryFrom> for TokenAssignment { + type Error = ContractError; + + fn try_from(state: StateDelta<'_>) -> Result { + let this = bincode::deserialize_from(state.as_ref()) + .map_err(|err| ContractError::Deser(format!("{err}")))?; + Ok(this) + } +} + +impl Display for TokenAssignment { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let assignee = bs58::encode(&self.assignee).into_string(); + write!( + f, + "{{ {tier} @ {slot} for {assignee}}}", + tier = self.tier, + slot = self.time_slot, + ) + } +} diff --git a/modules/antiflood-tokens/locutus.toml b/modules/antiflood-tokens/locutus.toml new file mode 100644 index 000000000..f11e5944f --- /dev/null +++ b/modules/antiflood-tokens/locutus.toml @@ -0,0 +1,3 @@ +[contract] +type = "standard" +lang = "rust" diff --git a/tests/test-component-1/Cargo.lock b/tests/test-component-1/Cargo.lock index 5a7454e1a..725abc66d 100644 --- a/tests/test-component-1/Cargo.lock +++ b/tests/test-component-1/Cargo.lock @@ -102,9 +102,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" dependencies = [ "iana-time-zone", + "js-sys", "num-integer", "num-traits", "serde", + "time 0.1.45", + "wasm-bindgen", "winapi", ] @@ -448,6 +451,7 @@ dependencies = [ "blake2", "bs58", "byteorder", + "chrono", "futures", "locutus-macros", "once_cell", @@ -517,15 +521,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_threads" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" -dependencies = [ - "libc", -] - [[package]] name = "once_cell" version = "1.15.0" @@ -713,7 +708,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros", - "time", + "time 0.3.17", ] [[package]] @@ -836,14 +831,40 @@ dependencies = [ [[package]] name = "time" -version = "0.3.15" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d634a985c4d4238ec39cacaed2e7ae552fbd3c476b552c1deac3021b7d7eaf0c" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" dependencies = [ - "itoa", "libc", - "num_threads", + "wasi", + "winapi", +] + +[[package]] +name = "time" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +dependencies = [ + "itoa", "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", ] [[package]] @@ -938,6 +959,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wasm-bindgen" version = "0.2.83" diff --git a/tests/test-component-1/src/lib.rs b/tests/test-component-1/src/lib.rs index 6a1977c78..76b785065 100644 --- a/tests/test-component-1/src/lib.rs +++ b/tests/test-component-1/src/lib.rs @@ -1,5 +1,3 @@ -use std::sync::Arc; - use locutus_stdlib::prelude::*; use serde::{Deserialize, Serialize}; @@ -19,7 +17,7 @@ impl SecretsContext { impl From for ComponentContext { fn from(val: SecretsContext) -> Self { - ComponentContext(val.serialized()) + ComponentContext::new(val.serialized()) } } @@ -152,9 +150,9 @@ impl ComponentInterface for Component { #[test] fn check_signing() -> Result<(), Box> { - // 1- create inbox message parts + // 1. create inbox message parts let contract = WrappedContract::new( - Arc::new(ContractCode::from(vec![1])), + std::sync::Arc::new(ContractCode::from(vec![1])), Parameters::from(vec![]), ); let app = ContractInstanceId::try_from(contract.key.to_string()).unwrap(); diff --git a/tests/test-contract-1/Cargo.lock b/tests/test-contract-1/Cargo.lock index 6b3f3aa04..7826128e3 100644 --- a/tests/test-contract-1/Cargo.lock +++ b/tests/test-contract-1/Cargo.lock @@ -102,9 +102,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" dependencies = [ "iana-time-zone", + "js-sys", "num-integer", "num-traits", "serde", + "time 0.1.45", + "wasm-bindgen", "winapi", ] @@ -448,6 +451,7 @@ dependencies = [ "blake2", "bs58", "byteorder", + "chrono", "futures", "locutus-macros", "once_cell", @@ -704,7 +708,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros", - "time", + "time 0.3.17", ] [[package]] @@ -822,6 +826,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi", + "winapi", +] + [[package]] name = "time" version = "0.3.17" @@ -941,6 +956,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wasm-bindgen" version = "0.2.83" diff --git a/tests/test-contract-1/Cargo.toml b/tests/test-contract-1/Cargo.toml index 64871a56b..315ce0750 100644 --- a/tests/test-contract-1/Cargo.toml +++ b/tests/test-contract-1/Cargo.toml @@ -3,8 +3,6 @@ name = "test-contract-1" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [workspace] [lib] diff --git a/tests/test-contract-1/README.md b/tests/test-contract-1/README.md new file mode 100644 index 000000000..e4fb5c3eb --- /dev/null +++ b/tests/test-contract-1/README.md @@ -0,0 +1 @@ +This contract is used to test the contract interface. diff --git a/tests/test-contract-1/src/lib.rs b/tests/test-contract-1/src/lib.rs index 7440b851a..d0fd8f024 100644 --- a/tests/test-contract-1/src/lib.rs +++ b/tests/test-contract-1/src/lib.rs @@ -1,5 +1,4 @@ use locutus_stdlib::prelude::*; -// ANCHOR: contractifce struct Contract; diff --git a/tests/test-contract-2/Cargo.lock b/tests/test-contract-2/Cargo.lock new file mode 100644 index 000000000..70a2e25f0 --- /dev/null +++ b/tests/test-contract-2/Cargo.lock @@ -0,0 +1,1114 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +dependencies = [ + "serde", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "blake2" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b12e5fd123190ce1c2e559308a94c9bacad77907d4c6005d9e58fe1a0689e55e" +dependencies = [ + "digest", +] + +[[package]] +name = "block-buffer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bumpalo" +version = "3.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cc" +version = "1.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" + +[[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.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-integer", + "num-traits", + "serde", + "time 0.1.45", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[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 = "cxx" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf07d07d6531bfcdbe9b8b739b104610c6508dcc4d63b410585faf338241daf" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2eb5b96ecdc99f72657332953d4d9c50135af1bac34277801cc3937906ebd39" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac040a39517fd1674e0f32177648334b0f4074625b5588a64519804ba0553b12" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "darling" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "filetime" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e884668cd0c7480504233e951174ddc3b382f7c2666e3b7310b5c4e7b0c37f9" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "windows-sys", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" + +[[package]] +name = "futures-executor" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" + +[[package]] +name = "futures-macro" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + +[[package]] +name = "futures-task" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" + +[[package]] +name = "futures-util" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "iana-time-zone" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown", + "serde", +] + +[[package]] +name = "itoa" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" + +[[package]] +name = "js-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +dependencies = [ + "wasm-bindgen", +] + +[[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.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" + +[[package]] +name = "link-cplusplus" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] + +[[package]] +name = "locutus-macros" +version = "0.0.3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "locutus-stdlib" +version = "0.0.3" +dependencies = [ + "arrayvec", + "bincode", + "blake2", + "bs58", + "byteorder", + "chrono", + "futures", + "locutus-macros", + "once_cell", + "rmp-serde", + "rmpv", + "semver", + "serde", + "serde_bytes", + "serde_json", + "serde_with", + "tar", + "thiserror", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[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.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "paste" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "rmp" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44519172358fd6d58656c86ab8e7fbc9e1490c3e8f14d35ed78ca0dd07403c9f" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "rmp-serde" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5b13be192e0220b8afb7222aa5813cb62cc269ebb5cac346ca6487681d2913e" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + +[[package]] +name = "rmpv" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de8813b3a2f95c5138fe5925bfb8784175d88d6bff059ba8ce090aa891319754" +dependencies = [ + "num-traits", + "rmp", +] + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "scratch" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + +[[package]] +name = "semver" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +dependencies = [ + "serde", +] + +[[package]] +name = "serde" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25bf4a5a814902cd1014dbccfa4d4560fb8432c779471e96e035602519f82eef" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap", + "serde", + "serde_json", + "serde_with_macros", + "time 0.3.17", +] + +[[package]] +name = "serde_with_macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3452b4c0f6c1e357f73fdb87cd1efabaa12acf328c7a528e252893baeb3f4aa" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tar" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "test-contract-2" +version = "0.1.0" +dependencies = [ + "locutus-stdlib", +] + +[[package]] +name = "thiserror" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi", + "winapi", +] + +[[package]] +name = "time" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[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 = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasm-bindgen" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +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.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +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.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + +[[package]] +name = "xattr" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" +dependencies = [ + "libc", +] diff --git a/tests/test-contract-2/Cargo.toml b/tests/test-contract-2/Cargo.toml new file mode 100644 index 000000000..b6b244f68 --- /dev/null +++ b/tests/test-contract-2/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "test-contract-2" +version = "0.1.0" +edition = "2021" + +[workspace] + +[lib] +crate-type = ["cdylib"] + +[dependencies] +locutus-stdlib = { path = "../../crates/locutus-stdlib" } + +[features] +trace = ["locutus-stdlib/trace"] diff --git a/tests/test-contract-2/README.md b/tests/test-contract-2/README.md new file mode 100644 index 000000000..de80e75ab --- /dev/null +++ b/tests/test-contract-2/README.md @@ -0,0 +1 @@ +This contract is used to test the std lib functionality from WASM. diff --git a/tests/test-contract-2/locutus.toml b/tests/test-contract-2/locutus.toml new file mode 100644 index 000000000..b8345f455 --- /dev/null +++ b/tests/test-contract-2/locutus.toml @@ -0,0 +1,2 @@ +[contract] +lang = "rust" diff --git a/tests/test-contract-2/src/lib.rs b/tests/test-contract-2/src/lib.rs new file mode 100644 index 000000000..f5ccca21b --- /dev/null +++ b/tests/test-contract-2/src/lib.rs @@ -0,0 +1,14 @@ +use locutus_stdlib::prelude::*; + +pub fn set_tra() { + use locutus_stdlib::prelude::tracing_subscriber as tra; + let _ = tra::fmt().with_env_filter("info").try_init(); +} + +#[no_mangle] +pub extern "C" fn time_func() { + set_tra(); + tracing::info!("trying to get time"); + let now = locutus_stdlib::time::now(); + tracing::info!(%now, "current time"); +}