From c5bc9ed31e9ef3aebe918e0faad3d240ee4307e3 Mon Sep 17 00:00:00 2001 From: pritsheth Date: Fri, 16 Feb 2024 12:14:17 -0800 Subject: [PATCH 1/6] Add soroban-spec-tools and remove soroban-tests crate --- .github/workflows/rust.yml | 6 - Cargo.lock | 2573 +---------------- Cargo.toml | 18 +- Makefile | 6 +- cmd/crates/soroban-spec-tools/Cargo.toml | 39 + cmd/crates/soroban-spec-tools/README.md | 3 + cmd/crates/soroban-spec-tools/src/contract.rs | 276 ++ cmd/crates/soroban-spec-tools/src/lib.rs | 1469 ++++++++++ cmd/crates/soroban-spec-tools/src/utils.rs | 294 ++ cmd/crates/soroban-test/Cargo.toml | 43 - cmd/crates/soroban-test/README.md | 54 - cmd/crates/soroban-test/src/lib.rs | 229 -- cmd/crates/soroban-test/src/wasm.rs | 61 - .../soroban-test/tests/fixtures/args/world | 1 - .../tests/fixtures/hello/Cargo.lock | 7 - .../tests/fixtures/hello/Cargo.toml | 9 - .../tests/fixtures/hello/src/main.rs | 3 - .../tests/fixtures/test-jsons/get-events.json | 57 - .../test-wasms/custom_type/Cargo.toml | 18 - .../test-wasms/custom_type/src/lib.rs | 187 -- .../test-wasms/hello_world/Cargo.toml | 18 - .../test-wasms/hello_world/src/lib.rs | 86 - .../tests/fixtures/test-wasms/swap/Cargo.toml | 18 - .../tests/fixtures/test-wasms/swap/src/lib.rs | 77 - .../fixtures/test-wasms/swap/src/test.rs | 112 - .../fixtures/test-wasms/token/Cargo.toml | 19 - .../fixtures/test-wasms/token/src/admin.rs | 18 - .../test-wasms/token/src/allowance.rs | 63 - .../fixtures/test-wasms/token/src/balance.rs | 35 - .../fixtures/test-wasms/token/src/contract.rs | 167 -- .../fixtures/test-wasms/token/src/lib.rs | 11 - .../fixtures/test-wasms/token/src/metadata.rs | 22 - .../test-wasms/token/src/storage_types.rs | 31 - .../fixtures/test-wasms/token/src/test.rs | 256 -- .../tests/fixtures/test-wasms/udt/Cargo.toml | 18 - .../tests/fixtures/test-wasms/udt/src/lib.rs | 112 - .../soroban-test/tests/it/arg_parsing.rs | 215 -- cmd/crates/soroban-test/tests/it/config.rs | 223 -- .../soroban-test/tests/it/hello_world.rs | 22 - cmd/crates/soroban-test/tests/it/help.rs | 97 - .../soroban-test/tests/it/integration.rs | 5 - .../tests/it/integration/custom_types.rs | 419 --- .../tests/it/integration/dotenv.rs | 67 - .../tests/it/integration/hello_world.rs | 308 -- .../soroban-test/tests/it/integration/util.rs | 119 - .../soroban-test/tests/it/integration/wrap.rs | 97 - .../it/lab_test_transaction_envelope.txt | 54 - cmd/crates/soroban-test/tests/it/main.rs | 8 - cmd/crates/soroban-test/tests/it/plugin.rs | 77 - cmd/crates/soroban-test/tests/it/util.rs | 72 - cmd/crates/soroban-test/tests/it/version.rs | 12 - cmd/soroban-rpc/internal/test/cli_test.go | 383 --- 52 files changed, 2216 insertions(+), 6378 deletions(-) create mode 100644 cmd/crates/soroban-spec-tools/Cargo.toml create mode 100644 cmd/crates/soroban-spec-tools/README.md create mode 100644 cmd/crates/soroban-spec-tools/src/contract.rs create mode 100644 cmd/crates/soroban-spec-tools/src/lib.rs create mode 100644 cmd/crates/soroban-spec-tools/src/utils.rs delete mode 100644 cmd/crates/soroban-test/Cargo.toml delete mode 100644 cmd/crates/soroban-test/README.md delete mode 100644 cmd/crates/soroban-test/src/lib.rs delete mode 100644 cmd/crates/soroban-test/src/wasm.rs delete mode 100644 cmd/crates/soroban-test/tests/fixtures/args/world delete mode 100644 cmd/crates/soroban-test/tests/fixtures/hello/Cargo.lock delete mode 100644 cmd/crates/soroban-test/tests/fixtures/hello/Cargo.toml delete mode 100644 cmd/crates/soroban-test/tests/fixtures/hello/src/main.rs delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-jsons/get-events.json delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/Cargo.toml delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/src/lib.rs delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/hello_world/Cargo.toml delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/hello_world/src/lib.rs delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/Cargo.toml delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/src/lib.rs delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/src/test.rs delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/token/Cargo.toml delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/admin.rs delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/allowance.rs delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/balance.rs delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/contract.rs delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/lib.rs delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/metadata.rs delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/storage_types.rs delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/test.rs delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/udt/Cargo.toml delete mode 100644 cmd/crates/soroban-test/tests/fixtures/test-wasms/udt/src/lib.rs delete mode 100644 cmd/crates/soroban-test/tests/it/arg_parsing.rs delete mode 100644 cmd/crates/soroban-test/tests/it/config.rs delete mode 100644 cmd/crates/soroban-test/tests/it/hello_world.rs delete mode 100644 cmd/crates/soroban-test/tests/it/help.rs delete mode 100644 cmd/crates/soroban-test/tests/it/integration.rs delete mode 100644 cmd/crates/soroban-test/tests/it/integration/custom_types.rs delete mode 100644 cmd/crates/soroban-test/tests/it/integration/dotenv.rs delete mode 100644 cmd/crates/soroban-test/tests/it/integration/hello_world.rs delete mode 100644 cmd/crates/soroban-test/tests/it/integration/util.rs delete mode 100644 cmd/crates/soroban-test/tests/it/integration/wrap.rs delete mode 100644 cmd/crates/soroban-test/tests/it/lab_test_transaction_envelope.txt delete mode 100644 cmd/crates/soroban-test/tests/it/main.rs delete mode 100644 cmd/crates/soroban-test/tests/it/plugin.rs delete mode 100644 cmd/crates/soroban-test/tests/it/util.rs delete mode 100644 cmd/crates/soroban-test/tests/it/version.rs delete mode 100644 cmd/soroban-rpc/internal/test/cli_test.go diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 0ae08a56..6070106c 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -74,9 +74,3 @@ jobs: run: sudo apt-get update && sudo apt-get -y install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu - run: cargo clippy --all-targets --target ${{ matrix.target }} - run: make build-test - - if: startsWith(matrix.target, 'x86_64') - # specify directories explicitly to avoid building the preflight library (otherwise it will fail with missing symbols) - run: | - for I in cmd/crates/* cmd/crates/soroban-test/tests/fixtures/test-wasms/hello_world ; do - cargo test --target ${{ matrix.target }} --manifest-path $I/Cargo.toml - done diff --git a/Cargo.lock b/Cargo.lock index 6dfd5b15..5502fec1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,15 +17,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "aho-corasick" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" -dependencies = [ - "memchr", -] - [[package]] name = "android-tzdata" version = "0.1.1" @@ -104,42 +95,6 @@ dependencies = [ "derive_arbitrary", ] -[[package]] -name = "arc-swap" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" - -[[package]] -name = "assert_cmd" -version = "2.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00ad3f3a942eee60335ab4342358c161ee296829e0d16ff42fc1d6cb07815467" -dependencies = [ - "anstyle", - "bstr", - "doc-comment", - "predicates 3.1.0", - "predicates-core", - "predicates-tree", - "wait-timeout", -] - -[[package]] -name = "assert_fs" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cd762e110c8ed629b11b6cde59458cc1c71de78ebbcc30099fc8e0403a2a2ec" -dependencies = [ - "anstyle", - "doc-comment", - "globwalk", - "predicates 3.1.0", - "predicates-core", - "predicates-tree", - "tempfile", -] - [[package]] name = "async-trait" version = "0.1.76" @@ -148,7 +103,7 @@ checksum = "531b97fb4cd3dfdce92c35dedbfdc1f0b9d8091c8ca943d6dae340ef5012d514" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn", ] [[package]] @@ -223,15 +178,6 @@ version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" -[[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.4" @@ -241,37 +187,11 @@ dependencies = [ "generic-array", ] -[[package]] -name = "bstr" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" -dependencies = [ - "memchr", - "regex-automata 0.4.5", - "serde", -] - -[[package]] -name = "btoi" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd6407f73a9b8b6162d8a2ef999fe6afd7cc15902ebf42c5cd296addf17e0ad" -dependencies = [ - "num-traits", -] - [[package]] name = "bumpalo" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" - -[[package]] -name = "byteorder" -version = "1.5.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "d32a994c2b3ca201d9b263612a374263f05e7adde37c4707f693dcd375076d1f" [[package]] name = "bytes" @@ -288,39 +208,7 @@ dependencies = [ "num-bigint", "proc-macro2", "quote", - "syn 2.0.39", -] - -[[package]] -name = "camino" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo-platform" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo_metadata" -version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" -dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", - "thiserror", + "syn", ] [[package]] @@ -340,24 +228,22 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb" +checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" dependencies = [ "android-tzdata", "iana-time-zone", - "js-sys", "num-traits", "serde", - "wasm-bindgen", "windows-targets 0.52.0", ] [[package]] name = "clap" -version = "4.5.0" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" +checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" dependencies = [ "clap_builder", "clap_derive", @@ -365,9 +251,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.0" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" +checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" dependencies = [ "anstream", "anstyle", @@ -375,25 +261,16 @@ dependencies = [ "strsim 0.11.0", ] -[[package]] -name = "clap_complete" -version = "4.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "299353be8209bd133b049bf1c63582d184a8b39fd9c04f15fe65f50f88bdfe6c" -dependencies = [ - "clap", -] - [[package]] name = "clap_derive" version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", - "syn 2.0.39", + "syn", ] [[package]] @@ -402,12 +279,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" -[[package]] -name = "clru" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8191fa7302e03607ff0e237d4246cc043ff5b3cb9409d995172ba3bea16b807" - [[package]] name = "colorchoice" version = "1.0.0" @@ -445,17 +316,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crate-git-revision" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f998aef136a4e7833b0e4f0fc0939a59c40140b28e0ffbf524ad84fb2cc568c8" -dependencies = [ - "serde", - "serde_derive", - "serde_json", -] - [[package]] name = "crate-git-revision" version = "0.0.6" @@ -467,49 +327,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" - [[package]] name = "crypto-bigint" version = "0.5.5" @@ -517,7 +334,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", - "rand_core 0.6.4", + "rand_core", "subtle", "zeroize", ] @@ -532,60 +349,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "crypto-mac" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bcd97a54c7ca5ce2f6eb16f6bede5b0ab5f0055fedc17d2f0b4466e21671ca" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "csv" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" -dependencies = [ - "csv-core", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" -dependencies = [ - "memchr", -] - -[[package]] -name = "ctor" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d2b3721e861707777e3195b0158f950ae6dc4a27e4d02ff9f67e3eb3de199e" -dependencies = [ - "quote", - "syn 2.0.39", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - [[package]] name = "curve25519-dalek" version = "4.1.1" @@ -595,7 +358,7 @@ dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", - "digest 0.10.7", + "digest", "fiat-crypto", "platforms", "rustc_version", @@ -611,14 +374,14 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn", ] [[package]] name = "darling" -version = "0.20.5" +version = "0.20.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc5d6b04b3fd0ba9926f945895de7d806260a2d7431ba82e7edaecb043c4c6b8" +checksum = "c376d08ea6aa96aafe61237c7200d1241cb177b7d3a542d791f2d118e9cbb955" dependencies = [ "darling_core", "darling_macro", @@ -626,27 +389,27 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.5" +version = "0.20.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e48a959bcd5c761246f5d090ebc2fbf7b9cd527a492b07a67510c108f1e7e3" +checksum = "33043dcd19068b8192064c704b3f83eb464f91f1ff527b44a4e2b08d9cdb8855" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.39", + "syn", ] [[package]] name = "darling_macro" -version = "0.20.5" +version = "0.20.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1545d67a2149e1d93b7e5c7752dce5a7426eb5d1357ddcfd89336b94444f77" +checksum = "c5a91391accf613803c2a9bf9abccdbaa07c54b4244a5b64883f9c3c137c86be" dependencies = [ "darling_core", "quote", - "syn 2.0.39", + "syn", ] [[package]] @@ -677,22 +440,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", -] - -[[package]] -name = "difflib" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", + "syn", ] [[package]] @@ -701,56 +449,18 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.4", + "block-buffer", "const-oid", "crypto-common", "subtle", ] -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "doc-comment" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" - -[[package]] -name = "dotenvy" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" - [[package]] name = "downcast-rs" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" -[[package]] -name = "dunce" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" - [[package]] name = "ecdsa" version = "0.16.9" @@ -758,22 +468,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", - "digest 0.10.7", + "digest", "elliptic-curve", "rfc6979", - "signature 2.2.0", + "signature", "spki", ] -[[package]] -name = "ed25519" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" -dependencies = [ - "signature 1.6.4", -] - [[package]] name = "ed25519" version = "2.2.3" @@ -781,19 +482,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8", - "signature 2.2.0", -] - -[[package]] -name = "ed25519-dalek" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" -dependencies = [ - "curve25519-dalek 3.2.0", - "ed25519 1.5.3", - "sha2 0.9.9", - "zeroize", + "signature", ] [[package]] @@ -802,19 +491,19 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" dependencies = [ - "curve25519-dalek 4.1.1", - "ed25519 2.2.3", - "rand_core 0.6.4", + "curve25519-dalek", + "ed25519", + "rand_core", "serde", - "sha2 0.10.8", + "sha2", "zeroize", ] [[package]] name = "either" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "elliptic-curve" @@ -824,26 +513,17 @@ checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", - "digest 0.10.7", + "digest", "ff", "generic-array", "group", "pkcs8", - "rand_core 0.6.4", + "rand_core", "sec1", "subtle", "zeroize", ] -[[package]] -name = "encoding_rs" -version = "0.8.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" -dependencies = [ - "cfg-if", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -872,28 +552,13 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" -[[package]] -name = "faster-hex" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" -dependencies = [ - "serde", -] - -[[package]] -name = "fastrand" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - [[package]] name = "ff" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "rand_core 0.6.4", + "rand_core", "subtle", ] @@ -903,58 +568,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" -[[package]] -name = "filetime" -version = "0.2.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "windows-sys 0.52.0", -] - -[[package]] -name = "flate2" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "float-cmp" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" -dependencies = [ - "num-traits", -] - [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.1" @@ -964,12 +583,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - [[package]] name = "futures-channel" version = "0.3.30" @@ -986,16 +599,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] -name = "futures-io" +name = "futures-sink" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" @@ -1010,13 +617,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", - "futures-io", "futures-sink", "futures-task", - "memchr", "pin-project-lite", "pin-utils", - "slab", ] [[package]] @@ -1049,790 +653,6 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" -[[package]] -name = "gix" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31887c304d9a935f3e5494fb5d6a0106c34e965168ec0db9b457424eedd0c741" -dependencies = [ - "gix-actor", - "gix-attributes", - "gix-command", - "gix-commitgraph", - "gix-config", - "gix-credentials", - "gix-date", - "gix-diff", - "gix-discover", - "gix-features", - "gix-filter", - "gix-fs", - "gix-glob", - "gix-hash", - "gix-hashtable", - "gix-ignore", - "gix-index", - "gix-lock", - "gix-macros", - "gix-negotiate", - "gix-object", - "gix-odb", - "gix-pack", - "gix-path", - "gix-pathspec", - "gix-prompt", - "gix-protocol", - "gix-ref", - "gix-refspec", - "gix-revision", - "gix-revwalk", - "gix-sec", - "gix-submodule", - "gix-tempfile", - "gix-trace", - "gix-transport", - "gix-traverse", - "gix-url", - "gix-utils", - "gix-validate", - "gix-worktree", - "gix-worktree-state", - "once_cell", - "parking_lot", - "reqwest", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-actor" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a7bb9fad6125c81372987c06469601d37e1a2d421511adb69971b9083517a8a" -dependencies = [ - "bstr", - "btoi", - "gix-date", - "itoa", - "thiserror", - "winnow", -] - -[[package]] -name = "gix-attributes" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "214ee3792e504ee1ce206b36dcafa4f328ca313d1e2ac0b41433d68ef4e14260" -dependencies = [ - "bstr", - "gix-glob", - "gix-path", - "gix-quote", - "gix-trace", - "kstring", - "smallvec", - "thiserror", - "unicode-bom", -] - -[[package]] -name = "gix-bitmap" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b6cd0f246180034ddafac9b00a112f19178135b21eb031b3f79355891f7325" -dependencies = [ - "thiserror", -] - -[[package]] -name = "gix-chunk" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "003ec6deacf68076a0c157271a127e0bb2c031c1a41f7168cbe5d248d9b85c78" -dependencies = [ - "thiserror", -] - -[[package]] -name = "gix-command" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82b5e9494e61983e61049bbd15fe0fa6b70672dd236362bdb5b2b50fc428f10" -dependencies = [ - "bstr", - "gix-path", - "gix-trace", - "shell-words", -] - -[[package]] -name = "gix-commitgraph" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82dbd7fb959862e3df2583331f0ad032ac93533e8a52f1b0694bc517f5d292bc" -dependencies = [ - "bstr", - "gix-chunk", - "gix-features", - "gix-hash", - "memmap2", - "thiserror", -] - -[[package]] -name = "gix-config" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e62bf2073b6ce3921ffa6d8326f645f30eec5fc4a8e8a4bc0fcb721a2f3f69dc" -dependencies = [ - "bstr", - "gix-config-value", - "gix-features", - "gix-glob", - "gix-path", - "gix-ref", - "gix-sec", - "memchr", - "once_cell", - "smallvec", - "thiserror", - "unicode-bom", - "winnow", -] - -[[package]] -name = "gix-config-value" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e7bfb37a46ed0b8468db37a6d8a0a61d56bdbe4603ae492cb322e5f3958" -dependencies = [ - "bitflags 2.4.2", - "bstr", - "gix-path", - "libc", - "thiserror", -] - -[[package]] -name = "gix-credentials" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206ede3fe433abba3c8b0174179d5bbac65ae3f0d9187e2ea96c0494db6a139f" -dependencies = [ - "bstr", - "gix-command", - "gix-config-value", - "gix-path", - "gix-prompt", - "gix-sec", - "gix-trace", - "gix-url", - "thiserror", -] - -[[package]] -name = "gix-date" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb7f3dfb72bebe3449b5e642be64e3c6ccbe9821c8b8f19f487cf5bfbbf4067e" -dependencies = [ - "bstr", - "itoa", - "thiserror", - "time", -] - -[[package]] -name = "gix-diff" -version = "0.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbdcb5e49c4b9729dd1c361040ae5c3cd7c497b2260b18c954f62db3a63e98cf" -dependencies = [ - "bstr", - "gix-hash", - "gix-object", - "thiserror", -] - -[[package]] -name = "gix-discover" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4669218f3ec0cbbf8f16857b32200890f8ca585f36f5817242e4115fe4551af" -dependencies = [ - "bstr", - "dunce", - "gix-fs", - "gix-hash", - "gix-path", - "gix-ref", - "gix-sec", - "thiserror", -] - -[[package]] -name = "gix-features" -version = "0.38.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "184f7f7d4e45db0e2a362aeaf12c06c5e84817d0ef91d08e8e90170dad9f0b07" -dependencies = [ - "bytes", - "crc32fast", - "flate2", - "gix-hash", - "gix-trace", - "gix-utils", - "libc", - "once_cell", - "prodash", - "sha1_smol", - "thiserror", - "walkdir", -] - -[[package]] -name = "gix-filter" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9240862840fb740d209422937195e129e4ed3da49af212383260134bea8f6c1a" -dependencies = [ - "bstr", - "encoding_rs", - "gix-attributes", - "gix-command", - "gix-hash", - "gix-object", - "gix-packetline-blocking", - "gix-path", - "gix-quote", - "gix-trace", - "gix-utils", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-fs" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4436e883d5769f9fb18677b8712b49228357815f9e4104174a6fc2d8461a437b" -dependencies = [ - "gix-features", - "gix-utils", -] - -[[package]] -name = "gix-glob" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4965a1d06d0ab84a29d4a67697a97352ab14ae1da821084e5afb1fd6d8191ca0" -dependencies = [ - "bitflags 2.4.2", - "bstr", - "gix-features", - "gix-path", -] - -[[package]] -name = "gix-hash" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0ed89cdc1dce26685c80271c4287077901de3c3dd90234d5fa47c22b2268653" -dependencies = [ - "faster-hex", - "thiserror", -] - -[[package]] -name = "gix-hashtable" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebe47d8c0887f82355e2e9e16b6cecaa4d5e5346a7a474ca78ff94de1db35a5b" -dependencies = [ - "gix-hash", - "hashbrown 0.14.3", - "parking_lot", -] - -[[package]] -name = "gix-ignore" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f7069aaca4a05784c4cb44e392f0eaf627c6e57e05d3100c0e2386a37a682f0" -dependencies = [ - "bstr", - "gix-glob", - "gix-path", - "gix-trace", - "unicode-bom", -] - -[[package]] -name = "gix-index" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7152181ba8f0a3addc5075dd612cea31fc3e252b29c8be8c45f4892bf87426" -dependencies = [ - "bitflags 2.4.2", - "bstr", - "btoi", - "filetime", - "gix-bitmap", - "gix-features", - "gix-fs", - "gix-hash", - "gix-lock", - "gix-object", - "gix-traverse", - "itoa", - "libc", - "memmap2", - "rustix", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-lock" -version = "13.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "886490a07b1d6433aa91262a99d430a91cc8b9a1f758ac1282e132f1098a9342" -dependencies = [ - "gix-tempfile", - "gix-utils", - "thiserror", -] - -[[package]] -name = "gix-macros" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75e7ab728059f595f6ddc1ad8771b8d6a231971ae493d9d5948ecad366ee8bb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.39", -] - -[[package]] -name = "gix-negotiate" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a163adb84149e522e991cbe27250a6e01de56f98cd05b174614ce3f8a4e8b140" -dependencies = [ - "bitflags 2.4.2", - "gix-commitgraph", - "gix-date", - "gix-hash", - "gix-object", - "gix-revwalk", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-object" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693ce9d30741506cb082ef2d8b797415b48e032cce0ab23eff894c19a7e4777b" -dependencies = [ - "bstr", - "btoi", - "gix-actor", - "gix-date", - "gix-features", - "gix-hash", - "gix-validate", - "itoa", - "smallvec", - "thiserror", - "winnow", -] - -[[package]] -name = "gix-odb" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ba2fa9e81f2461b78b4d81a807867667326c84cdab48e0aed7b73a593aa1be4" -dependencies = [ - "arc-swap", - "gix-date", - "gix-features", - "gix-fs", - "gix-hash", - "gix-object", - "gix-pack", - "gix-path", - "gix-quote", - "parking_lot", - "tempfile", - "thiserror", -] - -[[package]] -name = "gix-pack" -version = "0.47.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da5f3e78c96b76c4e6fe5e8e06b76221e4a0ee9a255aa935ed1fdf68988dfd8" -dependencies = [ - "clru", - "gix-chunk", - "gix-features", - "gix-hash", - "gix-hashtable", - "gix-object", - "gix-path", - "gix-tempfile", - "memmap2", - "parking_lot", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-packetline" -version = "0.17.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ff45eef7747bde4986429a3e813478d50c2688b8f239e57bd3aa81065b285f" -dependencies = [ - "bstr", - "faster-hex", - "gix-trace", - "thiserror", -] - -[[package]] -name = "gix-packetline-blocking" -version = "0.17.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8ef6dd3ea50e26f3bf572e90c034d033c804d340cd1eb386392f184a9ba2f7" -dependencies = [ - "bstr", - "faster-hex", - "gix-trace", - "thiserror", -] - -[[package]] -name = "gix-path" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97e9ad649bf5e109562d6acba657ca428661ec08e77eaf3a755d8fa55485be9c" -dependencies = [ - "bstr", - "gix-trace", - "home", - "once_cell", - "thiserror", -] - -[[package]] -name = "gix-pathspec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cbd49750edb26b0a691e5246fc635fa554d344da825cd20fa9ee0da9c1b761f" -dependencies = [ - "bitflags 2.4.2", - "bstr", - "gix-attributes", - "gix-config-value", - "gix-glob", - "gix-path", - "thiserror", -] - -[[package]] -name = "gix-prompt" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02bd89d058258e53e0fd6c57f13ee16c5673a83066a68e11f88626fc8cfda5f6" -dependencies = [ - "gix-command", - "gix-config-value", - "parking_lot", - "rustix", - "thiserror", -] - -[[package]] -name = "gix-protocol" -version = "0.44.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84af465436787ff423a1b4d5bd0c1979200e7165ed04324fa03ba2235485eebc" -dependencies = [ - "bstr", - "btoi", - "gix-credentials", - "gix-date", - "gix-features", - "gix-hash", - "gix-transport", - "maybe-async", - "thiserror", - "winnow", -] - -[[package]] -name = "gix-quote" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7dc10303d73a960d10fb82f81188b036ac3e6b11b5795b20b1a60b51d1321f" -dependencies = [ - "bstr", - "btoi", - "thiserror", -] - -[[package]] -name = "gix-ref" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5818958994ad7879fa566f5441ebcc48f0926aa027b28948e6fbf6578894dc31" -dependencies = [ - "gix-actor", - "gix-date", - "gix-features", - "gix-fs", - "gix-hash", - "gix-lock", - "gix-object", - "gix-path", - "gix-tempfile", - "gix-utils", - "gix-validate", - "memmap2", - "thiserror", - "winnow", -] - -[[package]] -name = "gix-refspec" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613aa4d93034c5791d13bdc635e530f4ddab1412ddfb4a8215f76213177b61c7" -dependencies = [ - "bstr", - "gix-hash", - "gix-revision", - "gix-validate", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-revision" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "288f6549d7666db74dc3f169a9a333694fc28ecd2f5aa7b2c979c89eb556751a" -dependencies = [ - "bstr", - "gix-date", - "gix-hash", - "gix-hashtable", - "gix-object", - "gix-revwalk", - "gix-trace", - "thiserror", -] - -[[package]] -name = "gix-revwalk" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9b4d91dfc5c14fee61a28c65113ded720403b65a0f46169c0460f731a5d03c" -dependencies = [ - "gix-commitgraph", - "gix-date", - "gix-hash", - "gix-hashtable", - "gix-object", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-sec" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8d9bf462feaf05f2121cba7399dbc6c34d88a9cad58fc1e95027791d6a3c6d2" -dependencies = [ - "bitflags 2.4.2", - "gix-path", - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "gix-submodule" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73182f6c1f5ed1ed94ba16581ac62593d5e29cd1c028b2af618f836283b8f8d4" -dependencies = [ - "bstr", - "gix-config", - "gix-path", - "gix-pathspec", - "gix-refspec", - "gix-url", - "thiserror", -] - -[[package]] -name = "gix-tempfile" -version = "13.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439f4da9657aec7434cde3c2510dcdb0a35f2031233ff67ae986269c788966d7" -dependencies = [ - "gix-fs", - "libc", - "once_cell", - "parking_lot", - "tempfile", -] - -[[package]] -name = "gix-trace" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b202d766a7fefc596e2cc6a89cda8ad8ad733aed82da635ac120691112a9b1" - -[[package]] -name = "gix-transport" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58aba2869cc38937bc834b068c93e09e2ab1119bac626f0464d100c1438b799a" -dependencies = [ - "base64 0.21.7", - "bstr", - "gix-command", - "gix-credentials", - "gix-features", - "gix-packetline", - "gix-quote", - "gix-sec", - "gix-url", - "reqwest", - "thiserror", -] - -[[package]] -name = "gix-traverse" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfc30c5b5e4e838683b59e1b0574ce6bc1c35916df9709aaab32bb7751daf08b" -dependencies = [ - "gix-commitgraph", - "gix-date", - "gix-hash", - "gix-hashtable", - "gix-object", - "gix-revwalk", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-url" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f1981ecc700f4fd73ae62b9ca2da7c8816c8fd267f0185e3f8c21e967984ac" -dependencies = [ - "bstr", - "gix-features", - "gix-path", - "home", - "thiserror", - "url", -] - -[[package]] -name = "gix-utils" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e839f3d0798b296411263da6bee780a176ef8008a5dfc31287f7eda9266ab8" -dependencies = [ - "fastrand", - "unicode-normalization", -] - -[[package]] -name = "gix-validate" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac7cc36f496bd5d96cdca0f9289bb684480725d40db60f48194aa7723b883854" -dependencies = [ - "bstr", - "thiserror", -] - -[[package]] -name = "gix-worktree" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca36bb3dc54038c66507dc75c4d8edbee2d6d5cc45227b4eb508ad13dd60a006" -dependencies = [ - "bstr", - "gix-attributes", - "gix-features", - "gix-fs", - "gix-glob", - "gix-hash", - "gix-ignore", - "gix-index", - "gix-object", - "gix-path", -] - -[[package]] -name = "gix-worktree-state" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae178614b70bdb0c7f6f21b8c9fb711ab78bd7e8e1866f565fcf28876747f1d" -dependencies = [ - "bstr", - "gix-features", - "gix-filter", - "gix-fs", - "gix-glob", - "gix-hash", - "gix-index", - "gix-object", - "gix-path", - "gix-worktree", - "io-close", - "thiserror", -] - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "globset" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata 0.4.5", - "regex-syntax 0.8.2", -] - -[[package]] -name = "globwalk" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" -dependencies = [ - "bitflags 2.4.2", - "ignore", - "walkdir", -] - [[package]] name = "group" version = "0.13.0" @@ -1840,7 +660,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", - "rand_core 0.6.4", + "rand_core", "subtle", ] @@ -1856,7 +676,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.11", - "indexmap 2.2.2", + "indexmap 2.2.3", "slab", "tokio", "tokio-util", @@ -1875,27 +695,12 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -[[package]] -name = "hermit-abi" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3" - [[package]] name = "hex" version = "0.4.3" @@ -1911,23 +716,13 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" -[[package]] -name = "hmac" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deae6d9dbb35ec2c502d62b8f7b1c000a0822c3b0794ba36b3149c0a1c840dff" -dependencies = [ - "crypto-mac", - "digest 0.9.0", -] - [[package]] name = "hmac" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.7", + "digest", ] [[package]] @@ -2024,19 +819,6 @@ dependencies = [ "tokio-rustls", ] -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - [[package]] name = "iana-time-zone" version = "0.1.60" @@ -2064,52 +846,16 @@ dependencies = [ name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "ignore" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" -dependencies = [ - "crossbeam-deque", - "globset", - "log", - "memchr", - "regex-automata 0.4.5", - "same-file", - "walkdir", - "winapi-util", -] - -[[package]] -name = "include_dir" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" -dependencies = [ - "glob", - "include_dir_macros", -] +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "include_dir_macros" -version = "0.7.3" +name = "idna" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ - "proc-macro2", - "quote", + "unicode-bidi", + "unicode-normalization", ] [[package]] @@ -2125,9 +871,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -2140,22 +886,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" -[[package]] -name = "io-close" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cadcf447f06744f8ce713d2d6239bb5bde2c357a452397a9ed90c625da390bc" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "ipnet" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" - [[package]] name = "itertools" version = "0.10.5" @@ -2252,8 +982,8 @@ dependencies = [ "ecdsa", "elliptic-curve", "once_cell", - "sha2 0.10.8", - "signature 2.2.0", + "sha2", + "signature", ] [[package]] @@ -2265,21 +995,6 @@ dependencies = [ "cpufeatures", ] -[[package]] -name = "kstring" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747" -dependencies = [ - "static_assertions", -] - -[[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.153" @@ -2292,80 +1007,24 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" -[[package]] -name = "libredox" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" -dependencies = [ - "bitflags 2.4.2", - "libc", - "redox_syscall", -] - [[package]] name = "linux-raw-sys" version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" -[[package]] -name = "lock_api" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "log" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "maybe-async" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc95a651c82daf7004c824405aa1019723644950d488571bd718e3ed84646ed" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.39", -] - [[package]] name = "memchr" version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" -[[package]] -name = "memmap2" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" -dependencies = [ - "libc", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - [[package]] name = "miniz_oxide" version = "0.7.2" @@ -2386,40 +1045,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "normalize-line-endings" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" - -[[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-bigint" version = "0.4.4" @@ -2445,7 +1070,7 @@ checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn", ] [[package]] @@ -2467,25 +1092,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "num_threads" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" -dependencies = [ - "libc", -] - [[package]] name = "object" version = "0.32.2" @@ -2501,116 +1107,18 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "openssl" -version = "0.10.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" -dependencies = [ - "bitflags 2.4.2", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.39", -] - [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-src" -version = "300.2.2+3.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bbfad0063610ac26ee79f7484739e2b07555a75c42453b89263830b5c8103bc" -dependencies = [ - "cc", -] - -[[package]] -name = "openssl-sys" -version = "0.9.99" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" -dependencies = [ - "cc", - "libc", - "openssl-src", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.48.5", -] - [[package]] name = "paste" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" -[[package]] -name = "pathdiff" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" - -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest 0.10.7", -] - [[package]] name = "percent-encoding" version = "2.3.1" @@ -2634,7 +1142,7 @@ checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn", ] [[package]] @@ -2659,12 +1167,6 @@ dependencies = [ "spki", ] -[[package]] -name = "pkg-config" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" - [[package]] name = "platforms" version = "3.3.0" @@ -2683,231 +1185,73 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "predicates" -version = "2.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" -dependencies = [ - "difflib", - "float-cmp", - "itertools 0.10.5", - "normalize-line-endings", - "predicates-core", - "regex", -] - -[[package]] -name = "predicates" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" -dependencies = [ - "anstyle", - "difflib", - "predicates-core", -] - -[[package]] -name = "predicates-core" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" - -[[package]] -name = "predicates-tree" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" -dependencies = [ - "predicates-core", - "termtree", -] - [[package]] name = "preflight" version = "20.3.1" dependencies = [ "base64 0.21.7", "libc", - "sha2 0.10.8", + "sha2", "soroban-env-host", - "soroban-simulation", -] - -[[package]] -name = "prettyplease" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" -dependencies = [ - "proc-macro2", - "syn 2.0.39", -] - -[[package]] -name = "proc-macro2" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prodash" -version = "28.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744a264d26b88a6a7e37cbad97953fa233b94d585236310bcbc88474b4092d79" - -[[package]] -name = "quote" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", + "soroban-simulation", ] [[package]] -name = "redox_users" -version = "0.4.4" +name = "prettyplease" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ - "getrandom", - "libredox", - "thiserror", + "proc-macro2", + "syn", ] [[package]] -name = "regex" -version = "1.10.3" +name = "proc-macro2" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.4.5", - "regex-syntax 0.8.2", + "unicode-ident", ] [[package]] -name = "regex-automata" -version = "0.1.10" +name = "quote" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ - "regex-syntax 0.6.29", + "proc-macro2", ] [[package]] -name = "regex-automata" -version = "0.4.5" +name = "rand" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.8.2", + "libc", + "rand_chacha", + "rand_core", ] [[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.2" +name = "rand_chacha" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] [[package]] -name = "reqwest" -version = "0.11.24" +name = "rand_core" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "base64 0.21.7", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http 0.2.11", - "http-body", - "hyper", - "hyper-rustls", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "system-configuration", - "tokio", - "tokio-rustls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots", - "winreg", + "getrandom", ] [[package]] @@ -2916,7 +1260,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "hmac 0.12.1", + "hmac", "subtle", ] @@ -2934,39 +1278,12 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "rpassword" -version = "7.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f" -dependencies = [ - "libc", - "rtoolbox", - "windows-sys 0.48.0", -] - -[[package]] -name = "rtoolbox" -version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "rustc-demangle" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc_version" version = "0.4.0" @@ -3038,15 +1355,6 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - [[package]] name = "schannel" version = "0.1.23" @@ -3056,12 +1364,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - [[package]] name = "sct" version = "0.7.1" @@ -3111,24 +1413,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" -dependencies = [ - "serde", -] - -[[package]] -name = "sep5" -version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afe34ccbd1fb6fa0b2fc7cccb037bd3d3f1e484c3befe1b713d7611884f336a" -dependencies = [ - "slip10", - "stellar-strkey 0.0.7", - "thiserror", - "tiny-bip39", -] +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" [[package]] name = "serde" @@ -3158,7 +1445,7 @@ checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn", ] [[package]] @@ -3172,30 +1459,19 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - [[package]] name = "serde_with" -version = "3.6.0" +version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b0ed1662c5a68664f45b76d18deb0e234aff37207086803165c961eb695e981" +checksum = "15d167997bd841ec232f5b2b8e0e26606df2e7caa4c31b95ea9ca52b200bd270" dependencies = [ "base64 0.21.7", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.2.2", + "indexmap 2.2.3", "serde", + "serde_derive", "serde_json", "serde_with_macros", "time", @@ -3203,33 +1479,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.6.0" +version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568577ff0ef47b879f736cd66740e022f3672788cdf002a05a4e609ea5a6fb15" +checksum = "865f9743393e638991566a8b7a479043c2c8da94a33e0a31f18214c9cae0a64d" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.39", -] - -[[package]] -name = "sha1_smol" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" - -[[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", + "syn", ] [[package]] @@ -3240,7 +1497,7 @@ checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest", ] [[package]] @@ -3249,54 +1506,18 @@ version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest 0.10.7", + "digest", "keccak", ] -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shell-words" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" - [[package]] name = "signature" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", + "digest", + "rand_core", ] [[package]] @@ -3308,17 +1529,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "slip10" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28724a6e6f70b0cb115c580891483da6f3aa99e6a353598303a57f89d23aa6bc" -dependencies = [ - "ed25519-dalek 1.0.1", - "hmac 0.9.0", - "sha2 0.9.9", -] - [[package]] name = "smallvec" version = "1.13.1" @@ -3344,73 +1554,7 @@ dependencies = [ "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.39", -] - -[[package]] -name = "soroban-cli" -version = "20.3.0" -source = "git+https://github.com/stellar/soroban-tools?rev=a1e51d263df80682a3dab2b00738700c7326f872#a1e51d263df80682a3dab2b00738700c7326f872" -dependencies = [ - "base64 0.21.7", - "cargo_metadata", - "chrono", - "clap", - "clap_complete", - "crate-git-revision 0.0.4", - "csv", - "dirs", - "dotenvy", - "ed25519-dalek 2.0.0", - "ethnum", - "gix", - "heck 0.4.1", - "hex", - "http 0.2.11", - "hyper", - "hyper-tls", - "itertools 0.10.5", - "jsonrpsee-core", - "jsonrpsee-http-client", - "num-bigint", - "openssl", - "pathdiff", - "rand", - "regex", - "rpassword", - "sep5", - "serde", - "serde-aux", - "serde_json", - "sha2 0.10.8", - "shlex", - "soroban-env-host", - "soroban-ledger-snapshot", - "soroban-rpc 20.3.0", - "soroban-sdk", - "soroban-spec", - "soroban-spec-json", - "soroban-spec-rust", - "soroban-spec-tools", - "soroban-spec-typescript", - "stellar-strkey 0.0.7", - "stellar-xdr", - "strsim 0.10.0", - "strum", - "strum_macros", - "tempfile", - "termcolor", - "termcolor_output", - "thiserror", - "tokio", - "toml", - "toml_edit", - "tracing", - "tracing-appender", - "tracing-subscriber", - "ureq", - "wasmparser 0.90.0", - "which", + "syn", ] [[package]] @@ -3420,7 +1564,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d609330abbcc2d7fe185304de0c10ef1a95e64eb8effb6ee4faeea97668e0a" dependencies = [ "arbitrary", - "crate-git-revision 0.0.6", + "crate-git-revision", "ethnum", "num-derive", "num-traits", @@ -3448,18 +1592,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd99f4e075f62e0faec118c568fbc70373793fb921148115d5f3f2563945c02d" dependencies = [ "backtrace", - "curve25519-dalek 4.1.1", - "ed25519-dalek 2.0.0", + "curve25519-dalek", + "ed25519-dalek", "getrandom", "hex-literal", - "hmac 0.12.1", + "hmac", "k256", "num-derive", "num-integer", "num-traits", "rand", "rand_chacha", - "sha2 0.10.8", + "sha2", "sha3", "soroban-builtin-sdk-macros", "soroban-env-common", @@ -3480,13 +1624,9 @@ dependencies = [ "serde", "serde_json", "stellar-xdr", - "syn 2.0.39", + "syn", ] -[[package]] -name = "soroban-hello" -version = "20.3.1" - [[package]] name = "soroban-ledger-snapshot" version = "20.3.1" @@ -3501,45 +1641,13 @@ dependencies = [ "thiserror", ] -[[package]] -name = "soroban-rpc" -version = "20.3.0" -source = "git+https://github.com/stellar/soroban-tools?rev=a1e51d263df80682a3dab2b00738700c7326f872#a1e51d263df80682a3dab2b00738700c7326f872" -dependencies = [ - "base64 0.21.7", - "clap", - "ed25519-dalek 2.0.0", - "ethnum", - "hex", - "http 1.0.0", - "itertools 0.10.5", - "jsonrpsee-core", - "jsonrpsee-http-client", - "serde", - "serde-aux", - "serde_json", - "sha2 0.10.8", - "soroban-env-host", - "soroban-sdk", - "soroban-spec", - "soroban-spec-tools", - "stellar-strkey 0.0.7", - "stellar-xdr", - "termcolor", - "termcolor_output", - "thiserror", - "tokio", - "tracing", - "wasmparser 0.90.0", -] - [[package]] name = "soroban-rpc" version = "20.3.1" dependencies = [ "base64 0.21.7", "clap", - "ed25519-dalek 2.0.0", + "ed25519-dalek", "ethnum", "hex", "http 1.0.0", @@ -3549,7 +1657,7 @@ dependencies = [ "serde", "serde-aux", "serde_json", - "sha2 0.10.8", + "sha2", "soroban-env-host", "soroban-sdk", "soroban-spec", @@ -3571,10 +1679,7 @@ version = "20.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "842c20c8503b137f8a8a5981009eb1f5841b96516f1485d7e1bf9c02afb227d1" dependencies = [ - "arbitrary", "bytes-lit", - "ctor", - "ed25519-dalek 2.0.0", "rand", "serde", "serde_json", @@ -3591,18 +1696,18 @@ version = "20.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0afc8337fadde3047fb774fa2abc3877a4a260b8e531868b65d5a1debc60b3b9" dependencies = [ - "crate-git-revision 0.0.6", + "crate-git-revision", "darling", "itertools 0.11.0", "proc-macro2", "quote", "rustc_version", - "sha2 0.10.8", + "sha2", "soroban-env-common", "soroban-spec", "soroban-spec-rust", "stellar-xdr", - "syn 2.0.39", + "syn", ] [[package]] @@ -3630,20 +1735,6 @@ dependencies = [ "wasmparser 0.88.0", ] -[[package]] -name = "soroban-spec-json" -version = "20.3.0" -source = "git+https://github.com/stellar/soroban-tools?rev=a1e51d263df80682a3dab2b00738700c7326f872#a1e51d263df80682a3dab2b00738700c7326f872" -dependencies = [ - "serde", - "serde_derive", - "serde_json", - "sha2 0.9.9", - "soroban-spec", - "stellar-xdr", - "thiserror", -] - [[package]] name = "soroban-spec-rust" version = "20.3.1" @@ -3653,82 +1744,32 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "sha2 0.10.8", + "sha2", "soroban-spec", "stellar-xdr", - "syn 2.0.39", + "syn", "thiserror", ] [[package]] name = "soroban-spec-tools" -version = "20.3.0" -source = "git+https://github.com/stellar/soroban-tools?rev=a1e51d263df80682a3dab2b00738700c7326f872#a1e51d263df80682a3dab2b00738700c7326f872" -dependencies = [ - "base64 0.21.7", - "ethnum", - "hex", - "itertools 0.10.5", - "serde_json", - "soroban-env-host", - "soroban-spec", - "stellar-strkey 0.0.7", - "stellar-xdr", - "thiserror", - "wasmparser 0.90.0", -] - -[[package]] -name = "soroban-spec-typescript" -version = "20.3.0" -source = "git+https://github.com/stellar/soroban-tools?rev=a1e51d263df80682a3dab2b00738700c7326f872#a1e51d263df80682a3dab2b00738700c7326f872" -dependencies = [ - "base64 0.21.7", - "heck 0.4.1", - "include_dir", - "itertools 0.10.5", - "prettyplease", - "serde", - "serde_derive", - "serde_json", - "sha2 0.9.9", - "soroban-spec", - "stellar-xdr", - "thiserror", -] - -[[package]] -name = "soroban-test" version = "20.3.1" dependencies = [ - "assert_cmd", - "assert_fs", - "fs_extra", - "predicates 2.1.5", - "sep5", + "base64 0.21.7", + "ethnum", + "hex", + "itertools 0.10.5", "serde_json", - "sha2 0.10.8", - "soroban-cli", "soroban-env-host", - "soroban-ledger-snapshot", - "soroban-sdk", "soroban-spec", - "soroban-spec-tools", "stellar-strkey 0.0.7", + "stellar-xdr", "thiserror", "tokio", + "wasmparser 0.90.0", "which", ] -[[package]] -name = "soroban-token-sdk" -version = "20.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "867bd2927e092f2bbf65d1e3cda9f89fa1d1eea935776416bf3ead47fccc82ef" -dependencies = [ - "soroban-sdk", -] - [[package]] name = "soroban-wasmi" version = "0.31.1-soroban.20.0.1" @@ -3781,7 +1822,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12d2bf45e114117ea91d820a846fd1afbe3ba7d717988fee094ce8227a3bf8bd" dependencies = [ "base32", - "crate-git-revision 0.0.6", + "crate-git-revision", "thiserror", ] @@ -3793,15 +1834,12 @@ checksum = "e59cdf3eb4467fb5a4b00b52e7de6dca72f67fac6f9b700f55c95a5d86f09c9d" dependencies = [ "arbitrary", "base64 0.13.1", - "clap", - "crate-git-revision 0.0.6", + "crate-git-revision", "escape-bytes", "hex", "serde", - "serde_json", "serde_with", "stellar-strkey 0.0.8", - "thiserror", ] [[package]] @@ -3816,41 +1854,12 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" -[[package]] -name = "strum" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "530efb820d53b712f4e347916c5e7ed20deb76a4f0457943b3182fb889b06d2c" - -[[package]] -name = "strum_macros" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6e163a520367c465f59e0a61a23cfae3b10b6546d78b6f672a382be79f7110" -dependencies = [ - "heck 0.3.3", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "subtle" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.39" @@ -3862,45 +1871,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "tempfile" -version = "3.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" -dependencies = [ - "cfg-if", - "fastrand", - "rustix", - "windows-sys 0.52.0", -] - [[package]] name = "termcolor" version = "1.4.1" @@ -3926,48 +1896,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f34dde0bb841eb3762b42bdff8db11bbdbc0a3bd7b32012955f5ce1d081f86c1" -[[package]] -name = "termtree" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" - -[[package]] -name = "test_custom_types" -version = "20.3.1" -dependencies = [ - "soroban-sdk", -] - -[[package]] -name = "test_hello_world" -version = "20.3.1" -dependencies = [ - "soroban-sdk", -] - -[[package]] -name = "test_swap" -version = "20.3.1" -dependencies = [ - "soroban-sdk", -] - -[[package]] -name = "test_token" -version = "20.3.1" -dependencies = [ - "soroban-sdk", - "soroban-token-sdk", -] - -[[package]] -name = "test_udt" -version = "20.3.1" -dependencies = [ - "soroban-sdk", -] - [[package]] name = "thiserror" version = "1.0.55" @@ -3985,17 +1913,7 @@ checksum = "268026685b2be38d7103e9e507c938a1fcb3d7e6eb15e87870b617bf37b6d581" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", -] - -[[package]] -name = "thread_local" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" -dependencies = [ - "cfg-if", - "once_cell", + "syn", ] [[package]] @@ -4006,9 +1924,7 @@ checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ "deranged", "itoa", - "libc", "num-conv", - "num_threads", "powerfmt", "serde", "time-core", @@ -4031,25 +1947,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "tiny-bip39" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62cc94d358b5a1e84a5cb9109f559aa3c4d634d2b1b4de3d0fa4adc7c78e2861" -dependencies = [ - "anyhow", - "hmac 0.12.1", - "once_cell", - "pbkdf2", - "rand", - "rustc-hash", - "sha2 0.10.8", - "thiserror", - "unicode-normalization", - "wasm-bindgen", - "zeroize", -] - [[package]] name = "tinyvec" version = "1.6.0" @@ -4075,36 +1972,11 @@ dependencies = [ "bytes", "libc", "mio", - "num_cpus", - "parking_lot", "pin-project-lite", - "signal-hook-registry", "socket2", - "tokio-macros", "windows-sys 0.48.0", ] -[[package]] -name = "tokio-macros" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.39", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.24.1" @@ -4129,32 +2001,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_datetime" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" - -[[package]] -name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap 2.2.2", - "toml_datetime", - "winnow", -] - [[package]] name = "tower" version = "0.4.13" @@ -4194,18 +2040,6 @@ dependencies = [ "tracing-core", ] -[[package]] -name = "tracing-appender" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" -dependencies = [ - "crossbeam-channel", - "thiserror", - "time", - "tracing-subscriber", -] - [[package]] name = "tracing-attributes" version = "0.1.27" @@ -4214,7 +2048,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn", ] [[package]] @@ -4224,36 +2058,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", ] [[package]] @@ -4274,12 +2078,6 @@ version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" -[[package]] -name = "unicode-bom" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" - [[package]] name = "unicode-ident" version = "1.0.12" @@ -4295,36 +2093,12 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" - [[package]] name = "untrusted" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" -[[package]] -name = "ureq" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97" -dependencies = [ - "base64 0.21.7", - "flate2", - "log", - "once_cell", - "rustls", - "rustls-webpki", - "serde", - "serde_json", - "url", - "webpki-roots", -] - [[package]] name = "url" version = "2.5.0" @@ -4342,43 +2116,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wait-timeout" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" -dependencies = [ - "libc", -] - -[[package]] -name = "walkdir" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" -dependencies = [ - "same-file", - "winapi-util", -] - [[package]] name = "want" version = "0.3.1" @@ -4415,22 +2158,10 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.39", + "syn", "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "wasm-bindgen-macro" version = "0.2.91" @@ -4449,7 +2180,7 @@ checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4505,22 +2236,6 @@ dependencies = [ "indexmap-nostd", ] -[[package]] -name = "web-sys" -version = "0.3.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - [[package]] name = "which" version = "4.4.2" @@ -4530,7 +2245,6 @@ dependencies = [ "either", "home", "once_cell", - "regex", "rustix", ] @@ -4706,41 +2420,8 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" -[[package]] -name = "winnow" -version = "0.5.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5389a154b01683d28c77f8f68f49dea75f0a4da32557a58f68ee51ebba472d29" -dependencies = [ - "memchr", -] - -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "zeroize" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.39", -] diff --git a/Cargo.toml b/Cargo.toml index 0fd9a7c1..68e3f63a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,13 +2,11 @@ resolver = "2" members = [ "cmd/crates/soroban-rpc", - "cmd/crates/soroban-test", - "cmd/crates/soroban-test/tests/fixtures/test-wasms/*", - "cmd/crates/soroban-test/tests/fixtures/hello", + "cmd/crates/soroban-spec-tools", "cmd/soroban-rpc/lib/preflight", ] -default-members = ["cmd/crates/soroban-rpc", "cmd/crates/soroban-test"] -exclude = ["cmd/crates/soroban-test/tests/fixtures/hello"] +default-members = ["cmd/crates/soroban-rpc", "cmd/crates/soroban-spec-tools"] +#exclude = ["cmd/crates/soroban-test/tests/fixtures/hello"] [workspace.package] version = "20.3.1" @@ -49,9 +47,8 @@ git = "https://github.com/stellar/soroban-tools" rev = "a59f5f421a27bab71472041fc619dd8b0d1cf902" [workspace.dependencies.soroban-spec-tools] -version = "20.3.0" -git = "https://github.com/stellar/soroban-tools" -rev = "a1e51d263df80682a3dab2b00738700c7326f872" +version = "20.2.0" +path = "./cmd/crates/soroban-spec-tools" [workspace.dependencies.soroban-sdk] version = "=20.3.1" @@ -68,11 +65,6 @@ version = "=20.3.1" # git = "https://github.com/stellar/rs-soroban-sdk" # rev = "4aef54ff9295c2fca4c5b9fbd2c92d0ff99f67de" -[workspace.dependencies.soroban-cli] -version = "20.3.0" -git = "https://github.com/stellar/soroban-tools" -rev = "a1e51d263df80682a3dab2b00738700c7326f872" - [workspace.dependencies.soroban-rpc] version = "20.3.1" path = "cmd/crates/soroban-rpc" diff --git a/Makefile b/Makefile index 39e3d743..f0ad7e89 100644 --- a/Makefile +++ b/Makefile @@ -40,9 +40,9 @@ CARGO_BUILD_TARGET ?= $(shell rustc -vV | sed -n 's|host: ||p') Cargo.lock: Cargo.toml cargo update --workspace -install_rust: Cargo.lock - cargo install soroban-cli --version 20.2.0 - cargo install --path ./cmd/crates/soroban-test/tests/fixtures/hello --root ./target --debug --quiet +#install_rust: Cargo.lock +# cargo install soroban-cli --version 20.2.0 +# cargo install --path ./cmd/crates/soroban-test/tests/fixtures/hello --root ./target --debug --quiet install: install_rust build-libpreflight go install -ldflags="${GOLDFLAGS}" ${MACOS_MIN_VER} ./... diff --git a/cmd/crates/soroban-spec-tools/Cargo.toml b/cmd/crates/soroban-spec-tools/Cargo.toml new file mode 100644 index 00000000..514b8292 --- /dev/null +++ b/cmd/crates/soroban-spec-tools/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "soroban-spec-tools" +description = "Tools for using a contract's XDR spec" +homepage = "https://github.com/stellar/soroban-tools" +repository = "https://github.com/stellar/soroban-tools" +authors = ["Stellar Development Foundation "] +license = "Apache-2.0" +readme = "README.md" +version.workspace = true +edition = "2021" +rust-version.workspace = true +autobins = false + + +[lib] +crate-type = ["rlib"] + + +[dependencies] +soroban-spec = { workspace = true } +stellar-strkey = { workspace = true } +stellar-xdr = { workspace = true, features = ["curr", "std", "serde"] } +soroban-env-host = { workspace = true } + +serde_json = { workspace = true } +itertools = { workspace = true } +ethnum = { workspace = true } +hex = { workspace = true } +wasmparser = { workspace = true } +base64 = { workspace = true } +thiserror = "1.0.31" +# soroban-ledger-snapshot = { workspace = true } +# soroban-sdk = { workspace = true } +# sep5 = { workspace = true } + + +[dev-dependencies] +which = { workspace = true } +tokio = "1.28.1" diff --git a/cmd/crates/soroban-spec-tools/README.md b/cmd/crates/soroban-spec-tools/README.md new file mode 100644 index 00000000..d2b00654 --- /dev/null +++ b/cmd/crates/soroban-spec-tools/README.md @@ -0,0 +1,3 @@ +# soroban-spec-tools + +Tools and utilities for soroban specification / interface. diff --git a/cmd/crates/soroban-spec-tools/src/contract.rs b/cmd/crates/soroban-spec-tools/src/contract.rs new file mode 100644 index 00000000..2d0d857c --- /dev/null +++ b/cmd/crates/soroban-spec-tools/src/contract.rs @@ -0,0 +1,276 @@ +use base64::{engine::general_purpose::STANDARD as base64, Engine as _}; +use std::{ + fmt::Display, + io::{self, Cursor}, +}; + +use soroban_env_host::xdr::{ + self, Limited, Limits, ReadXdr, ScEnvMetaEntry, ScMetaEntry, ScMetaV0, ScSpecEntry, + ScSpecFunctionV0, ScSpecUdtEnumV0, ScSpecUdtErrorEnumV0, ScSpecUdtStructV0, ScSpecUdtUnionV0, + StringM, WriteXdr, +}; + +pub struct Spec { + pub env_meta_base64: Option, + pub env_meta: Vec, + pub meta_base64: Option, + pub meta: Vec, + pub spec_base64: Option, + pub spec: Vec, +} + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("reading file {filepath}: {error}")] + CannotReadContractFile { + filepath: std::path::PathBuf, + error: io::Error, + }, + #[error("cannot parse wasm file {file}: {error}")] + CannotParseWasm { + file: std::path::PathBuf, + error: wasmparser::BinaryReaderError, + }, + #[error("xdr processing error: {0}")] + Xdr(#[from] xdr::Error), + + #[error(transparent)] + Parser(#[from] wasmparser::BinaryReaderError), +} + +impl Spec { + pub fn new(bytes: &[u8]) -> Result { + let mut env_meta: Option<&[u8]> = None; + let mut meta: Option<&[u8]> = None; + let mut spec: Option<&[u8]> = None; + for payload in wasmparser::Parser::new(0).parse_all(bytes) { + let payload = payload?; + if let wasmparser::Payload::CustomSection(section) = payload { + let out = match section.name() { + "contractenvmetav0" => &mut env_meta, + "contractmetav0" => &mut meta, + "contractspecv0" => &mut spec, + _ => continue, + }; + *out = Some(section.data()); + }; + } + + let mut env_meta_base64 = None; + let env_meta = if let Some(env_meta) = env_meta { + env_meta_base64 = Some(base64.encode(env_meta)); + let cursor = Cursor::new(env_meta); + let mut read = Limited::new(cursor, Limits::none()); + ScEnvMetaEntry::read_xdr_iter(&mut read).collect::, xdr::Error>>()? + } else { + vec![] + }; + + let mut meta_base64 = None; + let meta = if let Some(meta) = meta { + meta_base64 = Some(base64.encode(meta)); + let cursor = Cursor::new(meta); + let mut depth_limit_read = Limited::new(cursor, Limits::none()); + ScMetaEntry::read_xdr_iter(&mut depth_limit_read) + .collect::, xdr::Error>>()? + } else { + vec![] + }; + + let mut spec_base64 = None; + let spec = if let Some(spec) = spec { + spec_base64 = Some(base64.encode(spec)); + let cursor = Cursor::new(spec); + let mut read = Limited::new(cursor, Limits::none()); + ScSpecEntry::read_xdr_iter(&mut read).collect::, xdr::Error>>()? + } else { + vec![] + }; + + Ok(Spec { + env_meta_base64, + env_meta, + meta_base64, + meta, + spec_base64, + spec, + }) + } + + pub fn spec_as_json_array(&self) -> Result { + let spec = self + .spec + .iter() + .map(|e| Ok(format!("\"{}\"", e.to_xdr_base64(Limits::none())?))) + .collect::, Error>>()? + .join(",\n"); + Ok(format!("[{spec}]")) + } +} + +impl Display for Spec { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(env_meta) = &self.env_meta_base64 { + writeln!(f, "Env Meta: {env_meta}")?; + for env_meta_entry in &self.env_meta { + match env_meta_entry { + ScEnvMetaEntry::ScEnvMetaKindInterfaceVersion(v) => { + writeln!(f, " • Interface Version: {v}")?; + } + } + } + writeln!(f)?; + } else { + writeln!(f, "Env Meta: None\n")?; + } + + if let Some(_meta) = &self.meta_base64 { + writeln!(f, "Contract Meta:")?; + for meta_entry in &self.meta { + match meta_entry { + ScMetaEntry::ScMetaV0(ScMetaV0 { key, val }) => { + writeln!(f, " • {key}: {val}")?; + } + } + } + writeln!(f)?; + } else { + writeln!(f, "Contract Meta: None\n")?; + } + + if let Some(_spec_base64) = &self.spec_base64 { + writeln!(f, "Contract Spec:")?; + for spec_entry in &self.spec { + match spec_entry { + ScSpecEntry::FunctionV0(func) => write_func(f, func)?, + ScSpecEntry::UdtUnionV0(udt) => write_union(f, udt)?, + ScSpecEntry::UdtStructV0(udt) => write_struct(f, udt)?, + ScSpecEntry::UdtEnumV0(udt) => write_enum(f, udt)?, + ScSpecEntry::UdtErrorEnumV0(udt) => write_error(f, udt)?, + } + } + } else { + writeln!(f, "Contract Spec: None")?; + } + Ok(()) + } +} + +fn write_func(f: &mut std::fmt::Formatter<'_>, func: &ScSpecFunctionV0) -> std::fmt::Result { + writeln!(f, " • Function: {}", func.name.to_utf8_string_lossy())?; + if func.doc.len() > 0 { + writeln!( + f, + " Docs: {}", + &indent(&func.doc.to_utf8_string_lossy(), 11).trim() + )?; + } + writeln!( + f, + " Inputs: {}", + indent(&format!("{:#?}", func.inputs), 5).trim() + )?; + writeln!( + f, + " Output: {}", + indent(&format!("{:#?}", func.outputs), 5).trim() + )?; + writeln!(f)?; + Ok(()) +} + +fn write_union(f: &mut std::fmt::Formatter<'_>, udt: &ScSpecUdtUnionV0) -> std::fmt::Result { + writeln!(f, " • Union: {}", format_name(&udt.lib, &udt.name))?; + if udt.doc.len() > 0 { + writeln!( + f, + " Docs: {}", + indent(&udt.doc.to_utf8_string_lossy(), 10).trim() + )?; + } + writeln!(f, " Cases:")?; + for case in udt.cases.iter() { + writeln!(f, " • {}", indent(&format!("{case:#?}"), 8).trim())?; + } + writeln!(f)?; + Ok(()) +} + +fn write_struct(f: &mut std::fmt::Formatter<'_>, udt: &ScSpecUdtStructV0) -> std::fmt::Result { + writeln!(f, " • Struct: {}", format_name(&udt.lib, &udt.name))?; + if udt.doc.len() > 0 { + writeln!( + f, + " Docs: {}", + indent(&udt.doc.to_utf8_string_lossy(), 10).trim() + )?; + } + writeln!(f, " Fields:")?; + for field in udt.fields.iter() { + writeln!( + f, + " • {}: {}", + field.name.to_utf8_string_lossy(), + indent(&format!("{:#?}", field.type_), 8).trim() + )?; + if field.doc.len() > 0 { + writeln!(f, "{}", indent(&format!("{:#?}", field.doc), 8))?; + } + } + writeln!(f)?; + Ok(()) +} + +fn write_enum(f: &mut std::fmt::Formatter<'_>, udt: &ScSpecUdtEnumV0) -> std::fmt::Result { + writeln!(f, " • Enum: {}", format_name(&udt.lib, &udt.name))?; + if udt.doc.len() > 0 { + writeln!( + f, + " Docs: {}", + indent(&udt.doc.to_utf8_string_lossy(), 10).trim() + )?; + } + writeln!(f, " Cases:")?; + for case in udt.cases.iter() { + writeln!(f, " • {}", indent(&format!("{case:#?}"), 8).trim())?; + } + writeln!(f)?; + Ok(()) +} + +fn write_error(f: &mut std::fmt::Formatter<'_>, udt: &ScSpecUdtErrorEnumV0) -> std::fmt::Result { + writeln!(f, " • Error: {}", format_name(&udt.lib, &udt.name))?; + if udt.doc.len() > 0 { + writeln!( + f, + " Docs: {}", + indent(&udt.doc.to_utf8_string_lossy(), 10).trim() + )?; + } + writeln!(f, " Cases:")?; + for case in udt.cases.iter() { + writeln!(f, " • {}", indent(&format!("{case:#?}"), 8).trim())?; + } + writeln!(f)?; + Ok(()) +} + +fn indent(s: &str, n: usize) -> String { + let pad = " ".repeat(n); + s.lines() + .map(|line| format!("{pad}{line}")) + .collect::>() + .join("\n") +} + +fn format_name(lib: &StringM<80>, name: &StringM<60>) -> String { + if lib.len() > 0 { + format!( + "{}::{}", + lib.to_utf8_string_lossy(), + name.to_utf8_string_lossy() + ) + } else { + name.to_utf8_string_lossy() + } +} diff --git a/cmd/crates/soroban-spec-tools/src/lib.rs b/cmd/crates/soroban-spec-tools/src/lib.rs new file mode 100644 index 00000000..bc3c2a38 --- /dev/null +++ b/cmd/crates/soroban-spec-tools/src/lib.rs @@ -0,0 +1,1469 @@ +#![allow(clippy::missing_errors_doc, clippy::must_use_candidate)] +use std::str::FromStr; + +use itertools::Itertools; +use serde_json::{json, Value}; +use stellar_xdr::curr::{ + AccountId, BytesM, ContractExecutable, Error as XdrError, Hash, Int128Parts, Int256Parts, + PublicKey, ScAddress, ScBytes, ScContractInstance, ScMap, ScMapEntry, ScNonceKey, ScSpecEntry, + ScSpecFunctionV0, ScSpecTypeDef as ScType, ScSpecTypeMap, ScSpecTypeOption, ScSpecTypeResult, + ScSpecTypeTuple, ScSpecTypeUdt, ScSpecTypeVec, ScSpecUdtEnumV0, ScSpecUdtErrorEnumCaseV0, + ScSpecUdtErrorEnumV0, ScSpecUdtStructV0, ScSpecUdtUnionCaseTupleV0, ScSpecUdtUnionCaseV0, + ScSpecUdtUnionCaseVoidV0, ScSpecUdtUnionV0, ScString, ScSymbol, ScVal, ScVec, StringM, + UInt128Parts, UInt256Parts, Uint256, VecM, +}; + +pub mod contract; +pub mod utils; + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("an unknown error occurred")] + Unknown, + #[error("Invalid pair {0:#?} {1:#?}")] + InvalidPair(ScVal, ScType), + #[error("value is not parseable to {0:#?}")] + InvalidValue(Option), + #[error("Unknown case {0} for {1}")] + EnumCase(String, String), + #[error("Enum {0} missing value for type {1}")] + EnumMissingSecondValue(String, String), + #[error("Enum {0} is illformed")] + IllFormedEnum(String), + #[error("Unknown const case {0}")] + EnumConst(u32), + #[error("Enum const value must be a u32 or smaller")] + EnumConstTooLarge(u64), + #[error("Missing Entry {0}")] + MissingEntry(String), + #[error("Missing Spec")] + MissingSpec, + #[error(transparent)] + Xdr(XdrError), + #[error(transparent)] + Serde(#[from] serde_json::Error), + #[error(transparent)] + Ethnum(#[from] core::num::ParseIntError), + + #[error("Missing key {0} in map")] + MissingKey(String), + #[error("Failed to convert {0} to number")] + FailedNumConversion(serde_json::Number), + #[error("First argument in an enum must be a sybmol")] + EnumFirstValueNotSymbol, + #[error("Failed to find enum case {0}")] + FailedToFindEnumCase(String), + #[error(transparent)] + FailedSilceToByte(#[from] std::array::TryFromSliceError), + #[error(transparent)] + Infallible(#[from] std::convert::Infallible), + #[error("Missing Error case {0}")] + MissingErrorCase(u32), + #[error(transparent)] + Spec(#[from] soroban_spec::read::FromWasmError), + #[error(transparent)] + Base64Spec(#[from] soroban_spec::read::ParseSpecBase64Error), +} + +#[derive(Default, Clone)] +pub struct Spec(pub Option>); + +impl TryInto for &[u8] { + type Error = soroban_spec::read::FromWasmError; + + fn try_into(self) -> Result { + let spec = soroban_spec::read::from_wasm(self)?; + Ok(Spec::new(spec)) + } +} + +impl Spec { + pub fn new(entries: Vec) -> Self { + Self(Some(entries)) + } + + pub fn from_wasm(wasm: &[u8]) -> Result { + let spec = soroban_spec::read::from_wasm(wasm)?; + Ok(Spec::new(spec)) + } + + pub fn parse_base64(base64: &str) -> Result { + let spec = soroban_spec::read::parse_base64(base64.as_bytes())?; + Ok(Spec::new(spec)) + } +} + +impl Spec { + /// # Errors + /// Could fail to find User Defined Type + pub fn doc(&self, name: &str, type_: &ScType) -> Result, Error> { + let mut str = match type_ { + ScType::Val + | ScType::U64 + | ScType::I64 + | ScType::U128 + | ScType::I128 + | ScType::U32 + | ScType::I32 + | ScType::Result(_) + | ScType::Vec(_) + | ScType::Map(_) + | ScType::Tuple(_) + | ScType::BytesN(_) + | ScType::Symbol + | ScType::Error + | ScType::Bytes + | ScType::Void + | ScType::Timepoint + | ScType::Duration + | ScType::U256 + | ScType::I256 + | ScType::String + | ScType::Bool => String::new(), + ScType::Address => String::from( + "Can be public key (G13..), a contract hash (6c45307) or an identity (alice), ", + ), + ScType::Option(type_) => return self.doc(name, &type_.value_type), + ScType::Udt(ScSpecTypeUdt { name }) => { + let spec_type = self.find(&name.to_utf8_string_lossy())?; + match spec_type { + ScSpecEntry::FunctionV0(ScSpecFunctionV0 { doc, .. }) + | ScSpecEntry::UdtStructV0(ScSpecUdtStructV0 { doc, .. }) + | ScSpecEntry::UdtUnionV0(ScSpecUdtUnionV0 { doc, .. }) + | ScSpecEntry::UdtEnumV0(ScSpecUdtEnumV0 { doc, .. }) + | ScSpecEntry::UdtErrorEnumV0(ScSpecUdtErrorEnumV0 { doc, .. }) => doc, + } + .to_utf8_string_lossy() + } + }; + if let Some(mut ex) = self.example(type_) { + if ex.contains(' ') { + ex = format!("'{ex}'"); + } else if ex.contains('"') { + ex = ex.replace('"', ""); + } + if matches!(type_, ScType::Bool) { + ex = String::new(); + } + let sep = if str.is_empty() { "" } else { "\n" }; + str = format!("{str}{sep}Example:\n --{name} {ex}"); + if ex.contains('"') {} + } + if str.is_empty() { + Ok(None) + } else { + Ok(Some(Box::leak(str.into_boxed_str()))) + } + } + + /// # Errors + /// + /// Might return errors + pub fn find(&self, name: &str) -> Result<&ScSpecEntry, Error> { + self.0 + .as_ref() + .and_then(|specs| { + specs.iter().find(|e| { + let entry_name = match e { + ScSpecEntry::FunctionV0(x) => x.name.to_utf8_string_lossy(), + ScSpecEntry::UdtStructV0(x) => x.name.to_utf8_string_lossy(), + ScSpecEntry::UdtUnionV0(x) => x.name.to_utf8_string_lossy(), + ScSpecEntry::UdtEnumV0(x) => x.name.to_utf8_string_lossy(), + ScSpecEntry::UdtErrorEnumV0(x) => x.name.to_utf8_string_lossy(), + }; + name == entry_name + }) + }) + .ok_or_else(|| Error::MissingEntry(name.to_owned())) + } + + /// # Errors + /// + /// Might return errors + pub fn find_function(&self, name: &str) -> Result<&ScSpecFunctionV0, Error> { + match self.find(name)? { + ScSpecEntry::FunctionV0(f) => Ok(f), + _ => Err(Error::MissingEntry(name.to_owned())), + } + } + // + /// # Errors + /// + pub fn find_functions(&self) -> Result, Error> { + Ok(self + .0 + .as_ref() + .ok_or(Error::MissingSpec)? + .iter() + .filter_map(|e| match e { + ScSpecEntry::FunctionV0(x) => Some(x), + _ => None, + })) + } + + /// # Errors + /// + pub fn find_error_type(&self, value: u32) -> Result<&ScSpecUdtErrorEnumCaseV0, Error> { + if let ScSpecEntry::UdtErrorEnumV0(ScSpecUdtErrorEnumV0 { cases, .. }) = + self.find("Error")? + { + if let Some(case) = cases.iter().find(|case| value == case.value) { + return Ok(case); + } + } + Err(Error::MissingErrorCase(value)) + } + + /// # Errors + /// + /// Might return errors + pub fn from_string_primitive(s: &str, t: &ScType) -> Result { + Self::default().from_string(s, t) + } + + /// # Errors + /// + /// Might return errors + #[allow(clippy::wrong_self_convention)] + pub fn from_string(&self, s: &str, t: &ScType) -> Result { + if let ScType::Option(b) = t { + if s == "null" { + return Ok(ScVal::Void); + } + let ScSpecTypeOption { value_type } = b.as_ref().clone(); + let v = value_type.as_ref().clone(); + return self.from_string(s, &v); + } + // Parse as string and for special types assume Value::String + serde_json::from_str(s) + .map_or_else( + |e| match t { + ScType::Symbol + | ScType::String + | ScType::Bytes + | ScType::BytesN(_) + | ScType::U256 + | ScType::I256 + | ScType::U128 + | ScType::I128 + | ScType::Address => Ok(Value::String(s.to_owned())), + ScType::Udt(ScSpecTypeUdt { name }) + if matches!( + self.find(&name.to_utf8_string_lossy())?, + ScSpecEntry::UdtUnionV0(_) | ScSpecEntry::UdtStructV0(_) + ) => + { + Ok(Value::String(s.to_owned())) + } + _ => Err(Error::Serde(e)), + }, + |val| match t { + ScType::U128 | ScType::I128 | ScType::U256 | ScType::I256 => { + Ok(Value::String(s.to_owned())) + } + _ => Ok(val), + }, + ) + .and_then(|raw| self.from_json(&raw, t)) + } + + /// # Errors + /// + /// Might return errors + #[allow(clippy::wrong_self_convention)] + pub fn from_json(&self, v: &Value, t: &ScType) -> Result { + let val: ScVal = match (t, v) { + ( + ScType::Bool + | ScType::U128 + | ScType::I128 + | ScType::U256 + | ScType::I256 + | ScType::I32 + | ScType::I64 + | ScType::U32 + | ScType::U64 + | ScType::String + | ScType::Symbol + | ScType::Address + | ScType::Bytes + | ScType::BytesN(_), + _, + ) => from_json_primitives(v, t)?, + + // Vec parsing + (ScType::Vec(elem), Value::Array(raw)) => { + let converted: ScVec = raw + .iter() + .map(|item| self.from_json(item, &elem.element_type)) + .collect::, Error>>()? + .try_into() + .map_err(Error::Xdr)?; + ScVal::Vec(Some(converted)) + } + + // Map parsing + (ScType::Map(map), Value::Object(raw)) => self.parse_map(map, raw)?, + + // Option parsing + (ScType::Option(_), Value::Null) => ScVal::Void, + (ScType::Option(elem), v) => self.from_json(v, &elem.value_type)?, + + // Tuple parsing + (ScType::Tuple(elem), Value::Array(raw)) => self.parse_tuple(t, elem, raw)?, + + // User defined types parsing + (ScType::Udt(ScSpecTypeUdt { name }), _) => self.parse_udt(name, v)?, + + // TODO: Implement the rest of these + (_, raw) => serde_json::from_value(raw.clone()).map_err(Error::Serde)?, + }; + Ok(val) + } + + fn parse_udt(&self, name: &StringM<60>, value: &Value) -> Result { + let name = &name.to_utf8_string_lossy(); + match (self.find(name)?, value) { + (ScSpecEntry::UdtStructV0(strukt), Value::Object(map)) => { + if strukt + .fields + .iter() + .any(|f| f.name.to_utf8_string_lossy() == "0") + { + self.parse_tuple_strukt( + strukt, + &(0..map.len()) + .map(|i| map.get(&i.to_string()).unwrap().clone()) + .collect::>(), + ) + } else { + self.parse_strukt(strukt, map) + } + } + (ScSpecEntry::UdtStructV0(strukt), Value::Array(arr)) => { + self.parse_tuple_strukt(strukt, arr) + } + ( + ScSpecEntry::UdtUnionV0(union), + val @ (Value::Array(_) | Value::String(_) | Value::Object(_)), + ) => self.parse_union(union, val), + (ScSpecEntry::UdtEnumV0(enum_), Value::Number(num)) => parse_const_enum(num, enum_), + (s, v) => todo!("Not implemented for {s:#?} {v:#?}"), + } + } + + fn parse_tuple_strukt( + &self, + strukt: &ScSpecUdtStructV0, + array: &[Value], + ) -> Result { + let items = strukt + .fields + .to_vec() + .iter() + .zip(array.iter()) + .map(|(f, v)| { + let val = self.from_json(v, &f.type_)?; + Ok(val) + }) + .collect::, Error>>()?; + Ok(ScVal::Vec(Some(items.try_into().map_err(Error::Xdr)?))) + } + + fn parse_strukt( + &self, + strukt: &ScSpecUdtStructV0, + map: &serde_json::Map, + ) -> Result { + let items = strukt + .fields + .to_vec() + .iter() + .map(|f| { + let name = &f.name.to_utf8_string_lossy(); + let v = map + .get(name) + .ok_or_else(|| Error::MissingKey(name.clone()))?; + let val = self.from_json(v, &f.type_)?; + let key = StringM::from_str(name).unwrap(); + Ok(ScMapEntry { + key: ScVal::Symbol(key.into()), + val, + }) + }) + .collect::, Error>>()?; + let map = ScMap::sorted_from(items).map_err(Error::Xdr)?; + Ok(ScVal::Map(Some(map))) + } + + fn parse_union(&self, union: &ScSpecUdtUnionV0, value: &Value) -> Result { + let (enum_case, rest) = match value { + Value::String(s) => (s, None), + Value::Object(o) if o.len() == 1 => { + let res = o.values().next().map(|v| match v { + Value::Object(obj) if obj.contains_key("0") => { + let len = obj.len(); + Value::Array( + (0..len) + .map(|i| obj.get(&i.to_string()).unwrap().clone()) + .collect::>(), + ) + } + _ => v.clone(), + }); + (o.keys().next().unwrap(), res) + } + _ => todo!(), + }; + let case = union + .cases + .iter() + .find(|c| { + let name = match c { + ScSpecUdtUnionCaseV0::VoidV0(v) => &v.name, + ScSpecUdtUnionCaseV0::TupleV0(v) => &v.name, + }; + enum_case == &name.to_utf8_string_lossy() + }) + .ok_or_else(|| { + Error::EnumCase(enum_case.to_string(), union.name.to_utf8_string_lossy()) + })?; + + let mut res = vec![ScVal::Symbol(ScSymbol( + enum_case.try_into().map_err(Error::Xdr)?, + ))]; + + match (case, rest) { + (ScSpecUdtUnionCaseV0::VoidV0(_), _) | (ScSpecUdtUnionCaseV0::TupleV0(_), None) => (), + (ScSpecUdtUnionCaseV0::TupleV0(ScSpecUdtUnionCaseTupleV0 { type_, .. }), Some(arr)) + if type_.len() == 1 => + { + res.push(self.from_json(&arr, &type_[0])?); + } + ( + ScSpecUdtUnionCaseV0::TupleV0(ScSpecUdtUnionCaseTupleV0 { type_, .. }), + Some(Value::Array(arr)), + ) => { + res.extend( + arr.iter() + .zip(type_.iter()) + .map(|(elem, ty)| self.from_json(elem, ty)) + .collect::, _>>()?, + ); + } + (ScSpecUdtUnionCaseV0::TupleV0(ScSpecUdtUnionCaseTupleV0 { .. }), Some(_)) => {} + }; + Ok(ScVal::Vec(Some(res.try_into().map_err(Error::Xdr)?))) + } + + fn parse_tuple( + &self, + t: &ScType, + tuple: &ScSpecTypeTuple, + items: &[Value], + ) -> Result { + let ScSpecTypeTuple { value_types } = tuple; + if items.len() != value_types.len() { + return Err(Error::InvalidValue(Some(t.clone()))); + }; + let parsed: Result, Error> = items + .iter() + .zip(value_types.iter()) + .map(|(item, t)| self.from_json(item, t)) + .collect(); + let converted: ScVec = parsed?.try_into().map_err(Error::Xdr)?; + Ok(ScVal::Vec(Some(converted))) + } + + fn parse_map( + &self, + map: &ScSpecTypeMap, + value_map: &serde_json::Map, + ) -> Result { + let ScSpecTypeMap { + key_type, + value_type, + } = map; + // TODO: What do we do if the expected key_type is not a string or symbol? + let parsed: Result, Error> = value_map + .iter() + .map(|(k, v)| -> Result { + let key = self.from_string(k, key_type)?; + let val = self.from_json(v, value_type)?; + Ok(ScMapEntry { key, val }) + }) + .collect(); + Ok(ScVal::Map(Some( + ScMap::sorted_from(parsed?).map_err(Error::Xdr)?, + ))) + } +} + +impl Spec { + /// # Errors + /// + /// Might return `Error::InvalidValue` + /// + /// # Panics + /// + /// May panic + pub fn xdr_to_json(&self, val: &ScVal, output: &ScType) -> Result { + Ok(match (val, output) { + (ScVal::Void, ScType::Val | ScType::Option(_) | ScType::Tuple(_)) + | (ScVal::Map(None) | ScVal::Vec(None), ScType::Option(_)) => Value::Null, + (ScVal::Bool(_), ScType::Bool) + | (ScVal::Void, ScType::Void) + | (ScVal::String(_), ScType::String) + | (ScVal::Symbol(_), ScType::Symbol) + | (ScVal::U64(_), ScType::U64) + | (ScVal::I64(_), ScType::I64) + | (ScVal::U32(_), ScType::U32) + | (ScVal::I32(_), ScType::I32) + | (ScVal::U128(_), ScType::U128) + | (ScVal::I128(_), ScType::I128) + | (ScVal::U256(_), ScType::U256) + | (ScVal::I256(_), ScType::I256) + | (ScVal::Duration(_), ScType::Duration) + | (ScVal::Timepoint(_), ScType::Timepoint) + | ( + ScVal::ContractInstance(_) + | ScVal::LedgerKeyContractInstance + | ScVal::LedgerKeyNonce(_), + _, + ) + | (ScVal::Address(_), ScType::Address) + | (ScVal::Bytes(_), ScType::Bytes | ScType::BytesN(_)) => to_json(val)?, + + (val, ScType::Result(inner)) => self.xdr_to_json(val, &inner.ok_type)?, + + (val, ScType::Option(inner)) => self.xdr_to_json(val, &inner.value_type)?, + (ScVal::Map(Some(_)) | ScVal::Vec(Some(_)) | ScVal::U32(_), type_) => { + self.sc_object_to_json(val, type_)? + } + + (ScVal::Error(_), ScType::Error) => todo!(), + (v, typed) => todo!("{v:#?} doesn't have a matching {typed:#?}"), + }) + } + + /// # Errors + /// + /// Might return an error + pub fn vec_m_to_json( + &self, + vec_m: &VecM, + type_: &ScType, + ) -> Result { + Ok(Value::Array( + vec_m + .to_vec() + .iter() + .map(|sc_val| self.xdr_to_json(sc_val, type_)) + .collect::, Error>>()?, + )) + } + + /// # Errors + /// + /// Might return an error + pub fn sc_map_to_json(&self, sc_map: &ScMap, type_: &ScSpecTypeMap) -> Result { + let v = sc_map + .iter() + .map(|ScMapEntry { key, val }| { + let key_s = self.xdr_to_json(key, &type_.key_type)?.to_string(); + let val_value = self.xdr_to_json(val, &type_.value_type)?; + Ok((key_s, val_value)) + }) + .collect::, Error>>()?; + Ok(Value::Object(v)) + } + + /// # Errors + /// + /// Might return an error + /// + /// # Panics + /// + /// May panic + pub fn udt_to_json(&self, name: &StringM<60>, sc_obj: &ScVal) -> Result { + let name = &name.to_utf8_string_lossy(); + let udt = self.find(name)?; + Ok(match (sc_obj, udt) { + (ScVal::Map(Some(map)), ScSpecEntry::UdtStructV0(strukt)) => serde_json::Value::Object( + strukt + .fields + .iter() + .zip(map.iter()) + .map(|(field, entry)| { + let val = self.xdr_to_json(&entry.val, &field.type_)?; + Ok((field.name.to_utf8_string_lossy(), val)) + }) + .collect::, Error>>()?, + ), + (ScVal::Vec(Some(vec_)), ScSpecEntry::UdtStructV0(strukt)) => Value::Array( + strukt + .fields + .iter() + .zip(vec_.iter()) + .map(|(field, entry)| self.xdr_to_json(entry, &field.type_)) + .collect::, Error>>()?, + ), + (ScVal::Vec(Some(vec_)), ScSpecEntry::UdtUnionV0(union)) => { + let v = vec_.to_vec(); + // let val = &v[0]; + let (first, rest) = match v.split_at(1) { + ([first], []) => (first, None), + ([first], rest) => (first, Some(rest)), + _ => return Err(Error::IllFormedEnum(union.name.to_utf8_string_lossy())), + }; + + let ScVal::Symbol(case_name) = first else { + return Err(Error::EnumFirstValueNotSymbol); + }; + let case = union + .cases + .iter() + .find(|case| { + let name = match case { + ScSpecUdtUnionCaseV0::VoidV0(v) => &v.name, + ScSpecUdtUnionCaseV0::TupleV0(v) => &v.name, + }; + name.as_vec() == case_name.as_vec() + }) + .ok_or_else(|| Error::FailedToFindEnumCase(case_name.to_utf8_string_lossy()))?; + + let case_name = case_name.to_utf8_string_lossy(); + match case { + ScSpecUdtUnionCaseV0::TupleV0(v) => { + let rest = rest.ok_or_else(|| { + Error::EnumMissingSecondValue( + union.name.to_utf8_string_lossy(), + case_name.clone(), + ) + })?; + let val = if v.type_.len() == 1 { + self.xdr_to_json(&rest[0], &v.type_[0])? + } else { + Value::Array( + v.type_ + .iter() + .zip(rest.iter()) + .map(|(type_, val)| self.xdr_to_json(val, type_)) + .collect::, Error>>()?, + ) + }; + + Value::Object([(case_name, val)].into_iter().collect()) + } + ScSpecUdtUnionCaseV0::VoidV0(_) => Value::String(case_name), + } + } + (ScVal::U32(v), ScSpecEntry::UdtEnumV0(_enum_)) => { + Value::Number(serde_json::Number::from(*v)) + } + (s, v) => todo!("Not implemented for {s:#?} {v:#?}"), + }) + } + + /// # Errors + /// + /// Might return an error + /// + /// # Panics + /// + /// Some types are not yet supported and will cause a panic if supplied + pub fn sc_object_to_json(&self, val: &ScVal, spec_type: &ScType) -> Result { + Ok(match (val, spec_type) { + (ScVal::Vec(Some(ScVec(vec_m))), ScType::Vec(type_)) => { + self.vec_m_to_json(vec_m, &type_.element_type)? + } + (ScVal::Vec(Some(ScVec(vec_m))), ScType::Tuple(tuple_type)) => Value::Array( + vec_m + .iter() + .zip(tuple_type.value_types.iter()) + .map(|(v, t)| self.xdr_to_json(v, t)) + .collect::, _>>()?, + ), + ( + sc_obj @ (ScVal::Vec(_) | ScVal::Map(_) | ScVal::U32(_)), + ScType::Udt(ScSpecTypeUdt { name }), + ) => self.udt_to_json(name, sc_obj)?, + + (ScVal::Map(Some(map)), ScType::Map(map_type)) => self.sc_map_to_json(map, map_type)?, + + (ScVal::U64(u64_), ScType::U64) => Value::Number(serde_json::Number::from(*u64_)), + + (ScVal::I64(i64_), ScType::I64) => Value::Number(serde_json::Number::from(*i64_)), + (int @ ScVal::U128(_), ScType::U128) => { + // Always output u128s as strings + let v: u128 = int + .clone() + .try_into() + .map_err(|()| Error::InvalidValue(Some(ScType::U128)))?; + Value::String(v.to_string()) + } + + (int @ ScVal::I128(_), ScType::I128) => { + // Always output u128s as strings + let v: i128 = int + .clone() + .try_into() + .map_err(|()| Error::InvalidValue(Some(ScType::I128)))?; + Value::String(v.to_string()) + } + + (ScVal::Bytes(v), ScType::Bytes | ScType::BytesN(_)) => { + Value::String(to_lower_hex(v.as_slice())) + } + + (ScVal::Bytes(_), ScType::Udt(_)) => todo!(), + + (ScVal::ContractInstance(_), _) => todo!(), + + (ScVal::Address(v), ScType::Address) => sc_address_to_json(v), + + (ok_val, ScType::Result(result_type)) => { + let ScSpecTypeResult { ok_type, .. } = result_type.as_ref(); + self.xdr_to_json(ok_val, ok_type)? + } + + (x, y) => return Err(Error::InvalidPair(x.clone(), y.clone())), + }) + } +} + +/// # Errors +/// +/// Might return an error +pub fn from_string_primitive(s: &str, t: &ScType) -> Result { + Spec::from_string_primitive(s, t) +} + +fn parse_const_enum(num: &serde_json::Number, enum_: &ScSpecUdtEnumV0) -> Result { + let num = num + .as_u64() + .ok_or_else(|| Error::FailedNumConversion(num.clone()))?; + let num = u32::try_from(num).map_err(|_| Error::EnumConstTooLarge(num))?; + enum_ + .cases + .iter() + .find(|c| c.value == num) + .ok_or(Error::EnumConst(num)) + .map(|c| ScVal::U32(c.value)) +} + +/// # Errors +/// +/// Might return an error +#[allow(clippy::too_many_lines)] +pub fn from_json_primitives(v: &Value, t: &ScType) -> Result { + let val: ScVal = match (t, v) { + // Boolean parsing + (ScType::Bool, Value::Bool(true)) => ScVal::Bool(true), + (ScType::Bool, Value::Bool(false)) => ScVal::Bool(false), + + // Number parsing + (ScType::U128, Value::String(s)) => { + let val: u128 = u128::from_str(s) + .map(Into::into) + .map_err(|_| Error::InvalidValue(Some(t.clone())))?; + let bytes = val.to_be_bytes(); + let (hi, lo) = bytes.split_at(8); + ScVal::U128(UInt128Parts { + hi: u64::from_be_bytes(hi.try_into()?), + lo: u64::from_be_bytes(lo.try_into()?), + }) + } + + (ScType::I128, Value::String(s)) => { + let val: i128 = i128::from_str(s) + .map(Into::into) + .map_err(|_| Error::InvalidValue(Some(t.clone())))?; + let bytes = val.to_be_bytes(); + let (hi, lo) = bytes.split_at(8); + ScVal::I128(Int128Parts { + hi: i64::from_be_bytes(hi.try_into()?), + lo: u64::from_be_bytes(lo.try_into()?), + }) + } + + // Number parsing + (ScType::U256, Value::String(s)) => { + let (hi, lo) = ethnum::U256::from_str_prefixed(s)?.into_words(); + let hi_bytes = hi.to_be_bytes(); + let (hi_hi, hi_lo) = hi_bytes.split_at(8); + let lo_bytes = lo.to_be_bytes(); + let (lo_hi, lo_lo) = lo_bytes.split_at(8); + ScVal::U256(UInt256Parts { + hi_hi: u64::from_be_bytes(hi_hi.try_into()?), + hi_lo: u64::from_be_bytes(hi_lo.try_into()?), + lo_hi: u64::from_be_bytes(lo_hi.try_into()?), + lo_lo: u64::from_be_bytes(lo_lo.try_into()?), + }) + } + (ScType::I256, Value::String(s)) => { + let (hi, lo) = ethnum::I256::from_str_prefixed(s)?.into_words(); + let hi_bytes = hi.to_be_bytes(); + let (hi_hi, hi_lo) = hi_bytes.split_at(8); + let lo_bytes = lo.to_be_bytes(); + let (lo_hi, lo_lo) = lo_bytes.split_at(8); + ScVal::I256(Int256Parts { + hi_hi: i64::from_be_bytes(hi_hi.try_into()?), + hi_lo: u64::from_be_bytes(hi_lo.try_into()?), + lo_hi: u64::from_be_bytes(lo_hi.try_into()?), + lo_lo: u64::from_be_bytes(lo_lo.try_into()?), + }) + } + + (ScType::I32, Value::Number(n)) => ScVal::I32( + n.as_i64() + .ok_or_else(|| Error::InvalidValue(Some(t.clone())))? + .try_into() + .map_err(|_| Error::InvalidValue(Some(t.clone())))?, + ), + (ScType::U32, Value::Number(n)) => ScVal::U32( + n.as_u64() + .ok_or_else(|| Error::InvalidValue(Some(t.clone())))? + .try_into() + .map_err(|_| Error::InvalidValue(Some(t.clone())))?, + ), + (ScType::I64, Value::Number(n)) => ScVal::I64( + n.as_i64() + .ok_or_else(|| Error::InvalidValue(Some(t.clone())))?, + ), + (ScType::U64 | ScType::Timepoint | ScType::Duration, Value::Number(n)) => ScVal::U64( + n.as_u64() + .ok_or_else(|| Error::InvalidValue(Some(t.clone())))?, + ), + + // Symbol parsing + (ScType::Symbol, Value::String(s)) => ScVal::Symbol(ScSymbol( + s.as_bytes() + .try_into() + .map_err(|_| Error::InvalidValue(Some(t.clone())))?, + )), + + (ScType::Address, Value::String(s)) => sc_address_from_json(s)?, + + // Bytes parsing + (bytes @ ScType::BytesN(_), Value::Number(n)) => { + from_json_primitives(&Value::String(format!("{n}")), bytes)? + } + (ScType::BytesN(bytes), Value::String(s)) => ScVal::Bytes(ScBytes({ + if bytes.n == 32 { + // Bytes might be a strkey, try parsing it as one. Contract devs should use the new + // proper Address type, but for backwards compatibility some contracts might use a + // BytesN<32> to represent an Address. + if let Ok(key) = sc_address_from_json(s) { + return Ok(key); + } + } + // Bytes are not an address, just parse as a hex string + utils::padded_hex_from_str(s, bytes.n as usize) + .map_err(|_| Error::InvalidValue(Some(t.clone())))? + .try_into() + .map_err(|_| Error::InvalidValue(Some(t.clone())))? + })), + (ScType::Bytes, Value::Number(n)) => { + from_json_primitives(&Value::String(format!("{n}")), &ScType::Bytes)? + } + (ScType::Bytes, Value::String(s)) => ScVal::Bytes( + hex::decode(s) + .map_err(|_| Error::InvalidValue(Some(t.clone())))? + .try_into() + .map_err(|_| Error::InvalidValue(Some(t.clone())))?, + ), + (ScType::Bytes | ScType::BytesN(_), Value::Array(raw)) => { + let b: Result, Error> = raw + .iter() + .map(|item| { + item.as_u64() + .ok_or_else(|| Error::InvalidValue(Some(t.clone())))? + .try_into() + .map_err(|_| Error::InvalidValue(Some(t.clone()))) + }) + .collect(); + let converted: BytesM<{ u32::MAX }> = b?.try_into().map_err(Error::Xdr)?; + ScVal::Bytes(ScBytes(converted)) + } + + (ScType::String, Value::String(s)) => ScVal::String(ScString( + s.try_into() + .map_err(|_| Error::InvalidValue(Some(t.clone())))?, + )), + // Todo make proper error Which shouldn't exist + (_, raw) => serde_json::from_value(raw.clone())?, + }; + Ok(val) +} + +/// # Errors +/// +/// Might return an error +pub fn to_string(v: &ScVal) -> Result { + #[allow(clippy::match_same_arms)] + Ok(match v { + // If symbols are a top-level thing we omit the wrapping quotes + // TODO: Decide if this is a good idea or not. + ScVal::Symbol(v) => std::str::from_utf8(v.as_slice()) + .map_err(|_| Error::InvalidValue(Some(ScType::Symbol)))? + .to_string(), + ScVal::LedgerKeyContractInstance => "LedgerKeyContractInstance".to_string(), + _ => serde_json::to_string(&to_json(v)?)?, + }) +} + +/// # Errors +/// +/// Might return an error +#[allow(clippy::too_many_lines)] +pub fn to_json(v: &ScVal) -> Result { + #[allow(clippy::match_same_arms)] + let val: Value = match v { + ScVal::Bool(b) => Value::Bool(*b), + ScVal::Void => Value::Null, + ScVal::LedgerKeyContractInstance => Value::String("LedgerKeyContractInstance".to_string()), + ScVal::U64(v) => Value::Number(serde_json::Number::from(*v)), + ScVal::Timepoint(tp) => Value::Number(serde_json::Number::from(tp.0)), + ScVal::Duration(d) => Value::Number(serde_json::Number::from(d.0)), + ScVal::I64(v) => Value::Number(serde_json::Number::from(*v)), + ScVal::U32(v) => Value::Number(serde_json::Number::from(*v)), + ScVal::I32(v) => Value::Number(serde_json::Number::from(*v)), + ScVal::Symbol(v) => Value::String( + std::str::from_utf8(v.as_slice()) + .map_err(|_| Error::InvalidValue(Some(ScType::Symbol)))? + .to_string(), + ), + ScVal::String(v) => Value::String( + std::str::from_utf8(v.as_slice()) + .map_err(|_| Error::InvalidValue(Some(ScType::Symbol)))? + .to_string(), + ), + ScVal::Vec(v) => { + let values: Result, Error> = v.as_ref().map_or_else( + || Ok(vec![]), + |v| { + v.iter() + .map(|item| -> Result { to_json(item) }) + .collect() + }, + ); + Value::Array(values?) + } + ScVal::Map(None) => Value::Object(serde_json::Map::with_capacity(0)), + ScVal::Map(Some(v)) => { + // TODO: What do we do if the key is not a string? + let mut m = serde_json::Map::::with_capacity(v.len()); + for ScMapEntry { key, val } in v.iter() { + let k: String = to_string(key)?; + let v: Value = to_json(val).map_err(|_| Error::InvalidValue(None))?; + m.insert(k, v); + } + Value::Object(m) + } + ScVal::Bytes(v) => Value::String(to_lower_hex(v.as_slice())), + ScVal::Address(v) => sc_address_to_json(v), + ScVal::U128(n) => { + let hi: [u8; 8] = n.hi.to_be_bytes(); + let lo: [u8; 8] = n.lo.to_be_bytes(); + let bytes = [hi, lo].concat(); + // Always output u128s as strings + let v = u128::from_be_bytes( + bytes + .as_slice() + .try_into() + .map_err(|_| Error::InvalidValue(Some(ScType::I128)))?, + ) + .to_string(); + Value::String(v) + } + ScVal::I128(n) => { + let hi: [u8; 8] = n.hi.to_be_bytes(); + let lo: [u8; 8] = n.lo.to_be_bytes(); + let bytes = [hi, lo].concat(); + // Always output u128s as strings + let v = i128::from_be_bytes( + bytes + .as_slice() + .try_into() + .map_err(|_| Error::InvalidValue(Some(ScType::I128)))?, + ) + .to_string(); + Value::String(v) + } + ScVal::U256(u256parts) => { + let bytes = [ + u256parts.hi_hi.to_be_bytes(), + u256parts.hi_lo.to_be_bytes(), + u256parts.lo_hi.to_be_bytes(), + u256parts.lo_lo.to_be_bytes(), + ] + .concat(); + let u256 = ethnum::U256::from_be_bytes( + bytes + .as_slice() + .try_into() + .map_err(|_| Error::InvalidValue(Some(ScType::U256)))?, + ); + Value::String(u256.to_string()) + } + ScVal::I256(i256parts) => { + let bytes = [ + i256parts.hi_hi.to_be_bytes(), + i256parts.hi_lo.to_be_bytes(), + i256parts.lo_hi.to_be_bytes(), + i256parts.lo_lo.to_be_bytes(), + ] + .concat(); + let i256 = ethnum::I256::from_be_bytes( + bytes + .as_slice() + .try_into() + .map_err(|_| Error::InvalidValue(Some(ScType::I256)))?, + ); + Value::String(i256.to_string()) + } + ScVal::ContractInstance(ScContractInstance { + executable: ContractExecutable::Wasm(hash), + .. + }) => json!({ "hash": hash }), + ScVal::ContractInstance(ScContractInstance { + executable: ContractExecutable::StellarAsset, + .. + }) => json!({"SAC": true}), + ScVal::LedgerKeyNonce(ScNonceKey { nonce }) => { + Value::Number(serde_json::Number::from(*nonce)) + } + ScVal::Error(e) => serde_json::to_value(e)?, + }; + Ok(val) +} + +fn sc_address_to_json(v: &ScAddress) -> Value { + match v { + ScAddress::Account(AccountId(PublicKey::PublicKeyTypeEd25519(Uint256(k)))) => { + Value::String(stellar_strkey::ed25519::PublicKey(*k).to_string()) + } + ScAddress::Contract(Hash(h)) => Value::String(stellar_strkey::Contract(*h).to_string()), + } +} + +fn sc_address_from_json(s: &str) -> Result { + stellar_strkey::Strkey::from_string(s) + .map_err(|_| Error::InvalidValue(Some(ScType::Address))) + .map(|parsed| match parsed { + stellar_strkey::Strkey::PublicKeyEd25519(p) => Some(ScVal::Address( + ScAddress::Account(AccountId(PublicKey::PublicKeyTypeEd25519(Uint256(p.0)))), + )), + stellar_strkey::Strkey::Contract(c) => { + Some(ScVal::Address(ScAddress::Contract(Hash(c.0)))) + } + _ => None, + })? + .ok_or(Error::InvalidValue(Some(ScType::Address))) +} + +fn to_lower_hex(bytes: &[u8]) -> String { + let mut res = String::with_capacity(bytes.len()); + for b in bytes { + res.push_str(&format!("{b:02x}")); + } + res +} + +impl Spec { + #[must_use] + pub fn arg_value_name(&self, type_: &ScType, depth: usize) -> Option { + match type_ { + ScType::U64 => Some("u64".to_string()), + ScType::I64 => Some("i64".to_string()), + ScType::U128 => Some("u128".to_string()), + ScType::I128 => Some("i128".to_string()), + ScType::U32 => Some("u32".to_string()), + ScType::I32 => Some("i32".to_string()), + ScType::Bool => Some("bool".to_string()), + ScType::Symbol => Some("Symbol".to_string()), + ScType::Error => Some("Error".to_string()), + ScType::Bytes => Some("hex_bytes".to_string()), + ScType::Address => Some("Address".to_string()), + ScType::Void => Some("Null".to_string()), + ScType::Timepoint => Some("Timepoint".to_string()), + ScType::Duration => Some("Duration".to_string()), + ScType::U256 => Some("u256".to_string()), + ScType::I256 => Some("i256".to_string()), + ScType::String => Some("String".to_string()), + ScType::Option(val) => { + let ScSpecTypeOption { value_type } = val.as_ref(); + let inner = self.arg_value_name(value_type.as_ref(), depth + 1)?; + Some(format!("Option<{inner}>")) + } + ScType::Vec(val) => { + let ScSpecTypeVec { element_type } = val.as_ref(); + let inner = self.arg_value_name(element_type.as_ref(), depth + 1)?; + Some(format!("Array<{inner}>")) + } + ScType::Result(val) => { + let ScSpecTypeResult { + ok_type, + error_type, + } = val.as_ref(); + let ok = self.arg_value_name(ok_type.as_ref(), depth + 1)?; + let error = self.arg_value_name(error_type.as_ref(), depth + 1)?; + Some(format!("Result<{ok}, {error}>")) + } + ScType::Tuple(val) => { + let ScSpecTypeTuple { value_types } = val.as_ref(); + let names = value_types + .iter() + .map(|t| self.arg_value_name(t, depth + 1)) + .collect::>>()? + .join(", "); + Some(format!("Tuple<{names}>")) + } + ScType::Map(val) => { + let ScSpecTypeMap { + key_type, + value_type, + } = val.as_ref(); + let (key, val) = ( + self.arg_value_name(key_type.as_ref(), depth + 1)?, + self.arg_value_name(value_type.as_ref(), depth + 1)?, + ); + Some(format!("Map<{key}, {val}>")) + } + ScType::BytesN(t) => Some(format!("{}_hex_bytes", t.n)), + ScType::Udt(ScSpecTypeUdt { name }) => { + match self.find(&name.to_utf8_string_lossy()).ok()? { + ScSpecEntry::UdtStructV0(ScSpecUdtStructV0 { fields, .. }) + if fields + .first() + .map(|f| f.name.to_utf8_string_lossy() == "0") + .unwrap_or_default() => + { + let fields = fields + .iter() + .map(|t| self.arg_value_name(&t.type_, depth + 1)) + .collect::>>()? + .join(", "); + Some(format!("[{fields}]")) + } + ScSpecEntry::UdtStructV0(strukt) => self.arg_value_udt(strukt, depth), + ScSpecEntry::UdtUnionV0(union) => self.arg_value_union(union, depth), + ScSpecEntry::UdtEnumV0(enum_) => Some(arg_value_enum(enum_)), + ScSpecEntry::FunctionV0(_) | ScSpecEntry::UdtErrorEnumV0(_) => None, + } + } + // No specific value name for these yet. + ScType::Val => None, + } + } + + fn arg_value_udt(&self, strukt: &ScSpecUdtStructV0, depth: usize) -> Option { + let inner = strukt + .fields + .iter() + .map(|f| (f.name.to_utf8_string_lossy(), &f.type_)) + .map(|(name, type_)| { + let type_ = self.arg_value_name(type_, depth + 1)?; + Some(format!("{name}: {type_}")) + }) + .collect::>>()? + .join(", "); + Some(format!("{{ {inner} }}")) + } + + fn arg_value_union(&self, union: &ScSpecUdtUnionV0, depth: usize) -> Option { + union + .cases + .iter() + .map(|f| { + Some(match f { + ScSpecUdtUnionCaseV0::VoidV0(ScSpecUdtUnionCaseVoidV0 { name, .. }) => { + name.to_utf8_string_lossy() + } + ScSpecUdtUnionCaseV0::TupleV0(ScSpecUdtUnionCaseTupleV0 { + name, + type_, + .. + }) => format!( + "{}({})", + name.to_utf8_string_lossy(), + type_ + .iter() + .map(|type_| self.arg_value_name(type_, depth + 1)) + .collect::>>()? + .join(",") + ), + }) + }) + .collect::>>() + .map(|v| v.join(" | ")) + } +} + +fn arg_value_enum(enum_: &ScSpecUdtEnumV0) -> String { + enum_ + .cases + .iter() + .map(|case| case.value.to_string()) + .join(" | ") +} + +// Example implementation +impl Spec { + #[must_use] + pub fn example(&self, type_: &ScType) -> Option { + match type_ { + ScType::U64 => Some("42".to_string()), + ScType::I64 => Some("-42".to_string()), + ScType::U128 => Some("\"1000\"".to_string()), + ScType::I128 => Some("\"-100\"".to_string()), + ScType::U32 => Some("1".to_string()), + ScType::I32 => Some("-1".to_string()), + ScType::Bool => Some("true".to_string()), + ScType::Symbol => Some("\"hello\"".to_string()), + ScType::Error => Some("Error".to_string()), + ScType::Bytes => Some("\"beefface123\"".to_string()), + ScType::Address => { + Some("\"GDIY6AQQ75WMD4W46EYB7O6UYMHOCGQHLAQGQTKHDX4J2DYQCHVCR4W4\"".to_string()) + } + ScType::Void => Some("null".to_string()), + ScType::Timepoint => Some("1234".to_string()), + ScType::Duration => Some("9999".to_string()), + ScType::U256 => Some("\"2000\"".to_string()), + ScType::I256 => Some("\"-20000\"".to_string()), + ScType::String => Some("\"hello world\"".to_string()), + ScType::Option(val) => { + let ScSpecTypeOption { value_type } = val.as_ref(); + self.example(value_type.as_ref()) + } + ScType::Vec(val) => { + let ScSpecTypeVec { element_type } = val.as_ref(); + let inner = self.example(element_type.as_ref())?; + Some(format!("[ {inner} ]")) + } + ScType::Result(val) => { + let ScSpecTypeResult { + ok_type, + error_type, + } = val.as_ref(); + let ok = self.example(ok_type.as_ref())?; + let error = self.example(error_type.as_ref())?; + Some(format!("Result<{ok}, {error}>")) + } + ScType::Tuple(val) => { + let ScSpecTypeTuple { value_types } = val.as_ref(); + let names = value_types + .iter() + .map(|t| self.example(t)) + .collect::>>()? + .join(", "); + Some(format!("[{names}]")) + } + ScType::Map(map) => { + let ScSpecTypeMap { + key_type, + value_type, + } = map.as_ref(); + let (mut key, val) = ( + self.example(key_type.as_ref())?, + self.example(value_type.as_ref())?, + ); + if !matches!(key_type.as_ref(), ScType::Symbol) { + key = format!("\"{key}\""); + } + Some(format!("{{ {key}: {val} }}")) + } + ScType::BytesN(n) => { + let n = n.n as usize; + let res = if n % 2 == 0 { + "ef".repeat(n) + } else { + let mut s = "ef".repeat(n - 1); + s.push('e'); + s + }; + Some(format!("\"{res}\"")) + } + ScType::Udt(ScSpecTypeUdt { name }) => { + self.example_udts(name.to_utf8_string_lossy().as_ref()) + } + // No specific value name for these yet. + ScType::Val => None, + } + } + + fn example_udts(&self, name: &str) -> Option { + match self.find(name).ok() { + Some(ScSpecEntry::UdtStructV0(strukt)) => { + // Check if a tuple strukt + if !strukt.fields.is_empty() && strukt.fields[0].name.to_utf8_string_lossy() == "0" + { + let value_types = strukt + .fields + .iter() + .map(|f| f.type_.clone()) + .collect::>() + .try_into() + .ok()?; + return self.example(&ScType::Tuple(Box::new(ScSpecTypeTuple { value_types }))); + } + let inner = strukt + .fields + .iter() + .map(|f| (f.name.to_utf8_string_lossy(), &f.type_)) + .map(|(name, type_)| { + let type_ = self.example(type_)?; + let name = format!(r#""{name}""#); + Some(format!("{name}: {type_}")) + }) + .collect::>>()? + .join(", "); + Some(format!(r#"{{ {inner} }}"#)) + } + Some(ScSpecEntry::UdtUnionV0(union)) => self.example_union(union), + Some(ScSpecEntry::UdtEnumV0(enum_)) => { + enum_.cases.iter().next().map(|c| c.value.to_string()) + } + Some(ScSpecEntry::FunctionV0(_) | ScSpecEntry::UdtErrorEnumV0(_)) | None => None, + } + } + + fn example_union(&self, union: &ScSpecUdtUnionV0) -> Option { + let res = union + .cases + .iter() + .map(|case| match case { + ScSpecUdtUnionCaseV0::VoidV0(ScSpecUdtUnionCaseVoidV0 { name, .. }) => { + Some(format!("\"{}\"", name.to_utf8_string_lossy())) + } + ScSpecUdtUnionCaseV0::TupleV0(ScSpecUdtUnionCaseTupleV0 { + name, type_, .. + }) => { + if type_.len() == 1 { + let single = self.example(&type_[0])?; + Some(format!("{{\"{}\":{single}}}", name.to_utf8_string_lossy())) + } else { + let names = type_ + .iter() + .map(|t| self.example(t)) + .collect::>>()? + .join(", "); + Some(format!("{{\"{}\":[{names}]}}", name.to_utf8_string_lossy())) + } + } + }) + .collect::>>()?; + Some(res.join("|")) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use stellar_xdr::curr::ScSpecTypeBytesN; + + #[test] + fn from_json_primitives_bytesn() { + // TODO: Add test for parsing addresses + + // Check it parses hex-encoded bytes + let b = from_json_primitives( + &Value::String("beefface".to_string()), + &ScType::BytesN(ScSpecTypeBytesN { n: 4 }), + ) + .unwrap(); + assert_eq!( + b, + ScVal::Bytes(ScBytes(vec![0xbe, 0xef, 0xfa, 0xce].try_into().unwrap())) + ); + + // Check it parses hex-encoded bytes when they are all numbers. Normally the json would + // interpret the CLI arg as a number, so we need a special case there. + let b = from_json_primitives( + &Value::Number(4554.into()), + &ScType::BytesN(ScSpecTypeBytesN { n: 2 }), + ) + .unwrap(); + assert_eq!( + b, + ScVal::Bytes(ScBytes(vec![0x45, 0x54].try_into().unwrap())) + ); + } + + #[test] + fn from_json_primitives_bytes() { + // Check it parses hex-encoded bytes + let b = + from_json_primitives(&Value::String("beefface".to_string()), &ScType::Bytes).unwrap(); + assert_eq!( + b, + ScVal::Bytes(ScBytes(vec![0xbe, 0xef, 0xfa, 0xce].try_into().unwrap())) + ); + + // Check it parses hex-encoded bytes when they are all numbers. Normally the json would + // interpret the CLI arg as a number, so we need a special case there. + let b = from_json_primitives(&Value::Number(4554.into()), &ScType::Bytes).unwrap(); + assert_eq!( + b, + ScVal::Bytes(ScBytes(vec![0x45, 0x54].try_into().unwrap())) + ); + } + + #[test] + fn test_sc_address_from_json_strkey() { + // All zero contract address + match sc_address_from_json("CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4") { + Ok(addr) => assert_eq!(addr, ScVal::Address(ScAddress::Contract(Hash([0; 32])))), + Err(e) => panic!("Unexpected error: {e}"), + } + + // Real contract address + match sc_address_from_json("CA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAXE") { + Ok(addr) => assert_eq!( + addr, + ScVal::Address(ScAddress::Contract( + [ + 0x36, 0x3e, 0xaa, 0x38, 0x67, 0x84, 0x1f, 0xba, 0xd0, 0xf4, 0xed, 0x88, + 0xc7, 0x79, 0xe4, 0xfe, 0x66, 0xe5, 0x6a, 0x24, 0x70, 0xdc, 0x98, 0xc0, + 0xec, 0x9c, 0x07, 0x3d, 0x05, 0xc7, 0xb1, 0x03, + ] + .try_into() + .unwrap() + )) + ), + Err(e) => panic!("Unexpected error: {e}"), + } + + // All zero user account address + match sc_address_from_json("GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF") { + Ok(addr) => assert_eq!( + addr, + ScVal::Address(ScAddress::Account(AccountId( + PublicKey::PublicKeyTypeEd25519([0; 32].try_into().unwrap()) + ))) + ), + Err(e) => panic!("Unexpected error: {e}"), + } + + // Real user account address + match sc_address_from_json("GA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQHES5") { + Ok(addr) => assert_eq!( + addr, + ScVal::Address(ScAddress::Account(AccountId( + PublicKey::PublicKeyTypeEd25519( + [ + 0x36, 0x3e, 0xaa, 0x38, 0x67, 0x84, 0x1f, 0xba, 0xd0, 0xf4, 0xed, 0x88, + 0xc7, 0x79, 0xe4, 0xfe, 0x66, 0xe5, 0x6a, 0x24, 0x70, 0xdc, 0x98, 0xc0, + 0xec, 0x9c, 0x07, 0x3d, 0x05, 0xc7, 0xb1, 0x03, + ] + .try_into() + .unwrap() + ) + ))) + ), + Err(e) => panic!("Unexpected error: {e}"), + } + } +} diff --git a/cmd/crates/soroban-spec-tools/src/utils.rs b/cmd/crates/soroban-spec-tools/src/utils.rs new file mode 100644 index 00000000..66b153a1 --- /dev/null +++ b/cmd/crates/soroban-spec-tools/src/utils.rs @@ -0,0 +1,294 @@ +use base64::{engine::general_purpose::STANDARD as base64, Engine as _}; +use hex::FromHexError; +use std::{ + fmt::Display, + io::{self, Cursor}, +}; + +use stellar_xdr::curr::{ + Limited, Limits, ReadXdr, ScEnvMetaEntry, ScMetaEntry, ScMetaV0, ScSpecEntry, ScSpecFunctionV0, + ScSpecUdtEnumV0, ScSpecUdtErrorEnumV0, ScSpecUdtStructV0, ScSpecUdtUnionV0, StringM, +}; + +pub struct ContractSpec { + pub env_meta_base64: Option, + pub env_meta: Vec, + pub meta_base64: Option, + pub meta: Vec, + pub spec_base64: Option, + pub spec: Vec, +} + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("reading file {filepath}: {error}")] + CannotReadContractFile { + filepath: std::path::PathBuf, + error: io::Error, + }, + #[error("cannot parse wasm file {file}: {error}")] + CannotParseWasm { + file: std::path::PathBuf, + error: wasmparser::BinaryReaderError, + }, + #[error("xdr processing error: {0}")] + Xdr(#[from] stellar_xdr::curr::Error), + + #[error(transparent)] + Parser(#[from] wasmparser::BinaryReaderError), +} + +impl ContractSpec { + pub fn new(bytes: &[u8]) -> Result { + let mut env_meta: Option<&[u8]> = None; + let mut meta: Option<&[u8]> = None; + let mut spec: Option<&[u8]> = None; + for payload in wasmparser::Parser::new(0).parse_all(bytes) { + let payload = payload?; + if let wasmparser::Payload::CustomSection(section) = payload { + let out = match section.name() { + "contractenvmetav0" => &mut env_meta, + "contractmetav0" => &mut meta, + "contractspecv0" => &mut spec, + _ => continue, + }; + *out = Some(section.data()); + }; + } + + let mut env_meta_base64 = None; + let env_meta = if let Some(env_meta) = env_meta { + env_meta_base64 = Some(base64.encode(env_meta)); + let cursor = Cursor::new(env_meta); + let mut read = Limited::new(cursor, Limits::none()); + ScEnvMetaEntry::read_xdr_iter(&mut read).collect::, _>>()? + } else { + vec![] + }; + + let mut meta_base64 = None; + let meta = if let Some(meta) = meta { + meta_base64 = Some(base64.encode(meta)); + let cursor = Cursor::new(meta); + let mut read = Limited::new(cursor, Limits::none()); + ScMetaEntry::read_xdr_iter(&mut read).collect::, _>>()? + } else { + vec![] + }; + + let mut spec_base64 = None; + let spec = if let Some(spec) = spec { + spec_base64 = Some(base64.encode(spec)); + let cursor = Cursor::new(spec); + let mut read = Limited::new(cursor, Limits::none()); + ScSpecEntry::read_xdr_iter(&mut read).collect::, _>>()? + } else { + vec![] + }; + + Ok(ContractSpec { + env_meta_base64, + env_meta, + meta_base64, + meta, + spec_base64, + spec, + }) + } +} + +impl Display for ContractSpec { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(env_meta) = &self.env_meta_base64 { + writeln!(f, "Env Meta: {env_meta}")?; + for env_meta_entry in &self.env_meta { + match env_meta_entry { + ScEnvMetaEntry::ScEnvMetaKindInterfaceVersion(v) => { + writeln!(f, " • Interface Version: {v}")?; + } + } + } + writeln!(f)?; + } else { + writeln!(f, "Env Meta: None\n")?; + } + + if let Some(_meta) = &self.meta_base64 { + writeln!(f, "Contract Meta:")?; + for meta_entry in &self.meta { + match meta_entry { + ScMetaEntry::ScMetaV0(ScMetaV0 { key, val }) => { + writeln!(f, " • {key}: {val}")?; + } + } + } + writeln!(f)?; + } else { + writeln!(f, "Contract Meta: None\n")?; + } + + if let Some(_spec_base64) = &self.spec_base64 { + writeln!(f, "Contract Spec:")?; + for spec_entry in &self.spec { + match spec_entry { + ScSpecEntry::FunctionV0(func) => write_func(f, func)?, + ScSpecEntry::UdtUnionV0(udt) => write_union(f, udt)?, + ScSpecEntry::UdtStructV0(udt) => write_struct(f, udt)?, + ScSpecEntry::UdtEnumV0(udt) => write_enum(f, udt)?, + ScSpecEntry::UdtErrorEnumV0(udt) => write_error(f, udt)?, + } + } + } else { + writeln!(f, "Contract Spec: None")?; + } + Ok(()) + } +} + +fn write_func(f: &mut std::fmt::Formatter<'_>, func: &ScSpecFunctionV0) -> std::fmt::Result { + writeln!(f, " • Function: {}", func.name.to_utf8_string_lossy())?; + if func.doc.len() > 0 { + writeln!( + f, + " Docs: {}", + &indent(&func.doc.to_utf8_string_lossy(), 11).trim() + )?; + } + writeln!( + f, + " Inputs: {}", + indent(&format!("{:#?}", func.inputs), 5).trim() + )?; + writeln!( + f, + " Output: {}", + indent(&format!("{:#?}", func.outputs), 5).trim() + )?; + writeln!(f)?; + Ok(()) +} + +fn write_union(f: &mut std::fmt::Formatter<'_>, udt: &ScSpecUdtUnionV0) -> std::fmt::Result { + writeln!(f, " • Union: {}", format_name(&udt.lib, &udt.name))?; + if udt.doc.len() > 0 { + writeln!( + f, + " Docs: {}", + indent(&udt.doc.to_utf8_string_lossy(), 10).trim() + )?; + } + writeln!(f, " Cases:")?; + for case in udt.cases.iter() { + writeln!(f, " • {}", indent(&format!("{case:#?}"), 8).trim())?; + } + writeln!(f)?; + Ok(()) +} + +fn write_struct(f: &mut std::fmt::Formatter<'_>, udt: &ScSpecUdtStructV0) -> std::fmt::Result { + writeln!(f, " • Struct: {}", format_name(&udt.lib, &udt.name))?; + if udt.doc.len() > 0 { + writeln!( + f, + " Docs: {}", + indent(&udt.doc.to_utf8_string_lossy(), 10).trim() + )?; + } + writeln!(f, " Fields:")?; + for field in udt.fields.iter() { + writeln!( + f, + " • {}: {}", + field.name.to_utf8_string_lossy(), + indent(&format!("{:#?}", field.type_), 8).trim() + )?; + if field.doc.len() > 0 { + writeln!(f, "{}", indent(&format!("{:#?}", field.doc), 8))?; + } + } + writeln!(f)?; + Ok(()) +} + +fn write_enum(f: &mut std::fmt::Formatter<'_>, udt: &ScSpecUdtEnumV0) -> std::fmt::Result { + writeln!(f, " • Enum: {}", format_name(&udt.lib, &udt.name))?; + if udt.doc.len() > 0 { + writeln!( + f, + " Docs: {}", + indent(&udt.doc.to_utf8_string_lossy(), 10).trim() + )?; + } + writeln!(f, " Cases:")?; + for case in udt.cases.iter() { + writeln!(f, " • {}", indent(&format!("{case:#?}"), 8).trim())?; + } + writeln!(f)?; + Ok(()) +} + +fn write_error(f: &mut std::fmt::Formatter<'_>, udt: &ScSpecUdtErrorEnumV0) -> std::fmt::Result { + writeln!(f, " • Error: {}", format_name(&udt.lib, &udt.name))?; + if udt.doc.len() > 0 { + writeln!( + f, + " Docs: {}", + indent(&udt.doc.to_utf8_string_lossy(), 10).trim() + )?; + } + writeln!(f, " Cases:")?; + for case in udt.cases.iter() { + writeln!(f, " • {}", indent(&format!("{case:#?}"), 8).trim())?; + } + writeln!(f)?; + Ok(()) +} + +fn indent(s: &str, n: usize) -> String { + let pad = " ".repeat(n); + s.lines() + .map(|line| format!("{pad}{line}")) + .collect::>() + .join("\n") +} + +fn format_name(lib: &StringM<80>, name: &StringM<60>) -> String { + if lib.len() > 0 { + format!( + "{}::{}", + lib.to_utf8_string_lossy(), + name.to_utf8_string_lossy() + ) + } else { + name.to_utf8_string_lossy() + } +} + +/// # Errors +/// +/// Might return an error +pub fn padded_hex_from_str(s: &str, n: usize) -> Result, FromHexError> { + if s.len() > n * 2 { + return Err(FromHexError::InvalidStringLength); + } + let mut decoded = vec![0u8; n]; + let padded = format!("{s:0>width$}", width = n * 2); + hex::decode_to_slice(padded, &mut decoded)?; + Ok(decoded) +} + +/// # Errors +/// +/// Might return an error +pub fn contract_id_from_str(contract_id: &str) -> Result<[u8; 32], stellar_strkey::DecodeError> { + stellar_strkey::Contract::from_string(contract_id) + .map(|strkey| strkey.0) + .or_else(|_| { + // strkey failed, try to parse it as a hex string, for backwards compatibility. + padded_hex_from_str(contract_id, 32) + .map_err(|_| stellar_strkey::DecodeError::Invalid)? + .try_into() + .map_err(|_| stellar_strkey::DecodeError::Invalid) + }) + .map_err(|_| stellar_strkey::DecodeError::Invalid) +} diff --git a/cmd/crates/soroban-test/Cargo.toml b/cmd/crates/soroban-test/Cargo.toml deleted file mode 100644 index 3f15e3b4..00000000 --- a/cmd/crates/soroban-test/Cargo.toml +++ /dev/null @@ -1,43 +0,0 @@ -[package] -name = "soroban-test" -description = "Soroban Test Framework" -homepage = "https://github.com/stellar/soroban-test" -repository = "https://github.com/stellar/soroban-test" -authors = ["Stellar Development Foundation "] -license = "Apache-2.0" -readme = "README.md" -version = "20.3.1" -edition = "2021" -rust-version.workspace = true -autobins = false -publish = false - - -[lib] -crate-type = ["rlib", "cdylib"] - - -[dependencies] -soroban-env-host = { workspace = true } -soroban-spec = { workspace = true } -soroban-spec-tools = { workspace = true } -soroban-ledger-snapshot = { workspace = true } -stellar-strkey = { workspace = true } -soroban-sdk = { workspace = true } -sep5 = { workspace = true } -soroban-cli = { workspace = true } - -thiserror = "1.0.31" -sha2 = "0.10.6" -assert_cmd = "2.0.4" -assert_fs = "1.0.7" -predicates = "2.1.5" -fs_extra = "1.3.0" - -[dev-dependencies] -serde_json = "1.0.93" -which = { workspace = true } -tokio = "1.28.1" - -[features] -integration = [] diff --git a/cmd/crates/soroban-test/README.md b/cmd/crates/soroban-test/README.md deleted file mode 100644 index 3f8cdc9f..00000000 --- a/cmd/crates/soroban-test/README.md +++ /dev/null @@ -1,54 +0,0 @@ -Soroban Test -============ - -Test framework wrapping Soroban CLI. - -Provides a way to run tests against a local sandbox; running against RPC endpoint _coming soon_. - - -Overview -======== - -- `TestEnv` is a test environment for running tests isolated from each other. -- `TestEnv::with_default` invokes a closure, which is passed a reference to a random `TestEnv`. -- `TestEnv::new_assert_cmd` creates an `assert_cmd::Command` for a given subcommand and sets the current - directory to be the same as `TestEnv`. -- `TestEnv::cmd` is a generic function which parses a command from a string. - Note, however, that it uses `shlex` to tokenize the string. This can cause issues - for commands which contain strings with `"`s. For example, `{"hello": "world"}` becomes - `{hello:world}`. For that reason it's recommended to use `TestEnv::cmd_arr` instead. -- `TestEnv::cmd_arr` is a generic function which takes an array of `&str` which is passed directly to clap. - This is the preferred way since it ensures no string parsing footguns. -- `TestEnv::invoke` a convenience function for using the invoke command. - - -Example -======= - -```rs -use soroban_test::{TestEnv, Wasm}; - -const WASM: &Wasm = &Wasm::Release("soroban_hello_world_contract"); -const FRIEND: &str = "friend"; - -#[test] -fn invoke() { - TestEnv::with_default(|workspace| { - assert_eq!( - format!("[\"Hello\",\"{FRIEND}\"]"), - workspace - .invoke(&[ - "--id", - "1", - "--wasm", - &WASM.path().to_string_lossy(), - "--", - "hello", - "--to", - FRIEND, - ]) - .unwrap() - ); - }); -} -``` diff --git a/cmd/crates/soroban-test/src/lib.rs b/cmd/crates/soroban-test/src/lib.rs deleted file mode 100644 index bda6ec42..00000000 --- a/cmd/crates/soroban-test/src/lib.rs +++ /dev/null @@ -1,229 +0,0 @@ -//! **Soroban Test** - Test framework for invoking Soroban externally. -//! -//! Currently soroban provides a mock test environment for writing unit tets. -//! -//! However, it does not provide a way to run tests against a local sandbox or rpc endpoint. -//! -//! ## Overview -//! -//! - `TestEnv` is a test environment for running tests isolated from each other. -//! - `TestEnv::with_default` invokes a closure, which is passed a reference to a random `TestEnv`. -//! - `TestEnv::new_assert_cmd` creates an `assert_cmd::Command` for a given subcommand and sets the current -//! directory to be the same as `TestEnv`. -//! - `TestEnv::cmd` is a generic function which parses a command from a string. -//! Note, however, that it uses `shlex` to tokenize the string. This can cause issues -//! for commands which contain strings with `"`s. For example, `{"hello": "world"}` becomes -//! `{hello:world}`. For that reason it's recommended to use `TestEnv::cmd_arr` instead. -//! - `TestEnv::cmd_arr` is a generic function which takes an array of `&str` which is passed directly to clap. -//! This is the preferred way since it ensures no string parsing footguns. -//! - `TestEnv::invoke` a convenience function for using the invoke command. -//! -#![allow( - clippy::missing_errors_doc, - clippy::must_use_candidate, - clippy::missing_panics_doc -)] -use std::{ffi::OsString, fmt::Display, path::Path}; - -use assert_cmd::{assert::Assert, Command}; -use assert_fs::{fixture::FixtureError, prelude::PathChild, TempDir}; -use fs_extra::dir::CopyOptions; - -use soroban_cli::{ - commands::{config, contract, contract::invoke, global, keys}, - CommandParser, Pwd, -}; - -mod wasm; -pub use wasm::Wasm; - -#[derive(thiserror::Error, Debug)] -pub enum Error { - #[error(transparent)] - TempDir(#[from] FixtureError), - - #[error(transparent)] - FsError(#[from] fs_extra::error::Error), - - #[error(transparent)] - Invoke(#[from] invoke::Error), -} - -/// A `TestEnv` is a contained process for a specific test, with its own ENV and -/// its own `TempDir` where it will save test-specific configuration. -pub struct TestEnv { - pub temp_dir: TempDir, -} - -impl Default for TestEnv { - fn default() -> Self { - Self::new().unwrap() - } -} - -impl TestEnv { - /// Execute a closure which is passed a reference to the `TestEnv`. - /// `TempDir` implements the `Drop` trait ensuring that the temporary directory - /// it creates is deleted when the `TestEnv` is dropped. This pattern ensures - /// that the `TestEnv` cannot be dropped by the closure. For this reason, it's - /// recommended to use `TempDir::with_default` instead of `new` or `default`. - /// - /// ```rust,no_run - /// use soroban_test::TestEnv; - /// TestEnv::with_default(|env| { - /// env.new_assert_cmd("contract").args(&["invoke", "--id", "1", "--", "hello", "--world=world"]).assert().success(); - /// }); - /// ``` - /// - pub fn with_default(f: F) { - let test_env = TestEnv::default(); - f(&test_env); - } - pub fn new() -> Result { - let this = TempDir::new().map(|temp_dir| TestEnv { temp_dir })?; - std::env::set_var("XDG_CONFIG_HOME", this.temp_dir.as_os_str()); - this.new_assert_cmd("keys") - .arg("generate") - .arg("test") - .arg("-d") - .arg("--no-fund") - .assert(); - std::env::set_var("SOROBAN_ACCOUNT", "test"); - Ok(this) - } - - /// Create a new `assert_cmd::Command` for a given subcommand and set's the current directory - /// to be the internal `temp_dir`. - pub fn new_assert_cmd(&self, subcommand: &str) -> Command { - let mut this = Command::cargo_bin("soroban").unwrap_or_else(|_| Command::new("soroban")); - this.arg("-q"); - this.arg(subcommand); - this.current_dir(&self.temp_dir); - this - } - - /// Parses a `&str` into a command and sets the pwd to be the same as the current `TestEnv`. - /// Uses shlex under the hood and thus has issues parsing strings with embedded `"`s. - /// Thus `TestEnv::cmd_arr` is recommended to instead. - pub fn cmd>(&self, args: &str) -> T { - Self::cmd_with_pwd(args, self.dir()) - } - - /// Same as `TestEnv::cmd` but sets the pwd can be used instead of the current `TestEnv`. - pub fn cmd_with_pwd>(args: &str, pwd: &Path) -> T { - let args = format!("--config-dir={pwd:?} {args}"); - T::parse(&args).unwrap() - } - - /// Same as `TestEnv::cmd_arr` but sets the pwd can be used instead of the current `TestEnv`. - pub fn cmd_arr_with_pwd>(args: &[&str], pwd: &Path) -> T { - let mut cmds = vec!["--config-dir", pwd.to_str().unwrap()]; - cmds.extend_from_slice(args); - T::parse_arg_vec(&cmds).unwrap() - } - - /// Parse a command using an array of `&str`s, which passes the strings directly to clap - /// avoiding some issues `cmd` has with shlex. Use the current `TestEnv` pwd. - pub fn cmd_arr>(&self, args: &[&str]) -> T { - Self::cmd_arr_with_pwd(args, self.dir()) - } - - /// A convenience method for using the invoke command. - pub async fn invoke>(&self, command_str: &[I]) -> Result { - let cmd = contract::invoke::Cmd::parse_arg_vec( - &command_str - .iter() - .map(AsRef::as_ref) - .filter(|s| !s.is_empty()) - .collect::>(), - ) - .unwrap(); - self.invoke_cmd(cmd).await - } - - /// Invoke an already parsed invoke command - pub async fn invoke_cmd(&self, mut cmd: invoke::Cmd) -> Result { - cmd.set_pwd(self.dir()); - cmd.run_against_rpc_server(&global::Args { - locator: config::locator::Args { - global: false, - config_dir: None, - }, - filter_logs: Vec::default(), - quiet: false, - verbose: false, - very_verbose: false, - list: false, - }) - .await - } - - /// Reference to current directory of the `TestEnv`. - pub fn dir(&self) -> &TempDir { - &self.temp_dir - } - - /// Returns the public key corresponding to the test keys's `hd_path` - pub fn test_address(&self, hd_path: usize) -> String { - self.cmd::(&format!("--hd-path={hd_path}")) - .public_key() - .unwrap() - .to_string() - } - - /// Returns the private key corresponding to the test keys's `hd_path` - pub fn test_show(&self, hd_path: usize) -> String { - self.cmd::(&format!("--hd-path={hd_path}")) - .private_key() - .unwrap() - .to_string() - } - - /// Copy the contents of the current `TestEnv` to another `TestEnv` - pub fn fork(&self) -> Result { - let this = TestEnv::new()?; - self.save(&this.temp_dir)?; - Ok(this) - } - - /// Save the current state of the `TestEnv` to the given directory. - pub fn save(&self, dst: &Path) -> Result<(), Error> { - fs_extra::dir::copy(&self.temp_dir, dst, &CopyOptions::new())?; - Ok(()) - } -} - -pub fn temp_ledger_file() -> OsString { - TempDir::new() - .unwrap() - .child("ledger.json") - .as_os_str() - .into() -} - -pub trait AssertExt { - fn stdout_as_str(&self) -> String; -} - -impl AssertExt for Assert { - fn stdout_as_str(&self) -> String { - String::from_utf8(self.get_output().stdout.clone()) - .expect("failed to make str") - .trim() - .to_owned() - } -} -pub trait CommandExt { - fn json_arg(&mut self, j: A) -> &mut Self - where - A: Display; -} - -impl CommandExt for Command { - fn json_arg(&mut self, j: A) -> &mut Self - where - A: Display, - { - self.arg(OsString::from(j.to_string())) - } -} diff --git a/cmd/crates/soroban-test/src/wasm.rs b/cmd/crates/soroban-test/src/wasm.rs deleted file mode 100644 index d03114b9..00000000 --- a/cmd/crates/soroban-test/src/wasm.rs +++ /dev/null @@ -1,61 +0,0 @@ -use std::{fmt::Display, fs, path::PathBuf}; - -use sha2::{Digest, Sha256}; -use soroban_env_host::xdr; - -#[derive(thiserror::Error, Debug)] -pub enum Error { - #[error(transparent)] - Xdr(#[from] xdr::Error), -} - -pub enum Wasm<'a> { - Release(&'a str), - Custom(&'a str, &'a str), -} - -fn find_target_dir() -> Option { - let path = std::env::current_dir().unwrap(); - for parent in path.ancestors() { - let path = parent.join("target"); - if path.is_dir() { - return Some(path); - } - } - None -} - -impl Wasm<'_> { - /// # Panics - /// - /// # if not found - pub fn path(&self) -> PathBuf { - let path = find_target_dir().unwrap().join("wasm32-unknown-unknown"); - let mut path = match self { - Wasm::Release(name) => path.join("release").join(name), - Wasm::Custom(profile, name) => path.join(profile).join(name), - }; - path.set_extension("wasm"); - assert!(path.is_file(), "File not found: {}. run 'make build-test-wasms' to generate .wasm files before running this test", path.display()); - std::env::current_dir().unwrap().join(path) - } - - /// # Panics - /// - /// # if not found - pub fn bytes(&self) -> Vec { - fs::read(self.path()).unwrap() - } - - /// # Errors - /// - pub fn hash(&self) -> Result { - Ok(xdr::Hash(Sha256::digest(self.bytes()).into())) - } -} - -impl Display for Wasm<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.path().display()) - } -} diff --git a/cmd/crates/soroban-test/tests/fixtures/args/world b/cmd/crates/soroban-test/tests/fixtures/args/world deleted file mode 100644 index 04fea064..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/args/world +++ /dev/null @@ -1 +0,0 @@ -world \ No newline at end of file diff --git a/cmd/crates/soroban-test/tests/fixtures/hello/Cargo.lock b/cmd/crates/soroban-test/tests/fixtures/hello/Cargo.lock deleted file mode 100644 index dee1dea7..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/hello/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "soroban-hello" -version = "0.1.0" diff --git a/cmd/crates/soroban-test/tests/fixtures/hello/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/hello/Cargo.toml deleted file mode 100644 index faf41a44..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/hello/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "soroban-hello" -version = "20.3.1" -edition = "2021" -publish = false - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/cmd/crates/soroban-test/tests/fixtures/hello/src/main.rs b/cmd/crates/soroban-test/tests/fixtures/hello/src/main.rs deleted file mode 100644 index e7a11a96..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/hello/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-jsons/get-events.json b/cmd/crates/soroban-test/tests/fixtures/test-jsons/get-events.json deleted file mode 100644 index 1fe8e42f..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-jsons/get-events.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "latestLedger": 43601285, - "events": [ - { - "type": "contract", - "ledger": "40", - "ledgerClosedAt": "2022-12-14T01:01:20Z", - "contractId": "CBXL4AIUVYK7OLYYP4C5A3OLM2ZCXWLSDB2VZG2GI2YDJK4WD7A5LTHT", - "id": "0000000171798695937-0000000001", - "pagingToken": "0000000171798695937-0000000001", - "topic": [ - "AAAABQAAAAdDT1VOVEVSAA==", - "AAAABQAAAAlpbmNyZW1lbnQAAAA=" - ], - "value": "AAAAAQAAAAE=" - }, - { - "type": "system", - "ledger": "43601283", - "ledgerClosedAt": "2022-11-16T16:10:41Z", - "contractId": "CDR6QKTWZQYW6YUJ7UP7XXZRLWQPFRV6SWBLQS4ZQOSAF4BOUD77OO5Z", - "id": "0187266084548644865-0000000003", - "pagingToken": "187266084548644865-3", - "topic": [ - "AAAABQAAAAh0cmFuc2Zlcg==", - "AAAAAQB6Mcc=" - ], - "value": "AAAABQAAAApHaWJNb255UGxzAAA=" - }, - { - "type": "contract", - "ledger": "43601284", - "ledgerClosedAt": "2022-11-16T16:10:46Z", - "contractId": "CDR6QKTWZQYW6YUJ7UP7XXZRLWQPFRV6SWBLQS4ZQOSAF4BOUD77OO5Z", - "id": "0187266088843612161-0000000003", - "pagingToken": "187266088843612161-3", - "topic": [ - "AAAABQAAAAh0cmFuc2Zlcg==", - "AAAAAQB6Mcc=" - ], - "value": "AAAABQAAAApHaWJNb255UGxzAAA=" - }, - { - "type": "system", - "ledger": "43601285", - "ledgerClosedAt": "2022-11-16T16:10:51Z", - "contractId": "CCR6QKTWZQYW6YUJ7UP7XXZRLWQPFRV6SWBLQS4ZQOSAF4BOUD77OTE2", - "id": "0187266093138579457-0000000003", - "pagingToken": "187266093138579457-3", - "topic": [ - "AAAABQAAAAh0cmFuc2Zlcg==", - "AAAAAQB6Mcc=" - ], - "value": "AAAABQAAAApHaWJNb255UGxzAAA=" - } - ] -} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/Cargo.toml deleted file mode 100644 index 26844189..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "test_custom_types" -version = "20.3.1" -authors = ["Stellar Development Foundation "] -license = "Apache-2.0" -edition = "2021" -publish = false -rust-version.workspace = true - -[lib] -crate-type = ["cdylib", "rlib"] -doctest = false - -[dependencies] -soroban-sdk = { workspace = true } - -[dev-dependencies] -soroban-sdk = { workspace = true, features = ["testutils"]} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/src/lib.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/src/lib.rs deleted file mode 100644 index 9e4b442b..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/custom_type/src/lib.rs +++ /dev/null @@ -1,187 +0,0 @@ -#![no_std] -use soroban_sdk::{ - contract, contracterror, contractimpl, contracttype, symbol_short, vec, Address, Bytes, BytesN, - Env, Map, String, Symbol, Val, Vec, I256, U256, -}; - -#[contract] -pub struct Contract; - -/// This is from the rust doc above the struct Test -#[contracttype] -pub struct Test { - pub a: u32, - pub b: bool, - pub c: Symbol, -} - -#[contracttype] -pub enum SimpleEnum { - First, - Second, - Third, -} - -#[contracttype] -#[derive(Clone, Copy)] -// The `repr` attribute is here to specify the memory alignment for this type -#[repr(u32)] -pub enum RoyalCard { - // TODO: create the fields here for your `RoyalCard` type - Jack = 11, // delete this - Queen = 12, // delete this - King = 13, // delete this -} - -#[contracttype] -pub struct TupleStruct(Test, SimpleEnum); - -#[contracttype] -pub enum ComplexEnum { - Struct(Test), - Tuple(TupleStruct), - Enum(SimpleEnum), - Asset(Address, i128), - Void, -} - -#[contracterror] -#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] -#[repr(u32)] -pub enum Error { - /// Please provide an odd number - NumberMustBeOdd = 1, -} -#[contractimpl] -impl Contract { - pub fn hello(_env: Env, hello: Symbol) -> Symbol { - hello - } - - pub fn woid(_env: Env) { - // do nothing - } - - pub fn val(_env: Env) -> Val { - Val::default() - } - - pub fn u32_fail_on_even(_env: Env, u32_: u32) -> Result { - if u32_ % 2 == 1 { - Ok(u32_) - } else { - Err(Error::NumberMustBeOdd) - } - } - - pub fn u32_(_env: Env, u32_: u32) -> u32 { - u32_ - } - - pub fn i32_(_env: Env, i32_: i32) -> i32 { - i32_ - } - - pub fn i64_(_env: Env, i64_: i64) -> i64 { - i64_ - } - - /// Example contract method which takes a struct - pub fn strukt_hel(env: Env, strukt: Test) -> Vec { - vec![&env, symbol_short!("Hello"), strukt.c] - } - - pub fn strukt(_env: Env, strukt: Test) -> Test { - strukt - } - - pub fn simple(_env: Env, simple: SimpleEnum) -> SimpleEnum { - simple - } - - pub fn complex(_env: Env, complex: ComplexEnum) -> ComplexEnum { - complex - } - - pub fn addresse(_env: Env, addresse: Address) -> Address { - addresse - } - - pub fn bytes(_env: Env, bytes: Bytes) -> Bytes { - bytes - } - - pub fn bytes_n(_env: Env, bytes_n: BytesN<9>) -> BytesN<9> { - bytes_n - } - - pub fn card(_env: Env, card: RoyalCard) -> RoyalCard { - card - } - - pub fn boolean(_: Env, boolean: bool) -> bool { - boolean - } - - /// Negates a boolean value - pub fn not(_env: Env, boolean: bool) -> bool { - !boolean - } - - pub fn i128(_env: Env, i128: i128) -> i128 { - i128 - } - - pub fn u128(_env: Env, u128: u128) -> u128 { - u128 - } - - pub fn multi_args(_env: Env, a: u32, b: bool) -> u32 { - if b { - a - } else { - 0 - } - } - - pub fn map(_env: Env, map: Map) -> Map { - map - } - - pub fn vec(_env: Env, vec: Vec) -> Vec { - vec - } - - pub fn tuple(_env: Env, tuple: (Symbol, u32)) -> (Symbol, u32) { - tuple - } - - /// Example of an optional argument - pub fn option(_env: Env, option: Option) -> Option { - option - } - - pub fn u256(_env: Env, u256: U256) -> U256 { - u256 - } - - pub fn i256(_env: Env, i256: I256) -> I256 { - i256 - } - - pub fn string(_env: Env, string: String) -> String { - string - } - - pub fn tuple_strukt(_env: Env, tuple_strukt: TupleStruct) -> TupleStruct { - tuple_strukt - } - - // pub fn timepoint(_env: Env, timepoint: TimePoint) -> TimePoint { - // timepoint - // } - - // pub fn duration(_env: Env, duration: Duration) -> Duration { - // duration - // } -} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/hello_world/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/test-wasms/hello_world/Cargo.toml deleted file mode 100644 index 5a9bdf04..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/hello_world/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "test_hello_world" -version = "20.3.1" -authors = ["Stellar Development Foundation "] -license = "Apache-2.0" -edition = "2021" -publish = false -rust-version.workspace = true - -[lib] -crate-type = ["cdylib", "rlib"] -doctest = false - -[dependencies] -soroban-sdk = { workspace = true } - -[dev-dependencies] -soroban-sdk = { workspace = true, features = ["testutils"]} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/hello_world/src/lib.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/hello_world/src/lib.rs deleted file mode 100644 index 40006a1b..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/hello_world/src/lib.rs +++ /dev/null @@ -1,86 +0,0 @@ -#![no_std] -use soroban_sdk::{ - contract, contractimpl, log, symbol_short, vec, Address, BytesN, Env, String, Symbol, Vec, -}; - -const COUNTER: Symbol = symbol_short!("COUNTER"); - -#[contract] -pub struct Contract; - -#[contractimpl] -impl Contract { - pub fn hello(env: Env, world: Symbol) -> Vec { - vec![&env, symbol_short!("Hello"), world] - } - - pub fn world(env: Env, hello: Symbol) -> Vec { - vec![&env, symbol_short!("Hello"), hello] - } - - pub fn not(env: Env, boolean: bool) -> Vec { - vec![&env, !boolean] - } - - pub fn auth(env: Env, addr: Address, world: Symbol) -> Address { - addr.require_auth(); - // Emit test event - env.events().publish(("auth",), world); - - addr - } - - // get current count - pub fn get_count(env: Env) -> u32 { - env.storage().persistent().get(&COUNTER).unwrap_or(0) - } - - // increment count and return new one - pub fn inc(env: Env) -> u32 { - let mut count: u32 = env.storage().persistent().get(&COUNTER).unwrap_or(0); // Panic if the value of COUNTER is not u32. - log!(&env, "count: {}", count); - - // Increment the count. - count += 1; - - // Save the count. - env.storage().persistent().set(&COUNTER, &count); - count - } - - pub fn prng_u64_in_range(env: Env, low: u64, high: u64) -> u64 { - env.prng().gen_range(low..=high) - } - - pub fn upgrade_contract(env: Env, hash: BytesN<32>) { - env.deployer().update_current_contract_wasm(hash); - } - - #[allow(unused_variables)] - pub fn multi_word_cmd(env: Env, contract_owner: String) {} - /// Logs a string with `hello ` in front. - pub fn log(env: Env, str: Symbol) { - env.events().publish( - (Symbol::new(&env, "hello"), Symbol::new(&env, "")), - str.clone(), - ); - log!(&env, "hello {}", str); - } -} - -#[cfg(test)] -mod test { - use soroban_sdk::{symbol_short, vec, Env}; - - use crate::{Contract, ContractClient}; - - #[test] - fn test_hello() { - let env = Env::default(); - let contract_id = env.register_contract(None, Contract); - let client = ContractClient::new(&env, &contract_id); - let world = symbol_short!("world"); - let res = client.hello(&world); - assert_eq!(res, vec![&env, symbol_short!("Hello"), world]); - } -} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/Cargo.toml deleted file mode 100644 index f2465e22..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "test_swap" -version.workspace = true -authors = ["Stellar Development Foundation "] -license = "Apache-2.0" -edition = "2021" -publish = false -rust-version.workspace = true - -[lib] -crate-type = ["cdylib"] -doctest = false - -[dependencies] -soroban-sdk = { workspace = true } - -[dev_dependencies] -soroban-sdk = { workspace = true, features = ["testutils"] } diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/src/lib.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/src/lib.rs deleted file mode 100644 index 528b8422..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/src/lib.rs +++ /dev/null @@ -1,77 +0,0 @@ -//! This contract performs an atomic token swap between two parties. -//! Parties don't need to know each other and their signatures may be matched -//! off-chain. -//! This example demonstrates how multi-party authorization can be implemented. -#![no_std] - -use soroban_sdk::{contract, contractimpl, token, Address, Env, IntoVal}; - -#[contract] -pub struct AtomicSwapContract; - -#[contractimpl] -impl AtomicSwapContract { - // Swap token A for token B atomically. Settle for the minimum requested price - // for each party (this is an arbitrary choice; both parties could have - // received the full amount as well). - pub fn swap( - env: Env, - a: Address, - b: Address, - token_a: Address, - token_b: Address, - amount_a: i128, - min_b_for_a: i128, - amount_b: i128, - min_a_for_b: i128, - ) { - // Verify preconditions on the minimum price for both parties. - if amount_b < min_b_for_a { - panic!("not enough token B for token A"); - } - if amount_a < min_a_for_b { - panic!("not enough token A for token B"); - } - // Require authorization for a subset of arguments specific to a party. - // Notice, that arguments are symmetric - there is no difference between - // `a` and `b` in the call and hence their signatures can be used - // either for `a` or for `b` role. - a.require_auth_for_args( - (token_a.clone(), token_b.clone(), amount_a, min_b_for_a).into_val(&env), - ); - b.require_auth_for_args( - (token_b.clone(), token_a.clone(), amount_b, min_a_for_b).into_val(&env), - ); - - // Perform the swap by moving tokens from a to b and from b to a. - move_token(&env, &token_a, &a, &b, amount_a, min_a_for_b); - move_token(&env, &token_b, &b, &a, amount_b, min_b_for_a); - } -} - -fn move_token( - env: &Env, - token: &Address, - from: &Address, - to: &Address, - max_spend_amount: i128, - transfer_amount: i128, -) { - let token = token::Client::new(env, token); - let contract_address = env.current_contract_address(); - // This call needs to be authorized by `from` address. It transfers the - // maximum spend amount to the swap contract's address in order to decouple - // the signature from `to` address (so that parties don't need to know each - // other). - token.transfer(from, &contract_address, &max_spend_amount); - // Transfer the necessary amount to `to`. - token.transfer(&contract_address, to, &transfer_amount); - // Refund the remaining balance to `from`. - token.transfer( - &contract_address, - from, - &(&max_spend_amount - &transfer_amount), - ); -} - -mod test; diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/src/test.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/src/test.rs deleted file mode 100644 index cf7929ef..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/swap/src/test.rs +++ /dev/null @@ -1,112 +0,0 @@ -#![cfg(test)] -extern crate std; - -use super::*; -use soroban_sdk::{ - symbol_short, - testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation}, - token, Address, Env, IntoVal, -}; -use token::Client as TokenClient; -use token::StellarAssetClient as TokenAdminClient; - -fn create_token_contract<'a>(e: &Env, admin: &Address) -> (TokenClient<'a>, TokenAdminClient<'a>) { - let contract_address = e.register_stellar_asset_contract(admin.clone()); - ( - TokenClient::new(e, &contract_address), - TokenAdminClient::new(e, &contract_address), - ) -} - -fn create_atomic_swap_contract(e: &Env) -> AtomicSwapContractClient { - AtomicSwapContractClient::new(e, &e.register_contract(None, AtomicSwapContract {})) -} - -#[test] -fn test_atomic_swap() { - let env = Env::default(); - env.mock_all_auths(); - - let a = Address::generate(&env); - let b = Address::generate(&env); - - let token_admin = Address::generate(&env); - - let (token_a, token_a_admin) = create_token_contract(&env, &token_admin); - let (token_b, token_b_admin) = create_token_contract(&env, &token_admin); - token_a_admin.mint(&a, &1000); - token_b_admin.mint(&b, &5000); - - let contract = create_atomic_swap_contract(&env); - - contract.swap( - &a, - &b, - &token_a.address, - &token_b.address, - &1000, - &4500, - &5000, - &950, - ); - - assert_eq!( - env.auths(), - std::vec![ - ( - a.clone(), - AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - contract.address.clone(), - symbol_short!("swap"), - ( - token_a.address.clone(), - token_b.address.clone(), - 1000_i128, - 4500_i128 - ) - .into_val(&env), - )), - sub_invocations: std::vec![AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - token_a.address.clone(), - symbol_short!("transfer"), - (a.clone(), contract.address.clone(), 1000_i128,).into_val(&env), - )), - sub_invocations: std::vec![] - }] - } - ), - ( - b.clone(), - AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - contract.address.clone(), - symbol_short!("swap"), - ( - token_b.address.clone(), - token_a.address.clone(), - 5000_i128, - 950_i128 - ) - .into_val(&env), - )), - sub_invocations: std::vec![AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - token_b.address.clone(), - symbol_short!("transfer"), - (b.clone(), contract.address.clone(), 5000_i128,).into_val(&env), - )), - sub_invocations: std::vec![] - }] - } - ), - ] - ); - - assert_eq!(token_a.balance(&a), 50); - assert_eq!(token_a.balance(&b), 950); - - assert_eq!(token_b.balance(&a), 4500); - assert_eq!(token_b.balance(&b), 500); -} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/Cargo.toml deleted file mode 100644 index 3f32f139..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "test_token" -version.workspace = true -description = "Soroban standard token contract" -authors = ["Stellar Development Foundation "] -license = "Apache-2.0" -edition = "2021" -publish = false -rust-version.workspace = true - -[lib] -crate-type = ["cdylib"] - -[dependencies] -soroban-sdk = { workspace = true } -soroban-token-sdk = { workspace = true } - -[dev_dependencies] -soroban-sdk = { workspace = true, features = ["testutils"] } diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/admin.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/admin.rs deleted file mode 100644 index a820bf04..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/admin.rs +++ /dev/null @@ -1,18 +0,0 @@ -use soroban_sdk::{Address, Env}; - -use crate::storage_types::DataKey; - -pub fn has_administrator(e: &Env) -> bool { - let key = DataKey::Admin; - e.storage().instance().has(&key) -} - -pub fn read_administrator(e: &Env) -> Address { - let key = DataKey::Admin; - e.storage().instance().get(&key).unwrap() -} - -pub fn write_administrator(e: &Env, id: &Address) { - let key = DataKey::Admin; - e.storage().instance().set(&key, id); -} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/allowance.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/allowance.rs deleted file mode 100644 index ad746871..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/allowance.rs +++ /dev/null @@ -1,63 +0,0 @@ -use crate::storage_types::{AllowanceDataKey, AllowanceValue, DataKey}; -use soroban_sdk::{Address, Env}; - -pub fn read_allowance(e: &Env, from: Address, spender: Address) -> AllowanceValue { - let key = DataKey::Allowance(AllowanceDataKey { from, spender }); - if let Some(allowance) = e.storage().temporary().get::<_, AllowanceValue>(&key) { - if allowance.expiration_ledger < e.ledger().sequence() { - AllowanceValue { - amount: 0, - expiration_ledger: allowance.expiration_ledger, - } - } else { - allowance - } - } else { - AllowanceValue { - amount: 0, - expiration_ledger: 0, - } - } -} - -pub fn write_allowance( - e: &Env, - from: Address, - spender: Address, - amount: i128, - expiration_ledger: u32, -) { - let allowance = AllowanceValue { - amount, - expiration_ledger, - }; - - if amount > 0 && expiration_ledger < e.ledger().sequence() { - panic!("expiration_ledger is less than ledger seq when amount > 0") - } - - let key = DataKey::Allowance(AllowanceDataKey { from, spender }); - e.storage().temporary().set(&key.clone(), &allowance); - - if amount > 0 { - let live_for = expiration_ledger - .checked_sub(e.ledger().sequence()) - .unwrap(); - - e.storage().temporary().extend_ttl(&key, live_for, live_for) - } -} - -pub fn spend_allowance(e: &Env, from: Address, spender: Address, amount: i128) { - let allowance = read_allowance(e, from.clone(), spender.clone()); - if allowance.amount < amount { - panic!("insufficient allowance"); - } - write_allowance( - e, - from, - spender, - allowance.amount - amount, - allowance.expiration_ledger, - ); -} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/balance.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/balance.rs deleted file mode 100644 index 76134e8d..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/balance.rs +++ /dev/null @@ -1,35 +0,0 @@ -use crate::storage_types::{DataKey, BALANCE_BUMP_AMOUNT, BALANCE_LIFETIME_THRESHOLD}; -use soroban_sdk::{Address, Env}; - -pub fn read_balance(e: &Env, addr: Address) -> i128 { - let key = DataKey::Balance(addr); - if let Some(balance) = e.storage().persistent().get::(&key) { - e.storage() - .persistent() - .extend_ttl(&key, BALANCE_LIFETIME_THRESHOLD, BALANCE_BUMP_AMOUNT); - balance - } else { - 0 - } -} - -fn write_balance(e: &Env, addr: Address, amount: i128) { - let key = DataKey::Balance(addr); - e.storage().persistent().set(&key, &amount); - e.storage() - .persistent() - .extend_ttl(&key, BALANCE_LIFETIME_THRESHOLD, BALANCE_BUMP_AMOUNT); -} - -pub fn receive_balance(e: &Env, addr: Address, amount: i128) { - let balance = read_balance(e, addr.clone()); - write_balance(e, addr, balance + amount); -} - -pub fn spend_balance(e: &Env, addr: Address, amount: i128) { - let balance = read_balance(e, addr.clone()); - if balance < amount { - panic!("insufficient balance"); - } - write_balance(e, addr, balance - amount); -} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/contract.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/contract.rs deleted file mode 100644 index cc5690c6..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/contract.rs +++ /dev/null @@ -1,167 +0,0 @@ -//! This contract demonstrates a sample implementation of the Soroban token -//! interface. -use crate::admin::{has_administrator, read_administrator, write_administrator}; -use crate::allowance::{read_allowance, spend_allowance, write_allowance}; -use crate::balance::{read_balance, receive_balance, spend_balance}; -use crate::metadata::{read_decimal, read_name, read_symbol, write_metadata}; -use crate::storage_types::{INSTANCE_BUMP_AMOUNT, INSTANCE_LIFETIME_THRESHOLD}; -use soroban_sdk::token::{self, Interface as _}; -use soroban_sdk::{contract, contractimpl, Address, Env, String}; -use soroban_token_sdk::metadata::TokenMetadata; -use soroban_token_sdk::TokenUtils; - -fn check_nonnegative_amount(amount: i128) { - if amount < 0 { - panic!("negative amount is not allowed: {}", amount) - } -} - -#[contract] -pub struct Token; - -#[contractimpl] -impl Token { - pub fn initialize(e: Env, admin: Address, decimal: u32, name: String, symbol: String) { - if has_administrator(&e) { - panic!("already initialized") - } - write_administrator(&e, &admin); - if decimal > u8::MAX.into() { - panic!("Decimal must fit in a u8"); - } - - write_metadata( - &e, - TokenMetadata { - decimal, - name, - symbol, - }, - ) - } - - pub fn mint(e: Env, to: Address, amount: i128) { - check_nonnegative_amount(amount); - let admin = read_administrator(&e); - admin.require_auth(); - - e.storage() - .instance() - .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); - - receive_balance(&e, to.clone(), amount); - TokenUtils::new(&e).events().mint(admin, to, amount); - } - - pub fn set_admin(e: Env, new_admin: Address) { - let admin = read_administrator(&e); - admin.require_auth(); - - e.storage() - .instance() - .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); - - write_administrator(&e, &new_admin); - TokenUtils::new(&e).events().set_admin(admin, new_admin); - } -} - -#[contractimpl] -impl token::Interface for Token { - fn allowance(e: Env, from: Address, spender: Address) -> i128 { - e.storage() - .instance() - .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); - read_allowance(&e, from, spender).amount - } - - fn approve(e: Env, from: Address, spender: Address, amount: i128, expiration_ledger: u32) { - from.require_auth(); - - check_nonnegative_amount(amount); - - e.storage() - .instance() - .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); - - write_allowance(&e, from.clone(), spender.clone(), amount, expiration_ledger); - TokenUtils::new(&e) - .events() - .approve(from, spender, amount, expiration_ledger); - } - - fn balance(e: Env, id: Address) -> i128 { - e.storage() - .instance() - .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); - read_balance(&e, id) - } - - fn transfer(e: Env, from: Address, to: Address, amount: i128) { - from.require_auth(); - - check_nonnegative_amount(amount); - - e.storage() - .instance() - .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); - - spend_balance(&e, from.clone(), amount); - receive_balance(&e, to.clone(), amount); - TokenUtils::new(&e).events().transfer(from, to, amount); - } - - fn transfer_from(e: Env, spender: Address, from: Address, to: Address, amount: i128) { - spender.require_auth(); - - check_nonnegative_amount(amount); - - e.storage() - .instance() - .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); - - spend_allowance(&e, from.clone(), spender, amount); - spend_balance(&e, from.clone(), amount); - receive_balance(&e, to.clone(), amount); - TokenUtils::new(&e).events().transfer(from, to, amount) - } - - fn burn(e: Env, from: Address, amount: i128) { - from.require_auth(); - - check_nonnegative_amount(amount); - - e.storage() - .instance() - .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); - - spend_balance(&e, from.clone(), amount); - TokenUtils::new(&e).events().burn(from, amount); - } - - fn burn_from(e: Env, spender: Address, from: Address, amount: i128) { - spender.require_auth(); - - check_nonnegative_amount(amount); - - e.storage() - .instance() - .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); - - spend_allowance(&e, from.clone(), spender, amount); - spend_balance(&e, from.clone(), amount); - TokenUtils::new(&e).events().burn(from, amount) - } - - fn decimals(e: Env) -> u32 { - read_decimal(&e) - } - - fn name(e: Env) -> String { - read_name(&e) - } - - fn symbol(e: Env) -> String { - read_symbol(&e) - } -} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/lib.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/lib.rs deleted file mode 100644 index b5f04e4d..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/lib.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![no_std] - -mod admin; -mod allowance; -mod balance; -mod contract; -mod metadata; -mod storage_types; -mod test; - -pub use crate::contract::TokenClient; diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/metadata.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/metadata.rs deleted file mode 100644 index 715feeea..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/metadata.rs +++ /dev/null @@ -1,22 +0,0 @@ -use soroban_sdk::{Env, String}; -use soroban_token_sdk::{metadata::TokenMetadata, TokenUtils}; - -pub fn read_decimal(e: &Env) -> u32 { - let util = TokenUtils::new(e); - util.metadata().get_metadata().decimal -} - -pub fn read_name(e: &Env) -> String { - let util = TokenUtils::new(e); - util.metadata().get_metadata().name -} - -pub fn read_symbol(e: &Env) -> String { - let util = TokenUtils::new(e); - util.metadata().get_metadata().symbol -} - -pub fn write_metadata(e: &Env, metadata: TokenMetadata) { - let util = TokenUtils::new(e); - util.metadata().set_metadata(&metadata); -} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/storage_types.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/storage_types.rs deleted file mode 100644 index 5710c057..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/storage_types.rs +++ /dev/null @@ -1,31 +0,0 @@ -use soroban_sdk::{contracttype, Address}; - -pub(crate) const DAY_IN_LEDGERS: u32 = 17280; -pub(crate) const INSTANCE_BUMP_AMOUNT: u32 = 7 * DAY_IN_LEDGERS; -pub(crate) const INSTANCE_LIFETIME_THRESHOLD: u32 = INSTANCE_BUMP_AMOUNT - DAY_IN_LEDGERS; - -pub(crate) const BALANCE_BUMP_AMOUNT: u32 = 30 * DAY_IN_LEDGERS; -pub(crate) const BALANCE_LIFETIME_THRESHOLD: u32 = BALANCE_BUMP_AMOUNT - DAY_IN_LEDGERS; - -#[derive(Clone)] -#[contracttype] -pub struct AllowanceDataKey { - pub from: Address, - pub spender: Address, -} - -#[contracttype] -pub struct AllowanceValue { - pub amount: i128, - pub expiration_ledger: u32, -} - -#[derive(Clone)] -#[contracttype] -pub enum DataKey { - Allowance(AllowanceDataKey), - Balance(Address), - Nonce(Address), - State(Address), - Admin, -} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/test.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/test.rs deleted file mode 100644 index dbdb17a3..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/token/src/test.rs +++ /dev/null @@ -1,256 +0,0 @@ -#![cfg(test)] -extern crate std; - -use crate::{contract::Token, TokenClient}; -use soroban_sdk::{ - symbol_short, - testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation}, - Address, Env, IntoVal, Symbol, -}; - -fn create_token<'a>(e: &Env, admin: &Address) -> TokenClient<'a> { - let token = TokenClient::new(e, &e.register_contract(None, Token {})); - token.initialize(admin, &7, &"name".into_val(e), &"symbol".into_val(e)); - token -} - -#[test] -fn test() { - let e = Env::default(); - e.mock_all_auths(); - - let admin1 = Address::generate(&e); - let admin2 = Address::generate(&e); - let user1 = Address::generate(&e); - let user2 = Address::generate(&e); - let user3 = Address::generate(&e); - let token = create_token(&e, &admin1); - - token.mint(&user1, &1000); - assert_eq!( - e.auths(), - std::vec![( - admin1.clone(), - AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - token.address.clone(), - symbol_short!("mint"), - (&user1, 1000_i128).into_val(&e), - )), - sub_invocations: std::vec![] - } - )] - ); - assert_eq!(token.balance(&user1), 1000); - - token.approve(&user2, &user3, &500, &200); - assert_eq!( - e.auths(), - std::vec![( - user2.clone(), - AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - token.address.clone(), - symbol_short!("approve"), - (&user2, &user3, 500_i128, 200_u32).into_val(&e), - )), - sub_invocations: std::vec![] - } - )] - ); - assert_eq!(token.allowance(&user2, &user3), 500); - - token.transfer(&user1, &user2, &600); - assert_eq!( - e.auths(), - std::vec![( - user1.clone(), - AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - token.address.clone(), - symbol_short!("transfer"), - (&user1, &user2, 600_i128).into_val(&e), - )), - sub_invocations: std::vec![] - } - )] - ); - assert_eq!(token.balance(&user1), 400); - assert_eq!(token.balance(&user2), 600); - - token.transfer_from(&user3, &user2, &user1, &400); - assert_eq!( - e.auths(), - std::vec![( - user3.clone(), - AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - token.address.clone(), - Symbol::new(&e, "transfer_from"), - (&user3, &user2, &user1, 400_i128).into_val(&e), - )), - sub_invocations: std::vec![] - } - )] - ); - assert_eq!(token.balance(&user1), 800); - assert_eq!(token.balance(&user2), 200); - - token.transfer(&user1, &user3, &300); - assert_eq!(token.balance(&user1), 500); - assert_eq!(token.balance(&user3), 300); - - token.set_admin(&admin2); - assert_eq!( - e.auths(), - std::vec![( - admin1.clone(), - AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - token.address.clone(), - symbol_short!("set_admin"), - (&admin2,).into_val(&e), - )), - sub_invocations: std::vec![] - } - )] - ); - - // Increase to 500 - token.approve(&user2, &user3, &500, &200); - assert_eq!(token.allowance(&user2, &user3), 500); - token.approve(&user2, &user3, &0, &200); - assert_eq!( - e.auths(), - std::vec![( - user2.clone(), - AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - token.address.clone(), - symbol_short!("approve"), - (&user2, &user3, 0_i128, 200_u32).into_val(&e), - )), - sub_invocations: std::vec![] - } - )] - ); - assert_eq!(token.allowance(&user2, &user3), 0); -} - -#[test] -fn test_burn() { - let e = Env::default(); - e.mock_all_auths(); - - let admin = Address::generate(&e); - let user1 = Address::generate(&e); - let user2 = Address::generate(&e); - let token = create_token(&e, &admin); - - token.mint(&user1, &1000); - assert_eq!(token.balance(&user1), 1000); - - token.approve(&user1, &user2, &500, &200); - assert_eq!(token.allowance(&user1, &user2), 500); - - token.burn_from(&user2, &user1, &500); - assert_eq!( - e.auths(), - std::vec![( - user2.clone(), - AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - token.address.clone(), - symbol_short!("burn_from"), - (&user2, &user1, 500_i128).into_val(&e), - )), - sub_invocations: std::vec![] - } - )] - ); - - assert_eq!(token.allowance(&user1, &user2), 0); - assert_eq!(token.balance(&user1), 500); - assert_eq!(token.balance(&user2), 0); - - token.burn(&user1, &500); - assert_eq!( - e.auths(), - std::vec![( - user1.clone(), - AuthorizedInvocation { - function: AuthorizedFunction::Contract(( - token.address.clone(), - symbol_short!("burn"), - (&user1, 500_i128).into_val(&e), - )), - sub_invocations: std::vec![] - } - )] - ); - - assert_eq!(token.balance(&user1), 0); - assert_eq!(token.balance(&user2), 0); -} - -#[test] -#[should_panic(expected = "insufficient balance")] -fn transfer_insufficient_balance() { - let e = Env::default(); - e.mock_all_auths(); - - let admin = Address::generate(&e); - let user1 = Address::generate(&e); - let user2 = Address::generate(&e); - let token = create_token(&e, &admin); - - token.mint(&user1, &1000); - assert_eq!(token.balance(&user1), 1000); - - token.transfer(&user1, &user2, &1001); -} - -#[test] -#[should_panic(expected = "insufficient allowance")] -fn transfer_from_insufficient_allowance() { - let e = Env::default(); - e.mock_all_auths(); - - let admin = Address::generate(&e); - let user1 = Address::generate(&e); - let user2 = Address::generate(&e); - let user3 = Address::generate(&e); - let token = create_token(&e, &admin); - - token.mint(&user1, &1000); - assert_eq!(token.balance(&user1), 1000); - - token.approve(&user1, &user3, &100, &200); - assert_eq!(token.allowance(&user1, &user3), 100); - - token.transfer_from(&user3, &user1, &user2, &101); -} - -#[test] -#[should_panic(expected = "already initialized")] -fn initialize_already_initialized() { - let e = Env::default(); - let admin = Address::generate(&e); - let token = create_token(&e, &admin); - - token.initialize(&admin, &10, &"name".into_val(&e), &"symbol".into_val(&e)); -} - -#[test] -#[should_panic(expected = "Decimal must fit in a u8")] -fn decimal_is_over_max() { - let e = Env::default(); - let admin = Address::generate(&e); - let token = TokenClient::new(&e, &e.register_contract(None, Token {})); - token.initialize( - &admin, - &(u32::from(u8::MAX) + 1), - &"name".into_val(&e), - &"symbol".into_val(&e), - ); -} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/udt/Cargo.toml b/cmd/crates/soroban-test/tests/fixtures/test-wasms/udt/Cargo.toml deleted file mode 100644 index 20628480..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/udt/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "test_udt" -version.workspace = true -authors = ["Stellar Development Foundation "] -license = "Apache-2.0" -edition = "2021" -publish = false -rust-version.workspace = true - -[lib] -crate-type = ["cdylib"] -doctest = false - -[dependencies] -soroban-sdk = { workspace = true } - -[dev-dependencies] -soroban-sdk = { workspace = true , features = ["testutils"]} diff --git a/cmd/crates/soroban-test/tests/fixtures/test-wasms/udt/src/lib.rs b/cmd/crates/soroban-test/tests/fixtures/test-wasms/udt/src/lib.rs deleted file mode 100644 index 695d8a7a..00000000 --- a/cmd/crates/soroban-test/tests/fixtures/test-wasms/udt/src/lib.rs +++ /dev/null @@ -1,112 +0,0 @@ -#![no_std] -use soroban_sdk::{contract, contractimpl, contracttype, Vec}; - -#[contracttype] -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum UdtEnum2 { - A = 10, - B = 15, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum UdtEnum { - UdtA, - UdtB(UdtStruct), - UdtC(UdtEnum2), - UdtD(UdtTuple), -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct UdtTuple(pub i64, pub Vec); - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct UdtStruct { - a: i64, - b: i64, - pub c: Vec, -} - -#[contract] -pub struct Contract; - -#[contractimpl] -impl Contract { - #[allow(clippy::unnecessary_fold)] - pub fn add(a: UdtEnum, b: UdtEnum) -> i64 { - let a = match a { - UdtEnum::UdtA => 0, - UdtEnum::UdtB(udt) => udt.a + udt.b, - UdtEnum::UdtC(val) => val as i64, - UdtEnum::UdtD(tup) => tup.0 + tup.1.iter().fold(0i64, |sum, i| sum + i), - }; - let b = match b { - UdtEnum::UdtA => 0, - UdtEnum::UdtB(udt) => udt.a + udt.b, - UdtEnum::UdtC(val) => val as i64, - UdtEnum::UdtD(tup) => tup.0 + tup.1.iter().sum::(), - }; - a + b - } -} - -#[cfg(test)] -mod test { - use super::*; - use soroban_sdk::{vec, xdr::ScVal, Bytes, Env, TryFromVal}; - - #[test] - fn test_serializing() { - use soroban_sdk::xdr::ToXdr; - let e = Env::default(); - let udt = UdtStruct { - a: 10, - b: 12, - c: vec![&e, 1], - }; - let bin = udt.to_xdr(&e); - let expected_bytes = [ - 0u8, 0, 0, 17, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 1, 97, 0, 0, 0, 0, 0, 0, - 6, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 15, 0, 0, 0, 1, 98, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, - 0, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 1, 99, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, - ]; - let expected_bytes = Bytes::from_array(&e, &expected_bytes); - assert_eq!(bin, expected_bytes); - } - - #[test] - fn test_add() { - let e = Env::default(); - let contract_id = e.register_contract(None, Contract); - let client = ContractClient::new(&e, &contract_id); - - let udt = UdtStruct { - a: 10, - b: 12, - c: vec![&e, 1], - }; - let z = client.add(&UdtEnum::UdtA, &UdtEnum::UdtB(udt)); - assert_eq!(z, 22); - - let udt1 = UdtEnum2::A; - let udt2 = UdtTuple(1, vec![&e, 2, 3]); - let z = client.add(&UdtEnum::UdtC(udt1), &UdtEnum::UdtD(udt2)); - assert_eq!(z, 16); - } - - #[test] - fn test_scval_accessibility_from_udt_types() { - let e = Env::default(); - let udt = UdtStruct { - a: 10, - b: 12, - c: vec![&e, 1], - }; - let val: ScVal = udt.clone().try_into().unwrap(); - let roundtrip = UdtStruct::try_from_val(&e, &val).unwrap(); - assert_eq!(udt, roundtrip); - } -} diff --git a/cmd/crates/soroban-test/tests/it/arg_parsing.rs b/cmd/crates/soroban-test/tests/it/arg_parsing.rs deleted file mode 100644 index c245fd8c..00000000 --- a/cmd/crates/soroban-test/tests/it/arg_parsing.rs +++ /dev/null @@ -1,215 +0,0 @@ -use crate::util::CUSTOM_TYPES; -use serde_json::json; -use soroban_env_host::xdr::{ - ScBytes, ScSpecTypeBytesN, ScSpecTypeDef, ScSpecTypeOption, ScSpecTypeUdt, ScVal, -}; -use soroban_spec_tools::{from_string_primitive, Spec}; - -#[test] -fn parse_bool() { - println!( - "{:#?}", - from_string_primitive("true", &ScSpecTypeDef::Bool,).unwrap() - ); -} - -#[test] -fn parse_null() { - let parsed = from_string_primitive( - "null", - &ScSpecTypeDef::Option(Box::new(ScSpecTypeOption { - value_type: Box::new(ScSpecTypeDef::Bool), - })), - ) - .unwrap(); - println!("{parsed:#?}"); - assert!(parsed == ScVal::Void); -} - -#[test] -fn parse_u32() { - let u32_ = 42u32; - let res = &format!("{u32_}"); - println!( - "{:#?}", - from_string_primitive(res, &ScSpecTypeDef::U32,).unwrap() - ); -} - -#[test] -fn parse_i32() { - let i32_ = -42_i32; - let res = &format!("{i32_}"); - println!( - "{:#?}", - from_string_primitive(res, &ScSpecTypeDef::I32,).unwrap() - ); -} - -#[test] -fn parse_u64() { - let b = 42_000_000_000u64; - let res = &format!("{b}"); - println!( - "{:#?}", - from_string_primitive(res, &ScSpecTypeDef::U64,).unwrap() - ); -} - -#[test] -fn parse_u128() { - let b = 340_000_000_000_000_000_000_000_000_000_000_000_000u128; - let res = &format!("{b}"); - println!( - "{:#?}", - from_string_primitive(res, &ScSpecTypeDef::U128,).unwrap() - ); -} - -#[test] -fn parse_i128() { - let b = -170_000_000_000_000_000_000_000_000_000_000_000_000i128; - let res = &format!("{b}"); - println!( - "{:#?}", - from_string_primitive(res, &ScSpecTypeDef::I128,).unwrap() - ); -} - -#[test] -fn parse_i256() { - let b = -170_000_000_000_000_000_000_000_000_000_000_000_000i128; - let res = &format!("{b}"); - let entries = get_spec(); - entries.from_string(res, &ScSpecTypeDef::I256).unwrap(); - println!( - "{:#?}", - from_string_primitive(res, &ScSpecTypeDef::I256,).unwrap() - ); -} - -#[test] -fn parse_bytes() { - let b = from_string_primitive(r"beefface", &ScSpecTypeDef::Bytes).unwrap(); - assert_eq!( - b, - ScVal::Bytes(ScBytes(vec![0xbe, 0xef, 0xfa, 0xce].try_into().unwrap())) - ); - println!("{b:#?}"); -} - -#[test] -fn parse_bytes_when_hex_is_all_numbers() { - let b = from_string_primitive(r"4554", &ScSpecTypeDef::Bytes).unwrap(); - assert_eq!( - b, - ScVal::Bytes(ScBytes(vec![0x45, 0x54].try_into().unwrap())) - ); - println!("{b:#?}"); -} - -#[test] -fn parse_bytesn() { - let b = from_string_primitive( - r"beefface", - &ScSpecTypeDef::BytesN(ScSpecTypeBytesN { n: 4 }), - ) - .unwrap(); - assert_eq!( - b, - ScVal::Bytes(ScBytes(vec![0xbe, 0xef, 0xfa, 0xce].try_into().unwrap())) - ); - println!("{b:#?}"); -} - -#[test] -fn parse_bytesn_when_hex_is_all_numbers() { - let b = - from_string_primitive(r"4554", &ScSpecTypeDef::BytesN(ScSpecTypeBytesN { n: 2 })).unwrap(); - assert_eq!( - b, - ScVal::Bytes(ScBytes(vec![0x45, 0x54].try_into().unwrap())) - ); - println!("{b:#?}",); -} - -#[test] -fn parse_symbol() { - // let b = "hello"; - // let res = &parse_json(&HashMap::new(), &ScSpecTypeDef::Symbol, &json! {b}).unwrap(); - // println!("{res}"); - println!( - "{:#?}", - from_string_primitive(r#""hello""#, &ScSpecTypeDef::Symbol).unwrap() - ); -} - -#[test] -fn parse_symbol_with_no_quotation_marks() { - // let b = "hello"; - // let res = &parse_json(&HashMap::new(), &ScSpecTypeDef::Symbol, &json! {b}).unwrap(); - // println!("{res}"); - println!( - "{:#?}", - from_string_primitive("hello", &ScSpecTypeDef::Symbol).unwrap() - ); -} - -#[test] -fn parse_optional_symbol_with_no_quotation_marks() { - let parsed = from_string_primitive( - "hello", - &ScSpecTypeDef::Option(Box::new(ScSpecTypeOption { - value_type: Box::new(ScSpecTypeDef::Symbol), - })), - ) - .unwrap(); - println!("{parsed:#?}"); - assert!(parsed == ScVal::Symbol("hello".try_into().unwrap())); -} - -#[test] -fn parse_optional_bool_with_no_quotation_marks() { - let parsed = from_string_primitive( - "true", - &ScSpecTypeDef::Option(Box::new(ScSpecTypeOption { - value_type: Box::new(ScSpecTypeDef::Bool), - })), - ) - .unwrap(); - println!("{parsed:#?}"); - assert!(parsed == ScVal::Bool(true)); -} - -#[test] -fn parse_obj() { - let type_ = &ScSpecTypeDef::Udt(ScSpecTypeUdt { - name: "Test".parse().unwrap(), - }); - let entries = get_spec(); - let val = &json!({"a": 42, "b": false, "c": "world"}); - println!("{:#?}", entries.from_json(val, type_)); -} - -#[test] -fn parse_enum() { - let entries = get_spec(); - let func = entries.find_function("simple").unwrap(); - println!("{func:#?}"); - let type_ = &func.inputs.as_slice()[0].type_; - println!("{:#?}", entries.from_json(&json!("First"), type_)); -} - -#[test] -fn parse_enum_const() { - let entries = get_spec(); - let func = entries.find_function("card").unwrap(); - println!("{func:#?}"); - let type_ = &func.inputs.as_slice()[0].type_; - println!("{:#?}", entries.from_json(&json!(11), type_)); -} - -fn get_spec() -> Spec { - let res = soroban_spec::read::from_wasm(&CUSTOM_TYPES.bytes()).unwrap(); - Spec(Some(res)) -} diff --git a/cmd/crates/soroban-test/tests/it/config.rs b/cmd/crates/soroban-test/tests/it/config.rs deleted file mode 100644 index 5912b2cf..00000000 --- a/cmd/crates/soroban-test/tests/it/config.rs +++ /dev/null @@ -1,223 +0,0 @@ -use assert_fs::TempDir; -use soroban_test::TestEnv; -use std::{fs, path::Path}; - -use crate::util::{add_key, add_test_id, SecretKind, DEFAULT_SEED_PHRASE}; -use soroban_cli::commands::network; - -const NETWORK_PASSPHRASE: &str = "Local Sandbox Stellar Network ; September 2022"; - -#[test] -fn set_and_remove_network() { - TestEnv::with_default(|sandbox| { - add_network(sandbox, "local"); - let dir = sandbox.dir().join(".soroban").join("network"); - let read_dir = std::fs::read_dir(dir); - println!("{read_dir:#?}"); - let file = read_dir.unwrap().next().unwrap().unwrap(); - assert_eq!(file.file_name().to_str().unwrap(), "local.toml"); - - let res = sandbox.cmd::(""); - let res = res.ls().unwrap(); - assert_eq!(res.len(), 1); - assert_eq!(&res[0], "local"); - - sandbox.cmd::("local").run().unwrap(); - - // sandbox - // .new_assert_cmd("config") - // .arg("network") - // .arg("rm") - // .arg("local") - // .assert() - // .stdout(""); - sandbox - .new_assert_cmd("network") - .arg("ls") - .assert() - .stdout("\n"); - }); -} - -fn add_network(sandbox: &TestEnv, name: &str) { - sandbox - .new_assert_cmd("network") - .arg("add") - .args([ - "--rpc-url=https://127.0.0.1", - "--network-passphrase", - NETWORK_PASSPHRASE, - name, - ]) - .assert() - .success() - .stderr("") - .stdout(""); -} - -fn add_network_global(sandbox: &TestEnv, dir: &Path, name: &str) { - sandbox - .new_assert_cmd("network") - .env("XDG_CONFIG_HOME", dir.to_str().unwrap()) - .arg("add") - .arg("--global") - .arg("--rpc-url") - .arg("https://127.0.0.1") - .arg("--network-passphrase") - .arg("Local Sandbox Stellar Network ; September 2022") - .arg(name) - .assert() - .success(); -} - -#[test] -fn set_and_remove_global_network() { - let sandbox = TestEnv::default(); - let dir = TempDir::new().unwrap(); - - add_network_global(&sandbox, &dir, "global"); - - sandbox - .new_assert_cmd("network") - .env("XDG_CONFIG_HOME", dir.to_str().unwrap()) - .arg("ls") - .arg("--global") - .assert() - .stdout("global\n"); - - sandbox - .new_assert_cmd("network") - .env("XDG_CONFIG_HOME", dir.to_str().unwrap()) - .arg("rm") - .arg("--global") - .arg("global") - .assert() - .stdout(""); - - sandbox - .new_assert_cmd("network") - .env("XDG_CONFIG_HOME", dir.to_str().unwrap()) - .arg("ls") - .assert() - .stdout("\n"); -} - -#[test] -fn multiple_networks() { - let sandbox = TestEnv::default(); - let ls = || -> Vec { sandbox.cmd::("").ls().unwrap() }; - - add_network(&sandbox, "local"); - println!("{:#?}", ls()); - add_network(&sandbox, "local2"); - - assert_eq!(ls().as_slice(), ["local".to_owned(), "local2".to_owned()]); - - sandbox.cmd::("local").run().unwrap(); - - assert_eq!(ls().as_slice(), ["local2".to_owned()]); - - let sub_dir = sandbox.dir().join("sub_directory"); - fs::create_dir(&sub_dir).unwrap(); - - TestEnv::cmd_arr_with_pwd::( - &[ - "--rpc-url", - "https://127.0.0.1", - "--network-passphrase", - "Local Sandbox Stellar Network ; September 2022", - "local3", - ], - &sub_dir, - ) - .run() - .unwrap(); - - assert_eq!(ls().as_slice(), ["local2".to_owned(), "local3".to_owned()]); -} - -#[test] -fn read_key() { - let sandbox = TestEnv::default(); - let dir = sandbox.dir().as_ref(); - add_test_id(dir); - let ident_dir = dir.join(".soroban/identity"); - assert!(ident_dir.exists()); - sandbox - .new_assert_cmd("keys") - .arg("ls") - .assert() - .stdout(predicates::str::contains("test_id\n")); -} - -#[test] -fn generate_key() { - let sandbox = TestEnv::default(); - sandbox - .new_assert_cmd("keys") - .arg("generate") - .arg("--network=futurenet") - .arg("--no-fund") - .arg("--seed") - .arg("0000000000000000") - .arg("test_2") - .assert() - .stdout("") - .success(); - - sandbox - .new_assert_cmd("keys") - .arg("ls") - .assert() - .stdout(predicates::str::contains("test_2\n")); - let file_contents = - fs::read_to_string(sandbox.dir().join(".soroban/identity/test_2.toml")).unwrap(); - assert_eq!( - file_contents, - format!("seed_phrase = \"{DEFAULT_SEED_PHRASE}\"\n") - ); -} - -#[test] -fn seed_phrase() { - let sandbox = TestEnv::default(); - let dir = sandbox.dir(); - add_key( - dir, - "test_seed", - SecretKind::Seed, - "one two three four five six seven eight nine ten eleven twelve", - ); - - sandbox - .new_assert_cmd("keys") - .current_dir(dir) - .arg("ls") - .assert() - .stdout(predicates::str::contains("test_seed\n")); -} - -#[test] -fn use_env() { - let sandbox = TestEnv::default(); - - sandbox - .new_assert_cmd("keys") - .env( - "SOROBAN_SECRET_KEY", - "SDIY6AQQ75WMD4W46EYB7O6UYMHOCGQHLAQGQTKHDX4J2DYQCHVCQYFD", - ) - .arg("add") - .arg("bob") - .assert() - .stdout("") - .success(); - - sandbox - .new_assert_cmd("keys") - .arg("show") - .arg("bob") - .assert() - .success() - .stdout("SDIY6AQQ75WMD4W46EYB7O6UYMHOCGQHLAQGQTKHDX4J2DYQCHVCQYFD\n"); -} diff --git a/cmd/crates/soroban-test/tests/it/hello_world.rs b/cmd/crates/soroban-test/tests/it/hello_world.rs deleted file mode 100644 index 4c45403a..00000000 --- a/cmd/crates/soroban-test/tests/it/hello_world.rs +++ /dev/null @@ -1,22 +0,0 @@ -use soroban_cli::commands::contract::{self, fetch}; -use soroban_test::TestEnv; -use std::path::PathBuf; - -use crate::util::{ - add_test_seed, is_rpc, network_passphrase, network_passphrase_arg, rpc_url, rpc_url_arg, - DEFAULT_PUB_KEY, DEFAULT_PUB_KEY_1, DEFAULT_SECRET_KEY, DEFAULT_SEED_PHRASE, HELLO_WORLD, - TEST_SALT, -}; - -#[tokio::test] -async fn fetch() { - if !is_rpc() { - return; - } - let e = TestEnv::default(); - let f = e.dir().join("contract.wasm"); - let id = deploy_hello(&e); - let cmd = e.cmd_arr::(&["--id", &id, "--out-file", f.to_str().unwrap()]); - cmd.run().await.unwrap(); - assert!(f.exists()); -} diff --git a/cmd/crates/soroban-test/tests/it/help.rs b/cmd/crates/soroban-test/tests/it/help.rs deleted file mode 100644 index a66c449e..00000000 --- a/cmd/crates/soroban-test/tests/it/help.rs +++ /dev/null @@ -1,97 +0,0 @@ -use soroban_cli::commands::contract; -use soroban_test::TestEnv; - -use crate::util::{invoke_custom as invoke, CUSTOM_TYPES, DEFAULT_CONTRACT_ID}; - -async fn invoke_custom(func: &str, args: &str) -> Result { - let e = &TestEnv::default(); - invoke(e, DEFAULT_CONTRACT_ID, func, args, &CUSTOM_TYPES.path()).await -} - -#[tokio::test] -async fn generate_help() { - assert!(invoke_custom("strukt_hel", "--help") - .await - .unwrap() - .contains("Example contract method which takes a struct")); -} - -#[tokio::test] -async fn vec_help() { - assert!(invoke_custom("vec", "--help") - .await - .unwrap() - .contains("Array")); -} - -#[tokio::test] -async fn tuple_help() { - assert!(invoke_custom("tuple", "--help") - .await - .unwrap() - .contains("Tuple")); -} - -#[tokio::test] -async fn strukt_help() { - let output = invoke_custom("strukt", "--help").await.unwrap(); - assert!(output.contains("--strukt '{ \"a\": 1, \"b\": true, \"c\": \"hello\" }'",)); - assert!(output.contains("This is from the rust doc above the struct Test",)); -} - -#[tokio::test] -async fn complex_enum_help() { - let output = invoke_custom("complex", "--help").await.unwrap(); - assert!(output.contains(r#"--complex '{"Struct":{ "a": 1, "b": true, "c": "hello" }}"#,)); - assert!(output.contains(r#"{"Tuple":[{ "a": 1, "b": true, "c": "hello" }"#,)); - assert!(output.contains(r#"{"Enum":"First"|"Second"|"Third"}"#,)); - assert!(output.contains( - r#"{"Asset":["GDIY6AQQ75WMD4W46EYB7O6UYMHOCGQHLAQGQTKHDX4J2DYQCHVCR4W4", "-100"]}"#, - )); - assert!(output.contains(r#""Void"'"#)); -} - -#[tokio::test] -async fn multi_arg_failure() { - assert!(matches!( - invoke_custom("multi_args", "--b").await.unwrap_err(), - contract::invoke::Error::MissingArgument(_) - )); -} - -#[tokio::test] -async fn handle_arg_larger_than_i32_failure() { - let res = invoke_custom("i32_", &format!("--i32_={}", u32::MAX)).await; - assert!(matches!( - res, - Err(contract::invoke::Error::CannotParseArg { .. }) - )); -} - -#[tokio::test] -async fn handle_arg_larger_than_i64_failure() { - let res = invoke_custom("i64_", &format!("--i64_={}", u64::MAX)).await; - assert!(matches!( - res, - Err(contract::invoke::Error::CannotParseArg { .. }) - )); -} - -#[test] -fn build() { - let sandbox = TestEnv::default(); - let cargo_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let hello_world_contract_path = - cargo_dir.join("tests/fixtures/test-wasms/hello_world/Cargo.toml"); - sandbox - .new_assert_cmd("contract") - .arg("build") - .arg("--manifest-path") - .arg(hello_world_contract_path) - .arg("--profile") - .arg("test-wasms") - .arg("--package") - .arg("test_hello_world") - .assert() - .success(); -} diff --git a/cmd/crates/soroban-test/tests/it/integration.rs b/cmd/crates/soroban-test/tests/it/integration.rs deleted file mode 100644 index 4e92b931..00000000 --- a/cmd/crates/soroban-test/tests/it/integration.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod custom_types; -mod dotenv; -mod hello_world; -mod util; -mod wrap; diff --git a/cmd/crates/soroban-test/tests/it/integration/custom_types.rs b/cmd/crates/soroban-test/tests/it/integration/custom_types.rs deleted file mode 100644 index fda2c1f6..00000000 --- a/cmd/crates/soroban-test/tests/it/integration/custom_types.rs +++ /dev/null @@ -1,419 +0,0 @@ -use serde_json::json; - -use soroban_cli::commands; -use soroban_test::TestEnv; - -use crate::integration::util::{deploy_custom, extend_contract, CUSTOM_TYPES}; - -use super::util::invoke_with_roundtrip; - -fn invoke_custom(e: &TestEnv, id: &str, func: &str) -> assert_cmd::Command { - let mut s = e.new_assert_cmd("contract"); - s.arg("invoke").arg("--id").arg(id).arg("--").arg(func); - s -} - -#[tokio::test] -async fn parse() { - let sandbox = &TestEnv::default(); - let id = &deploy_custom(sandbox); - extend_contract(sandbox, id, CUSTOM_TYPES).await; - symbol(sandbox, id); - string_with_quotes(sandbox, id).await; - symbol_with_quotes(sandbox, id).await; - multi_arg_success(sandbox, id); - bytes_as_file(sandbox, id); - map(sandbox, id).await; - vec_(sandbox, id).await; - tuple(sandbox, id).await; - strukt(sandbox, id).await; - tuple_strukt(sandbox, id).await; - enum_2_str(sandbox, id).await; - e_2_s_enum(sandbox, id).await; - asset(sandbox, id).await; - e_2_s_tuple(sandbox, id).await; - e_2_s_strukt(sandbox, id).await; - number_arg(sandbox, id).await; - number_arg_return_err(sandbox, id).await; - i32(sandbox, id).await; - i64(sandbox, id).await; - negative_i32(sandbox, id).await; - negative_i64(sandbox, id).await; - account_address(sandbox, id).await; - contract_address(sandbox, id).await; - bytes(sandbox, id).await; - const_enum(sandbox, id).await; - number_arg_return_ok(sandbox, id); - void(sandbox, id); - val(sandbox, id); - parse_u128(sandbox, id); - parse_i128(sandbox, id); - parse_negative_i128(sandbox, id); - parse_u256(sandbox, id); - parse_i256(sandbox, id); - parse_negative_i256(sandbox, id); - boolean(sandbox, id); - boolean_two(sandbox, id); - boolean_no_flag(sandbox, id); - boolean_false(sandbox, id); - boolean_not(sandbox, id); - boolean_not_no_flag(sandbox, id); - option_none(sandbox, id); - option_some(sandbox, id); -} - -fn symbol(sandbox: &TestEnv, id: &str) { - invoke_custom(sandbox, id, "hello") - .arg("--hello") - .arg("world") - .assert() - .success() - .stdout( - r#""world" -"#, - ); -} - -async fn string_with_quotes(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip(sandbox, id, "string", json!("hello world")).await; -} - -async fn symbol_with_quotes(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip(sandbox, id, "hello", json!("world")).await; -} - -fn multi_arg_success(sandbox: &TestEnv, id: &str) { - invoke_custom(sandbox, id, "multi_args") - .arg("--a") - .arg("42") - .arg("--b") - .assert() - .success() - .stdout("42\n"); -} - -fn bytes_as_file(sandbox: &TestEnv, id: &str) { - let env = &TestEnv::default(); - let path = env.temp_dir.join("bytes.txt"); - std::fs::write(&path, 0x0073_7465_6c6c_6172u128.to_be_bytes()).unwrap(); - invoke_custom(sandbox, id, "bytes") - .arg("--bytes-file-path") - .arg(path) - .assert() - .success() - .stdout("\"0000000000000000007374656c6c6172\"\n"); -} - -async fn map(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip(sandbox, id, "map", json!({"0": true, "1": false})).await; -} - -async fn vec_(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip(sandbox, id, "vec", json!([0, 1])).await; -} - -async fn tuple(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip(sandbox, id, "tuple", json!(["hello", 0])).await; -} - -async fn strukt(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip( - sandbox, - id, - "strukt", - json!({"a": 42, "b": true, "c": "world"}), - ) - .await; -} - -async fn tuple_strukt(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip( - sandbox, - id, - "tuple_strukt", - json!([{"a": 42, "b": true, "c": "world"}, "First"]), - ) - .await; -} - -async fn enum_2_str(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip(sandbox, id, "simple", json!("First")).await; -} - -async fn e_2_s_enum(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip(sandbox, id, "complex", json!({"Enum": "First"})).await; -} - -async fn asset(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip( - sandbox, - id, - "complex", - json!({"Asset": ["CB64D3G7SM2RTH6JSGG34DDTFTQ5CFDKVDZJZSODMCX4NJ2HV2KN7OHT", "100" ]}), - ) - .await; -} - -fn complex_tuple() -> serde_json::Value { - json!({"Tuple": [{"a": 42, "b": true, "c": "world"}, "First"]}) -} - -async fn e_2_s_tuple(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip(sandbox, id, "complex", complex_tuple()).await; -} - -async fn e_2_s_strukt(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip( - sandbox, - id, - "complex", - json!({"Struct": {"a": 42, "b": true, "c": "world"}}), - ) - .await; -} - -async fn number_arg(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip(sandbox, id, "u32_", 42).await; -} - -fn number_arg_return_ok(sandbox: &TestEnv, id: &str) { - invoke_custom(sandbox, id, "u32_fail_on_even") - .arg("--u32_") - .arg("1") - .assert() - .success() - .stdout("1\n"); -} - -async fn number_arg_return_err(sandbox: &TestEnv, id: &str) { - let res = sandbox - .invoke(&["--id", id, "--", "u32_fail_on_even", "--u32_=2"]) - .await - .unwrap_err(); - if let commands::contract::invoke::Error::ContractInvoke(name, doc) = &res { - assert_eq!(name, "NumberMustBeOdd"); - assert_eq!(doc, "Please provide an odd number"); - }; - println!("{res:#?}"); -} - -fn void(sandbox: &TestEnv, id: &str) { - invoke_custom(sandbox, id, "woid") - .assert() - .success() - .stdout("\n") - .stderr(""); -} - -fn val(sandbox: &TestEnv, id: &str) { - invoke_custom(sandbox, id, "val") - .assert() - .success() - .stdout("null\n") - .stderr(""); -} - -async fn i32(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip(sandbox, id, "i32_", 42).await; -} - -async fn i64(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip(sandbox, id, "i64_", i64::MAX).await; -} - -async fn negative_i32(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip(sandbox, id, "i32_", -42).await; -} - -async fn negative_i64(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip(sandbox, id, "i64_", i64::MIN).await; -} - -async fn account_address(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip( - sandbox, - id, - "addresse", - json!("GD5KD2KEZJIGTC63IGW6UMUSMVUVG5IHG64HUTFWCHVZH2N2IBOQN7PS"), - ) - .await; -} - -async fn contract_address(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip( - sandbox, - id, - "addresse", - json!("CA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAXE"), - ) - .await; -} - -async fn bytes(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip(sandbox, id, "bytes", json!("7374656c6c6172")).await; -} - -async fn const_enum(sandbox: &TestEnv, id: &str) { - invoke_with_roundtrip(sandbox, id, "card", "11").await; -} - -fn parse_u128(sandbox: &TestEnv, id: &str) { - let num = "340000000000000000000000000000000000000"; - invoke_custom(sandbox, id, "u128") - .arg("--u128") - .arg(num) - .assert() - .success() - .stdout(format!( - r#""{num}" -"#, - )); -} - -fn parse_i128(sandbox: &TestEnv, id: &str) { - let num = "170000000000000000000000000000000000000"; - invoke_custom(sandbox, id, "i128") - .arg("--i128") - .arg(num) - .assert() - .success() - .stdout(format!( - r#""{num}" -"#, - )); -} - -fn parse_negative_i128(sandbox: &TestEnv, id: &str) { - let num = "-170000000000000000000000000000000000000"; - invoke_custom(sandbox, id, "i128") - .arg("--i128") - .arg(num) - .assert() - .success() - .stdout(format!( - r#""{num}" -"#, - )); -} - -fn parse_u256(sandbox: &TestEnv, id: &str) { - let num = "340000000000000000000000000000000000000"; - invoke_custom(sandbox, id, "u256") - .arg("--u256") - .arg(num) - .assert() - .success() - .stdout(format!( - r#""{num}" -"#, - )); -} - -fn parse_i256(sandbox: &TestEnv, id: &str) { - let num = "170000000000000000000000000000000000000"; - invoke_custom(sandbox, id, "i256") - .arg("--i256") - .arg(num) - .assert() - .success() - .stdout(format!( - r#""{num}" -"#, - )); -} - -fn parse_negative_i256(sandbox: &TestEnv, id: &str) { - let num = "-170000000000000000000000000000000000000"; - invoke_custom(sandbox, id, "i256") - .arg("--i256") - .arg(num) - .assert() - .success() - .stdout(format!( - r#""{num}" -"#, - )); -} - -fn boolean(sandbox: &TestEnv, id: &str) { - invoke_custom(sandbox, id, "boolean") - .arg("--boolean") - .assert() - .success() - .stdout( - r"true -", - ); -} -fn boolean_two(sandbox: &TestEnv, id: &str) { - invoke_custom(sandbox, id, "boolean") - .arg("--boolean") - .arg("true") - .assert() - .success() - .stdout( - r"true -", - ); -} - -fn boolean_no_flag(sandbox: &TestEnv, id: &str) { - invoke_custom(sandbox, id, "boolean") - .assert() - .success() - .stdout( - r"false -", - ); -} - -fn boolean_false(sandbox: &TestEnv, id: &str) { - invoke_custom(sandbox, id, "boolean") - .arg("--boolean") - .arg("false") - .assert() - .success() - .stdout( - r"false -", - ); -} - -fn boolean_not(sandbox: &TestEnv, id: &str) { - invoke_custom(sandbox, id, "not") - .arg("--boolean") - .assert() - .success() - .stdout( - r"false -", - ); -} - -fn boolean_not_no_flag(sandbox: &TestEnv, id: &str) { - invoke_custom(sandbox, id, "not").assert().success().stdout( - r"true -", - ); -} - -fn option_none(sandbox: &TestEnv, id: &str) { - invoke_custom(sandbox, id, "option") - .assert() - .success() - .stdout( - r"null -", - ); -} - -fn option_some(sandbox: &TestEnv, id: &str) { - invoke_custom(sandbox, id, "option") - .arg("--option=1") - .assert() - .success() - .stdout( - r"1 -", - ); -} diff --git a/cmd/crates/soroban-test/tests/it/integration/dotenv.rs b/cmd/crates/soroban-test/tests/it/integration/dotenv.rs deleted file mode 100644 index 7c0f25b3..00000000 --- a/cmd/crates/soroban-test/tests/it/integration/dotenv.rs +++ /dev/null @@ -1,67 +0,0 @@ -use soroban_test::TestEnv; - -use super::util::{deploy_hello, TEST_CONTRACT_ID}; - -fn write_env_file(e: &TestEnv, contents: &str) { - let env_file = e.dir().join(".env"); - std::fs::write(&env_file, contents).unwrap(); - assert_eq!(contents, std::fs::read_to_string(env_file).unwrap()); -} - -fn contract_id() -> String { - format!("SOROBAN_CONTRACT_ID={TEST_CONTRACT_ID}") -} - -#[test] -fn can_read_file() { - TestEnv::with_default(|e| { - deploy_hello(e); - write_env_file(e, &contract_id()); - e.new_assert_cmd("contract") - .arg("invoke") - .arg("--") - .arg("hello") - .arg("--world=world") - .assert() - .stdout("[\"Hello\",\"world\"]\n") - .success(); - }); -} - -#[test] -fn current_env_not_overwritten() { - TestEnv::with_default(|e| { - deploy_hello(e); - write_env_file(e, &contract_id()); - - e.new_assert_cmd("contract") - .env("SOROBAN_CONTRACT_ID", "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4") - .arg("invoke") - .arg("--") - .arg("hello") - .arg("--world=world") - .assert() - .stderr("error: Contract not found: CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4\n"); - }); -} - -#[test] -fn cli_args_have_priority() { - TestEnv::with_default(|e| { - deploy_hello(e); - write_env_file(e, &contract_id()); - e.new_assert_cmd("contract") - .env( - "SOROBAN_CONTRACT_ID", - "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - ) - .arg("invoke") - .arg("--id") - .arg(TEST_CONTRACT_ID) - .arg("--") - .arg("hello") - .arg("--world=world") - .assert() - .stdout("[\"Hello\",\"world\"]\n"); - }); -} diff --git a/cmd/crates/soroban-test/tests/it/integration/hello_world.rs b/cmd/crates/soroban-test/tests/it/integration/hello_world.rs deleted file mode 100644 index 7bd8d596..00000000 --- a/cmd/crates/soroban-test/tests/it/integration/hello_world.rs +++ /dev/null @@ -1,308 +0,0 @@ -use predicates::boolean::PredicateBooleanExt; -use soroban_cli::commands::{ - contract::{self, fetch}, - keys, -}; -use soroban_test::TestEnv; - -use crate::{integration::util::extend_contract, util::DEFAULT_SEED_PHRASE}; - -use super::util::{ - add_test_seed, deploy_hello, extend, network_passphrase, network_passphrase_arg, rpc_url, - rpc_url_arg, DEFAULT_PUB_KEY, DEFAULT_PUB_KEY_1, DEFAULT_SECRET_KEY, HELLO_WORLD, -}; - -#[tokio::test] -#[ignore] -async fn invoke() { - let sandbox = &TestEnv::default(); - let id = &deploy_hello(sandbox); - extend_contract(sandbox, id, HELLO_WORLD).await; - // Note that all functions tested here have no state - invoke_hello_world(sandbox, id); - sandbox - .new_assert_cmd("events") - .arg("--start-ledger=20") - .arg("--id") - .arg(id) - .assert() - .stdout(predicates::str::contains(id).not()) - .success(); - invoke_hello_world_with_lib(sandbox, id).await; - sandbox - .new_assert_cmd("events") - .arg("--start-ledger=20") - .arg("--id") - .arg(id) - .assert() - .stdout(predicates::str::contains(id)) - .success(); - invoke_hello_world_with_lib_two(sandbox, id).await; - invoke_auth(sandbox, id); - invoke_auth_with_identity(sandbox, id).await; - invoke_auth_with_different_test_account_fail(sandbox, id).await; - // invoke_auth_with_different_test_account(sandbox, id); - contract_data_read_failure(sandbox, id); - invoke_with_seed(sandbox, id).await; - invoke_with_sk(sandbox, id).await; - // This does add an identity to local config - invoke_with_id(sandbox, id).await; - handles_kebab_case(sandbox, id).await; - fetch(sandbox, id).await; - invoke_prng_u64_in_range_test(sandbox, id).await; -} - -fn invoke_hello_world(sandbox: &TestEnv, id: &str) { - sandbox - .new_assert_cmd("contract") - .arg("invoke") - .arg("--is-view") - .arg("--id") - .arg(id) - .arg("--") - .arg("hello") - .arg("--world=world") - .assert() - .stdout("[\"Hello\",\"world\"]\n") - .success(); -} - -async fn invoke_hello_world_with_lib(e: &TestEnv, id: &str) { - let mut cmd = contract::invoke::Cmd { - contract_id: id.to_string(), - slop: vec!["hello".into(), "--world=world".into()], - ..Default::default() - }; - - cmd.config.network.rpc_url = rpc_url(); - cmd.config.network.network_passphrase = network_passphrase(); - - let res = e.invoke_cmd(cmd).await.unwrap(); - assert_eq!(res, r#"["Hello","world"]"#); -} - -async fn invoke_hello_world_with_lib_two(e: &TestEnv, id: &str) { - let hello_world = HELLO_WORLD.to_string(); - let mut invoke_args = vec!["--id", id, "--wasm", hello_world.as_str()]; - let args = vec!["--", "hello", "--world=world"]; - let res = - if let (Some(rpc), Some(network_passphrase)) = (rpc_url_arg(), network_passphrase_arg()) { - invoke_args.push(&rpc); - invoke_args.push(&network_passphrase); - e.invoke(&[invoke_args, args].concat()).await.unwrap() - } else { - e.invoke(&[invoke_args, args].concat()).await.unwrap() - }; - assert_eq!(res, r#"["Hello","world"]"#); -} - -fn invoke_auth(sandbox: &TestEnv, id: &str) { - sandbox - .new_assert_cmd("contract") - .arg("invoke") - .arg("--id") - .arg(id) - .arg("--wasm") - .arg(HELLO_WORLD.path()) - .arg("--") - .arg("auth") - .arg(&format!("--addr={DEFAULT_PUB_KEY}")) - .arg("--world=world") - .assert() - .stdout(format!("\"{DEFAULT_PUB_KEY}\"\n")) - .success(); - - // Invoke it again without providing the contract, to exercise the deployment - sandbox - .new_assert_cmd("contract") - .arg("invoke") - .arg("--id") - .arg(id) - .arg("--") - .arg("auth") - .arg(&format!("--addr={DEFAULT_PUB_KEY}")) - .arg("--world=world") - .assert() - .stdout(format!("\"{DEFAULT_PUB_KEY}\"\n")) - .success(); -} - -async fn invoke_auth_with_identity(sandbox: &TestEnv, id: &str) { - sandbox - .cmd::("test -d ") - .run() - .await - .unwrap(); - sandbox - .new_assert_cmd("contract") - .arg("invoke") - .arg("--id") - .arg(id) - .arg("--wasm") - .arg(HELLO_WORLD.path()) - .arg("--") - .arg("auth") - .arg("--addr") - .arg(DEFAULT_PUB_KEY) - .arg("--world=world") - .assert() - .stdout(format!("\"{DEFAULT_PUB_KEY}\"\n")) - .success(); -} - -// fn invoke_auth_with_different_test_account(sandbox: &TestEnv, id: &str) { -// sandbox -// .new_assert_cmd("contract") -// .arg("invoke") -// .arg("--hd-path=1") -// .arg("--id") -// .arg(id) -// .arg("--wasm") -// .arg(HELLO_WORLD.path()) -// .arg("--") -// .arg("auth") -// .arg(&format!("--addr={DEFAULT_PUB_KEY_1}")) -// .arg("--world=world") -// .assert() -// .stdout(format!("\"{DEFAULT_PUB_KEY_1}\"\n")) -// .success(); -// } - -async fn invoke_auth_with_different_test_account_fail(sandbox: &TestEnv, id: &str) { - let res = sandbox - .invoke(&[ - "--hd-path=0", - "--id", - id, - &rpc_url_arg().unwrap_or_default(), - &network_passphrase_arg().unwrap_or_default(), - "--", - "auth", - &format!("--addr={DEFAULT_PUB_KEY_1}"), - "--world=world", - ]) - .await; - let e = res.unwrap_err(); - assert!( - matches!(e, contract::invoke::Error::Rpc(_)), - "Expected rpc error got {e:?}" - ); -} - -fn contract_data_read_failure(sandbox: &TestEnv, id: &str) { - sandbox - .new_assert_cmd("contract") - .arg("read") - .arg("--id") - .arg(id) - .arg("--key=COUNTER") - .arg("--durability=persistent") - .assert() - .failure() - .stderr( - "error: no matching contract data entries were found for the specified contract id\n", - ); -} - -#[tokio::test] -async fn contract_data_read() { - const KEY: &str = "COUNTER"; - let sandbox = &TestEnv::default(); - let id = &deploy_hello(sandbox); - let res = sandbox.invoke(&["--id", id, "--", "inc"]).await.unwrap(); - assert_eq!(res.trim(), "1"); - extend(sandbox, id, Some(KEY)).await; - - sandbox - .new_assert_cmd("contract") - .arg("read") - .arg("--id") - .arg(id) - .arg("--key") - .arg(KEY) - .arg("--durability=persistent") - .assert() - .success() - .stdout(predicates::str::starts_with("COUNTER,1")); - - sandbox - .new_assert_cmd("contract") - .arg("invoke") - .arg("--id") - .arg(id) - .arg("--") - .arg("inc") - .assert() - .success(); - - sandbox - .new_assert_cmd("contract") - .arg("read") - .arg("--id") - .arg(id) - .arg("--key") - .arg(KEY) - .arg("--durability=persistent") - .assert() - .success() - .stdout(predicates::str::starts_with("COUNTER,2")); -} - -async fn invoke_with_seed(sandbox: &TestEnv, id: &str) { - invoke_with_source(sandbox, DEFAULT_SEED_PHRASE, id).await; -} - -async fn invoke_with_sk(sandbox: &TestEnv, id: &str) { - invoke_with_source(sandbox, DEFAULT_SECRET_KEY, id).await; -} - -async fn invoke_with_id(sandbox: &TestEnv, id: &str) { - let identity = add_test_seed(sandbox.dir()); - invoke_with_source(sandbox, &identity, id).await; -} - -async fn invoke_with_source(sandbox: &TestEnv, source: &str, id: &str) { - let cmd = sandbox - .invoke(&[ - "--source-account", - source, - "--id", - id, - "--", - "hello", - "--world=world", - ]) - .await - .unwrap(); - assert_eq!(cmd, "[\"Hello\",\"world\"]"); -} - -async fn handles_kebab_case(e: &TestEnv, id: &str) { - assert!(e - .invoke(&["--id", id, "--", "multi-word-cmd", "--contract-owner=world",]) - .await - .is_ok()); -} - -async fn fetch(sandbox: &TestEnv, id: &str) { - let f = sandbox.dir().join("contract.wasm"); - let cmd = sandbox.cmd_arr::(&["--id", id, "--out-file", f.to_str().unwrap()]); - cmd.run().await.unwrap(); - assert!(f.exists()); -} - -async fn invoke_prng_u64_in_range_test(sandbox: &TestEnv, id: &str) { - assert!(sandbox - .invoke(&[ - "--id", - id, - "--wasm", - HELLO_WORLD.path().to_str().unwrap(), - "--", - "prng_u64_in_range", - "--low=0", - "--high=100", - ]) - .await - .is_ok()); -} diff --git a/cmd/crates/soroban-test/tests/it/integration/util.rs b/cmd/crates/soroban-test/tests/it/integration/util.rs deleted file mode 100644 index ea27680b..00000000 --- a/cmd/crates/soroban-test/tests/it/integration/util.rs +++ /dev/null @@ -1,119 +0,0 @@ -use soroban_cli::commands::contract; -use soroban_test::{TestEnv, Wasm}; -use std::{fmt::Display, path::Path}; - -use crate::util::{add_key, SecretKind}; - -pub const HELLO_WORLD: &Wasm = &Wasm::Custom("test-wasms", "test_hello_world"); -pub const CUSTOM_TYPES: &Wasm = &Wasm::Custom("test-wasms", "test_custom_types"); - -pub fn add_test_seed(dir: &Path) -> String { - let name = "test_seed"; - add_key( - dir, - name, - SecretKind::Seed, - "coral light army gather adapt blossom school alcohol coral light army giggle", - ); - name.to_owned() -} - -pub async fn invoke_with_roundtrip(e: &TestEnv, id: &str, func: &str, data: D) -where - D: Display, -{ - let data = data.to_string(); - println!("{data}"); - let res = e - .invoke(&["--id", id, "--", func, &format!("--{func}"), &data]) - .await - .unwrap(); - assert_eq!(res, data); -} - -pub const DEFAULT_PUB_KEY: &str = "GDIY6AQQ75WMD4W46EYB7O6UYMHOCGQHLAQGQTKHDX4J2DYQCHVCR4W4"; -pub const DEFAULT_SECRET_KEY: &str = "SC36BWNUOCZAO7DMEJNNKFV6BOTPJP7IG5PSHLUOLT6DZFRU3D3XGIXW"; - -pub const DEFAULT_PUB_KEY_1: &str = "GCKZUJVUNEFGD4HLFBUNVYM2QY2P5WQQZMGRA3DDL4HYVT5MW5KG3ODV"; -pub const TEST_SALT: &str = "f55ff16f66f43360266b95db6f8fec01d76031054306ae4a4b380598f6cfd114"; -pub const TEST_CONTRACT_ID: &str = "CBVTIVBYWAO2HNPNGKDCZW4OZYYESTKNGD7IPRTDGQSFJS4QBDQQJX3T"; - -pub fn rpc_url() -> Option { - std::env::var("SOROBAN_RPC_URL").ok() -} - -pub fn rpc_url_arg() -> Option { - rpc_url().map(|url| format!("--rpc-url={url}")) -} - -pub fn network_passphrase() -> Option { - std::env::var("SOROBAN_NETWORK_PASSPHRASE").ok() -} - -pub fn network_passphrase_arg() -> Option { - network_passphrase().map(|p| format!("--network-passphrase={p}")) -} - -pub fn deploy_hello(sandbox: &TestEnv) -> String { - deploy_contract(sandbox, HELLO_WORLD) -} - -pub fn deploy_custom(sandbox: &TestEnv) -> String { - deploy_contract(sandbox, CUSTOM_TYPES) -} - -pub fn deploy_contract(sandbox: &TestEnv, wasm: &Wasm) -> String { - let hash = wasm.hash().unwrap(); - sandbox - .new_assert_cmd("contract") - .arg("install") - .arg("--wasm") - .arg(wasm.path()) - .arg("--ignore-checks") - .assert() - .success() - .stdout(format!("{hash}\n")); - - sandbox - .new_assert_cmd("contract") - .arg("deploy") - .arg("--wasm-hash") - .arg(&format!("{hash}")) - .arg("--salt") - .arg(TEST_SALT) - .arg("--ignore-checks") - .assert() - .success() - .stdout(format!("{TEST_CONTRACT_ID}\n")); - TEST_CONTRACT_ID.to_string() -} - -pub async fn extend_contract(sandbox: &TestEnv, id: &str, wasm: &Wasm<'_>) { - extend(sandbox, id, None).await; - let cmd: contract::extend::Cmd = sandbox.cmd_arr(&[ - "--wasm-hash", - wasm.hash().unwrap().to_string().as_str(), - "--durability", - "persistent", - "--ledgers-to-extend", - "100000", - ]); - cmd.run().await.unwrap(); -} - -pub async fn extend(sandbox: &TestEnv, id: &str, value: Option<&str>) { - let mut args = vec![ - "--id", - id, - "--durability", - "persistent", - "--ledgers-to-extend", - "100000", - ]; - if let Some(value) = value { - args.push("--key"); - args.push(value); - } - let cmd: contract::extend::Cmd = sandbox.cmd_arr(&args); - cmd.run().await.unwrap(); -} diff --git a/cmd/crates/soroban-test/tests/it/integration/wrap.rs b/cmd/crates/soroban-test/tests/it/integration/wrap.rs deleted file mode 100644 index a69e70c7..00000000 --- a/cmd/crates/soroban-test/tests/it/integration/wrap.rs +++ /dev/null @@ -1,97 +0,0 @@ -use soroban_cli::CommandParser; -use soroban_cli::{ - commands::{contract::deploy::asset, keys}, - utils::contract_id_hash_from_asset, -}; -use soroban_test::TestEnv; - -use super::util::network_passphrase; - -#[tokio::test] -#[ignore] -async fn burn() { - let sandbox = &TestEnv::default(); - let network_passphrase = network_passphrase().unwrap(); - println!("NETWORK_PASSPHRASE: {network_passphrase:?}"); - let address = keys::address::Cmd::parse("test") - .unwrap() - .public_key() - .unwrap(); - let asset = format!("native:{address}"); - wrap_cmd(&asset).run().await.unwrap(); - let asset = soroban_cli::utils::parsing::parse_asset(&asset).unwrap(); - let hash = contract_id_hash_from_asset(&asset, &network_passphrase).unwrap(); - let id = stellar_strkey::Contract(hash.0).to_string(); - assert_eq!( - "CAMTHSPKXZJIRTUXQP5QWJIFH3XIDMKLFAWVQOFOXPTKAW5GKV37ZC4N", - id - ); - assert_eq!( - "true", - sandbox - .invoke(&[ - "--id", - &id, - "--source=test", - "--", - "authorized", - "--id", - &address.to_string() - ]) - .await - .unwrap() - ); - assert_eq!( - "\"9223372036854775807\"", - sandbox - .invoke(&[ - "--id", - &id, - "--source", - "test", - "--", - "balance", - "--id", - &address.to_string() - ]) - .await - .unwrap(), - ); - - println!( - "{}", - sandbox - .invoke(&[ - "--id", - &id, - "--source=test", - "--", - "burn", - "--id", - &address.to_string(), - "--amount=100" - ]) - .await - .unwrap() - ); - - assert_eq!( - "\"9223372036854775707\"", - sandbox - .invoke(&[ - "--id", - &id, - "--source=test", - "--", - "balance", - "--id", - &address.to_string() - ]) - .await - .unwrap(), - ); -} - -fn wrap_cmd(asset: &str) -> asset::Cmd { - asset::Cmd::parse_arg_vec(&["--source=test", &format!("--asset={asset}")]).unwrap() -} diff --git a/cmd/crates/soroban-test/tests/it/lab_test_transaction_envelope.txt b/cmd/crates/soroban-test/tests/it/lab_test_transaction_envelope.txt deleted file mode 100644 index 6cd59769..00000000 --- a/cmd/crates/soroban-test/tests/it/lab_test_transaction_envelope.txt +++ /dev/null @@ -1,54 +0,0 @@ -TransactionEnvelope( - Tx( - TransactionV1Envelope { - tx: Transaction { - source_account: Ed25519( - Uint256(7376fde88e4cd61cc0fb294a1786b3f1d061f5f2f1ca57465faa932211b946d6), - ), - fee: 100, - seq_num: SequenceNumber( - 1, - ), - cond: Time( - TimeBounds { - min_time: TimePoint( - 0, - ), - max_time: TimePoint( - 0, - ), - }, - ), - memo: None, - operations: VecM( - [ - Operation { - source_account: None, - body: CreateAccount( - CreateAccountOp { - destination: AccountId( - PublicKeyTypeEd25519( - Uint256(d18f0210ff6cc1f2dcf1301fbbd4c30ee11a075820684d471df89d0f1011ea28), - ), - ), - starting_balance: 1000000000000, - }, - ), - }, - ], - ), - ext: V0, - }, - signatures: VecM( - [ - DecoratedSignature { - hint: SignatureHint(11b946d6), - signature: Signature( - BytesM(a004a6e9b64c687f3f62b4fde3b1797c35786106e5f97f16dd9afe3ed850df87dd736390501f62726f7e99af4ec358a8fb281cab9f811a43989b8085dd312609), - ), - }, - ], - ), - }, - ), -) diff --git a/cmd/crates/soroban-test/tests/it/main.rs b/cmd/crates/soroban-test/tests/it/main.rs deleted file mode 100644 index a6b18cb2..00000000 --- a/cmd/crates/soroban-test/tests/it/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -mod arg_parsing; -mod config; -mod help; -#[cfg(feature = "integration")] -mod integration; -mod plugin; -mod util; -mod version; diff --git a/cmd/crates/soroban-test/tests/it/plugin.rs b/cmd/crates/soroban-test/tests/it/plugin.rs deleted file mode 100644 index 7d55d1e5..00000000 --- a/cmd/crates/soroban-test/tests/it/plugin.rs +++ /dev/null @@ -1,77 +0,0 @@ -/* -This function calls the soroban executable via cargo and checks that the output -is correct. The PATH environment variable is set to include the target/bin -directory, so that the soroban executable can be found. -*/ - -use std::{ffi::OsString, path::PathBuf}; - -#[test] -fn soroban_hello() { - // Add the target/bin directory to the iterator of paths - let paths = get_paths(); - // Call soroban with the PATH variable set to include the target/bin directory - assert_cmd::Command::cargo_bin("soroban") - .unwrap_or_else(|_| assert_cmd::Command::new("soroban")) - .arg("hello") - .env("PATH", &paths) - .assert() - .stdout("Hello, world!\n"); -} - -#[test] -fn list() { - // Call `soroban --list` with the PATH variable set to include the target/bin directory - assert_cmd::Command::cargo_bin("soroban") - .unwrap_or_else(|_| assert_cmd::Command::new("soroban")) - .arg("--list") - .env("PATH", get_paths()) - .assert() - .stdout(predicates::str::contains("hello")); -} - -#[test] -#[cfg(not(unix))] -fn has_no_path() { - // Call soroban with the PATH variable set to include just target/bin directory - assert_cmd::Command::cargo_bin("soroban") - .unwrap_or_else(|_| assert_cmd::Command::new("soroban")) - .arg("hello") - .env("PATH", &target_bin()) - .assert() - .stdout("Hello, world!\n"); -} - -#[test] -fn has_no_path_failure() { - // Call soroban with the PATH variable set to include just target/bin directory - assert_cmd::Command::cargo_bin("soroban") - .unwrap_or_else(|_| assert_cmd::Command::new("soroban")) - .arg("hello") - .assert() - .stderr(predicates::str::contains("error: no such command: `hello`")); -} - -fn target_bin() -> PathBuf { - // Get the current working directory - let current_dir = std::env::current_dir().unwrap(); - - // Create a path to the target/bin directory - current_dir - .join("../../../target/bin") - .canonicalize() - .unwrap() -} - -fn get_paths() -> OsString { - let target_bin_path = target_bin(); - // Get the current PATH environment variable - let path_key = std::env::var_os("PATH"); - if let Some(path_key) = path_key { - // Create an iterator of paths from the PATH environment variable - let current_paths = std::env::split_paths(&path_key); - std::env::join_paths(current_paths.chain(vec![target_bin_path])).unwrap() - } else { - target_bin_path.into() - } -} diff --git a/cmd/crates/soroban-test/tests/it/util.rs b/cmd/crates/soroban-test/tests/it/util.rs deleted file mode 100644 index 112d5f84..00000000 --- a/cmd/crates/soroban-test/tests/it/util.rs +++ /dev/null @@ -1,72 +0,0 @@ -use std::path::Path; - -use soroban_cli::commands::{ - config::{locator::KeyType, secret::Secret}, - contract, -}; -use soroban_test::{TestEnv, Wasm}; - -pub const CUSTOM_TYPES: &Wasm = &Wasm::Custom("test-wasms", "test_custom_types"); - -#[derive(Clone)] -pub enum SecretKind { - Seed, - Key, -} - -#[allow(clippy::needless_pass_by_value)] -pub fn add_key(dir: &Path, name: &str, kind: SecretKind, data: &str) { - let secret = match kind { - SecretKind::Seed => Secret::SeedPhrase { - seed_phrase: data.to_string(), - }, - SecretKind::Key => Secret::SecretKey { - secret_key: data.to_string(), - }, - }; - - KeyType::Identity - .write(name, &secret, &dir.join(".soroban")) - .unwrap(); -} - -pub fn add_test_id(dir: &Path) -> String { - let name = "test_id"; - add_key( - dir, - name, - SecretKind::Key, - "SBGWSG6BTNCKCOB3DIFBGCVMUPQFYPA2G4O34RMTB343OYPXU5DJDVMN", - ); - name.to_owned() -} - -pub const DEFAULT_SEED_PHRASE: &str = - "coral light army gather adapt blossom school alcohol coral light army giggle"; - -#[allow(dead_code)] -pub async fn invoke_custom( - sandbox: &TestEnv, - id: &str, - func: &str, - arg: &str, - wasm: &Path, -) -> Result { - let mut i: contract::invoke::Cmd = sandbox.cmd_arr(&[ - "--id", - id, - "--network", - "futurenet", - "--source", - "default", - "--", - func, - arg, - ]); - i.wasm = Some(wasm.to_path_buf()); - i.config.network.network = Some("futurenet".to_owned()); - i.invoke(&soroban_cli::commands::global::Args::default()) - .await -} - -pub const DEFAULT_CONTRACT_ID: &str = "CDR6QKTWZQYW6YUJ7UP7XXZRLWQPFRV6SWBLQS4ZQOSAF4BOUD77OO5Z"; diff --git a/cmd/crates/soroban-test/tests/it/version.rs b/cmd/crates/soroban-test/tests/it/version.rs deleted file mode 100644 index cb7826fa..00000000 --- a/cmd/crates/soroban-test/tests/it/version.rs +++ /dev/null @@ -1,12 +0,0 @@ -use soroban_cli::commands::version::long; -use soroban_test::TestEnv; - -#[test] -fn version() { - let sandbox = TestEnv::default(); - sandbox - .new_assert_cmd("version") - .assert() - .success() - .stdout(format!("soroban {}\n", long())); -} diff --git a/cmd/soroban-rpc/internal/test/cli_test.go b/cmd/soroban-rpc/internal/test/cli_test.go deleted file mode 100644 index d1a5b901..00000000 --- a/cmd/soroban-rpc/internal/test/cli_test.go +++ /dev/null @@ -1,383 +0,0 @@ -package test - -import ( - "context" - "crypto/sha256" - "encoding/hex" - "fmt" - "os" - "strconv" - "strings" - "testing" - - "github.com/creachadair/jrpc2" - "github.com/creachadair/jrpc2/jhttp" - "github.com/google/shlex" - "github.com/stellar/go/keypair" - "github.com/stellar/go/strkey" - "github.com/stellar/go/txnbuild" - "github.com/stellar/go/xdr" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gotest.tools/v3/icmd" - - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/methods" -) - -func cargoTest(t *testing.T, name string) { - NewCLITest(t) - c := icmd.Command("cargo", "test", "--features", "integration", "--package", "soroban-test", "--test", "it", "--", name, "--exact", "--nocapture") - c.Env = append(os.Environ(), - fmt.Sprintf("SOROBAN_RPC_URL=http://localhost:%d/", sorobanRPCPort), - fmt.Sprintf("SOROBAN_NETWORK_PASSPHRASE=%s", StandaloneNetworkPassphrase), - ) - res := icmd.RunCmd(c) - require.NoError(t, res.Error, res.Stdout(), res.Stderr()) -} - -func TestCLICargoTest(t *testing.T) { - names := icmd.RunCmd(icmd.Command("cargo", "-q", "test", "integration::", "--package", "soroban-test", "--features", "integration", "--", "--list")) - input := names.Stdout() - lines := strings.Split(strings.TrimSpace(input), "\n") - for _, line := range lines { - testName := strings.TrimSuffix(line, ": test") - t.Run(testName, func(t *testing.T) { - cargoTest(t, testName) - }) - } -} - -func TestCLIWrapCustom(t *testing.T) { - it := NewCLITest(t) - assetCode := "deadbeef" - issuerAccount := getCLIDefaultAccount(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract asset deploy --asset=%s:%s", assetCode, issuerAccount)) - require.Equal(t, "true", runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id=%s -- authorized --id=%s", strkeyContractID, issuerAccount))) - asset := txnbuild.CreditAsset{ - Code: assetCode, - Issuer: issuerAccount, - } - establishAccountTrustline(t, it, it.MasterKey(), it.MasterAccount(), asset) - masterAccount := keypair.Root(StandaloneNetworkPassphrase).Address() - runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id=%s -- mint --to=%s --amount 1", strkeyContractID, masterAccount)) -} - -func TestCLIWrapNative(t *testing.T) { - NewCLITest(t) - testAccount := getCLIDefaultAccount(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract asset deploy --asset=native:%s", testAccount)) - require.Equal(t, "CAMTHSPKXZJIRTUXQP5QWJIFH3XIDMKLFAWVQOFOXPTKAW5GKV37ZC4N", strkeyContractID) - require.Equal(t, "true", runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id=%s -- authorized --id=%s", strkeyContractID, testAccount))) - require.Equal(t, "\"9223372036854775807\"", runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id=%s -- balance --id %s", strkeyContractID, testAccount))) -} - -func TestCLIContractInstall(t *testing.T) { - NewCLITest(t) - output := runSuccessfulCLICmd(t, fmt.Sprintf("contract install --wasm %s --ignore-checks", helloWorldContractPath)) - wasm := getHelloWorldContract(t) - contractHash := xdr.Hash(sha256.Sum256(wasm)) - require.Contains(t, output, contractHash.HexString()) -} - -func TestCLIContractInstallAndDeploy(t *testing.T) { - NewCLITest(t) - runSuccessfulCLICmd(t, fmt.Sprintf("contract install --wasm %s --ignore-checks", helloWorldContractPath)) - wasm := getHelloWorldContract(t) - contractHash := xdr.Hash(sha256.Sum256(wasm)) - output := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt %s --wasm-hash %s --ignore-checks", hex.EncodeToString(testSalt[:]), contractHash.HexString())) - outputsContractIDInLastLine(t, output) -} - -func TestCLIContractDeploy(t *testing.T) { - NewCLITest(t) - output := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt %s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) - outputsContractIDInLastLine(t, output) -} - -func outputsContractIDInLastLine(t *testing.T, output string) { - lines := strings.Split(output, "\n") - nonEmptyLines := make([]string, 0, len(lines)) - for _, l := range lines { - if l != "" { - nonEmptyLines = append(nonEmptyLines, l) - } - } - require.GreaterOrEqual(t, len(nonEmptyLines), 1) - contractID := nonEmptyLines[len(nonEmptyLines)-1] - require.Len(t, contractID, 56) - require.Regexp(t, "^C", contractID) -} - -func TestCLIContractDeployAndInvoke(t *testing.T) { - NewCLITest(t) - contractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) - output := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- hello --world=world", contractID)) - require.Contains(t, output, `["Hello","world"]`) -} - -func TestCLIRestorePreamble(t *testing.T) { - test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) - count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) - require.Equal(t, "1", count) - count = runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) - require.Equal(t, "2", count) - - // Wait for the counter ledger entry to ttl and successfully invoke the `inc` contract function again - // This ensures that the CLI restores the entry (using the RestorePreamble in the simulateTransaction response) - ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) - client := jrpc2.NewClient(ch, nil) - waitUntilLedgerEntryTTL(t, client, getCounterLedgerKey(parseContractStrKey(t, strkeyContractID))) - - count = runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) - require.Equal(t, "3", count) -} - -func TestCLIExtend(t *testing.T) { - test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) - count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) - require.Equal(t, "1", count) - - ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) - client := jrpc2.NewClient(ch, nil) - - ttlKey := getCounterLedgerKey(parseContractStrKey(t, strkeyContractID)) - initialLiveUntilSeq := getLedgerEntryLiveUntil(t, client, ttlKey) - - extendOutput := runSuccessfulCLICmd( - t, - fmt.Sprintf( - "contract extend --id %s --key COUNTER --durability persistent --ledgers-to-extend 20", - strkeyContractID, - ), - ) - - newLiveUntilSeq := getLedgerEntryLiveUntil(t, client, ttlKey) - assert.Greater(t, newLiveUntilSeq, initialLiveUntilSeq) - assert.Equal(t, fmt.Sprintf("New ttl ledger: %d", newLiveUntilSeq), extendOutput) -} -func TestCLIExtendTooLow(t *testing.T) { - test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) - count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) - require.Equal(t, "1", count) - - ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) - client := jrpc2.NewClient(ch, nil) - - ttlKey := getCounterLedgerKey(parseContractStrKey(t, strkeyContractID)) - initialLiveUntilSeq := parseInt(t, getLedgerEntryLiveUntil(t, client, ttlKey).GoString()) - - extendOutput := extend(t, strkeyContractID, "400", "--key COUNTER ") - - newLiveUntilSeq := parseInt(t, getLedgerEntryLiveUntil(t, client, ttlKey).GoString()) - assert.Greater(t, newLiveUntilSeq, initialLiveUntilSeq) - assert.Equal(t, newLiveUntilSeq, extendOutput) - - updatedLiveUntilSeq := extend(t, strkeyContractID, "15", "--key COUNTER") - assert.Equal(t, extendOutput, updatedLiveUntilSeq) -} - -func TestCLIExtendTooHigh(t *testing.T) { - test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) - count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) - require.Equal(t, "1", count) - - ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) - client := jrpc2.NewClient(ch, nil) - - ttlKey := getCounterLedgerKey(parseContractStrKey(t, strkeyContractID)) - initialLiveUntilSeq := parseInt(t, getLedgerEntryLiveUntil(t, client, ttlKey).GoString()) - - extendOutput := extend(t, strkeyContractID, "100000000", "--key COUNTER ") - - newLiveUntilSeq := parseInt(t, getLedgerEntryLiveUntil(t, client, ttlKey).GoString()) - assert.Greater(t, newLiveUntilSeq, initialLiveUntilSeq) - assert.Equal(t, newLiveUntilSeq, extendOutput) -} - -func TestCLIRestore(t *testing.T) { - test := NewCLITest(t) - strkeyContractID := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --salt=%s --wasm %s --ignore-checks", hex.EncodeToString(testSalt[:]), helloWorldContractPath)) - count := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", strkeyContractID)) - require.Equal(t, "1", count) - - ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) - client := jrpc2.NewClient(ch, nil) - - ttlKey := getCounterLedgerKey(parseContractStrKey(t, strkeyContractID)) - initialLiveUntilSeq := getLedgerEntryLiveUntil(t, client, ttlKey) - // Wait for the counter ledger entry to ttl and successfully invoke the `inc` contract function again - // This ensures that the CLI restores the entry (using the RestorePreamble in the simulateTransaction response) - waitUntilLedgerEntryTTL(t, client, ttlKey) - - restoreOutput := runSuccessfulCLICmd( - t, - fmt.Sprintf( - "contract restore --id %s --key COUNTER --durability persistent", - strkeyContractID, - ), - ) - - newLiveUntilSeq := getLedgerEntryLiveUntil(t, client, getCounterLedgerKey(parseContractStrKey(t, strkeyContractID))) - assert.Greater(t, newLiveUntilSeq, initialLiveUntilSeq) - assert.Equal(t, fmt.Sprintf("New ttl ledger: %d", newLiveUntilSeq), restoreOutput) - - // FIXME: the following checks shouldn't live here: - - // test to see that we get an error when requesting the ttl ledger entry explicitly. - ledgerTTLEntry := getTtlKey(t, getCounterLedgerKey(parseContractStrKey(t, strkeyContractID))) - ledgerTTLEntryB64, err := xdr.MarshalBase64(ledgerTTLEntry) - require.NoError(t, err) - var getLedgerEntryResult methods.GetLedgerEntryResponse - err = client.CallResult(context.Background(), "getLedgerEntry", methods.GetLedgerEntryRequest{ - Key: ledgerTTLEntryB64, - }, &getLedgerEntryResult) - require.Error(t, err) - require.Contains(t, err.Error(), methods.ErrLedgerTtlEntriesCannotBeQueriedDirectly) - - // repeat with getLedgerEntries - var getLedgerEntriesResult methods.GetLedgerEntriesResponse - err = client.CallResult(context.Background(), "getLedgerEntries", methods.GetLedgerEntriesRequest{ - Keys: []string{ledgerTTLEntryB64}, - }, &getLedgerEntriesResult) - require.Error(t, err) - require.Contains(t, err.Error(), methods.ErrLedgerTtlEntriesCannotBeQueriedDirectly) -} - -func getTtlKey(t *testing.T, key xdr.LedgerKey) xdr.LedgerKey { - assert.True(t, key.Type == xdr.LedgerEntryTypeContractCode || key.Type == xdr.LedgerEntryTypeContractData) - binKey, err := key.MarshalBinary() - assert.NoError(t, err) - return xdr.LedgerKey{ - Type: xdr.LedgerEntryTypeTtl, - Ttl: &xdr.LedgerKeyTtl{ - KeyHash: sha256.Sum256(binKey), - }, - } -} - -func parseContractStrKey(t *testing.T, strkeyContractID string) [32]byte { - contractIDBytes := strkey.MustDecode(strkey.VersionByteContract, strkeyContractID) - var contractID [32]byte - require.Len(t, contractIDBytes, len(contractID)) - copy(contractID[:], contractIDBytes) - return contractID -} - -func runSuccessfulCLICmd(t *testing.T, cmd string) string { - res := runCLICommand(t, cmd) - stdout, stderr := res.Stdout(), res.Stderr() - outputs := fmt.Sprintf("stderr:\n%s\nstdout:\n%s\n", stderr, stdout) - require.NoError(t, res.Error, outputs) - fmt.Print(outputs) - return strings.TrimSpace(stdout) -} - -func runCLICommand(t *testing.T, cmd string) *icmd.Result { - args := []string{"-q", "--vv"} - parsedArgs, err := shlex.Split(cmd) - require.NoError(t, err, cmd) - args = append(args, parsedArgs...) - c := icmd.Command("soroban", args...) - c.Env = append(os.Environ(), - fmt.Sprintf("SOROBAN_RPC_URL=http://localhost:%d/", sorobanRPCPort), - fmt.Sprintf("SOROBAN_NETWORK_PASSPHRASE=%s", StandaloneNetworkPassphrase), - "SOROBAN_ACCOUNT=test", - ) - return icmd.RunCmd(c) -} - -func getCLIDefaultAccount(t *testing.T) string { - runSuccessfulCLICmd(t, "keys generate -d test --no-fund") - return "GDIY6AQQ75WMD4W46EYB7O6UYMHOCGQHLAQGQTKHDX4J2DYQCHVCR4W4" -} - -func NewCLITest(t *testing.T) *Test { - test := NewTest(t, nil) - fundAccount(t, test, getCLIDefaultAccount(t), "1000000") - return test -} - -func fundAccount(t *testing.T, test *Test, account string, amount string) { - ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) - client := jrpc2.NewClient(ch, nil) - - tx, err := txnbuild.NewTransaction(txnbuild.TransactionParams{ - SourceAccount: test.MasterAccount(), - IncrementSequenceNum: true, - Operations: []txnbuild.Operation{&txnbuild.CreateAccount{ - Destination: account, - Amount: amount, - }}, - BaseFee: txnbuild.MinBaseFee, - Memo: nil, - Preconditions: txnbuild.Preconditions{ - TimeBounds: txnbuild.NewInfiniteTimeout(), - }, - }) - require.NoError(t, err) - sendSuccessfulTransaction(t, client, test.MasterKey(), tx) -} - -func establishAccountTrustline(t *testing.T, test *Test, kp *keypair.Full, account txnbuild.Account, asset txnbuild.Asset) { - ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) - client := jrpc2.NewClient(ch, nil) - - line := asset.MustToChangeTrustAsset() - tx, err := txnbuild.NewTransaction(txnbuild.TransactionParams{ - SourceAccount: account, - IncrementSequenceNum: true, - Operations: []txnbuild.Operation{&txnbuild.ChangeTrust{ - Line: line, - Limit: "2000", - }}, - BaseFee: txnbuild.MinBaseFee, - Memo: nil, - Preconditions: txnbuild.Preconditions{ - TimeBounds: txnbuild.NewInfiniteTimeout(), - }, - }) - require.NoError(t, err) - sendSuccessfulTransaction(t, client, kp, tx) -} - -func parseInt(t *testing.T, s string) uint64 { - i, err := strconv.ParseUint(strings.TrimSpace(s), 10, 64) - require.NoError(t, err) - return i -} - -func extend(t *testing.T, contractId string, amount string, rest string) uint64 { - - res := runSuccessfulCLICmd( - t, - fmt.Sprintf( - "contract extend --ttl-ledger-only --id=%s --durability persistent --ledgers-to-extend=%s %s", - contractId, - amount, - rest, - ), - ) - - return parseInt(t, res) -} - -func getLedgerEntryLiveUntil(t *testing.T, client *jrpc2.Client, ttlLedgerKey xdr.LedgerKey) xdr.Uint32 { - keyB64, err := xdr.MarshalBase64(ttlLedgerKey) - require.NoError(t, err) - getLedgerEntryrequest := methods.GetLedgerEntryRequest{ - Key: keyB64, - } - var getLedgerEntryResult methods.GetLedgerEntryResponse - err = client.CallResult(context.Background(), "getLedgerEntry", getLedgerEntryrequest, &getLedgerEntryResult) - require.NoError(t, err) - var entry xdr.LedgerEntryData - require.NoError(t, xdr.SafeUnmarshalBase64(getLedgerEntryResult.XDR, &entry)) - - require.Contains(t, []xdr.LedgerEntryType{xdr.LedgerEntryTypeContractCode, xdr.LedgerEntryTypeContractData}, entry.Type) - require.NotNil(t, getLedgerEntryResult.LiveUntilLedgerSeq) - return xdr.Uint32(*getLedgerEntryResult.LiveUntilLedgerSeq) -} From c1dd6f8366cef68c72ea6192148adce2a177235b Mon Sep 17 00:00:00 2001 From: pritsheth Date: Fri, 16 Feb 2024 13:30:57 -0800 Subject: [PATCH 2/6] Update rust.yml --- .github/workflows/rust.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 6070106c..b0ca055b 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -74,3 +74,9 @@ jobs: run: sudo apt-get update && sudo apt-get -y install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu - run: cargo clippy --all-targets --target ${{ matrix.target }} - run: make build-test + - if: startsWith(matrix.target, 'x86_64') + # specify directories explicitly to avoid building the preflight library (otherwise it will fail with missing symbols) + run: | + for I in cmd/crates/* ; do + cargo test --target ${{ matrix.target }} --manifest-path $I/Cargo.toml + done From 11de16e821286bd39d0711ad8aaa17bc8a2f39a8 Mon Sep 17 00:00:00 2001 From: pritsheth Date: Fri, 16 Feb 2024 14:05:48 -0800 Subject: [PATCH 3/6] Remove build-test-wasms from makefile --- Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index f0ad7e89..5a90fe5d 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ Cargo.lock: Cargo.toml # cargo install soroban-cli --version 20.2.0 # cargo install --path ./cmd/crates/soroban-test/tests/fixtures/hello --root ./target --debug --quiet -install: install_rust build-libpreflight +install: build-libpreflight go install -ldflags="${GOLDFLAGS}" ${MACOS_MIN_VER} ./... build_rust: Cargo.lock @@ -58,12 +58,12 @@ build: build_rust build_go build-libpreflight: Cargo.lock cd cmd/soroban-rpc/lib/preflight && cargo build --target $(CARGO_BUILD_TARGET) --profile release-with-panic-unwind -build-test-wasms: Cargo.lock - cargo build --package 'test_*' --profile test-wasms --target wasm32-unknown-unknown +#build-test-wasms: Cargo.lock + #cargo build --package 'test_*' --profile test-wasms --target wasm32-unknown-unknown -build-test: build-test-wasms install_rust +#build-test: build-test-wasms install_rust -test: build-test +test: cargo test e2e-test: From 4b07a2bfac2b1ab47c253fb91ba66410543a12fe Mon Sep 17 00:00:00 2001 From: pritsheth Date: Fri, 16 Feb 2024 14:39:28 -0800 Subject: [PATCH 4/6] Uncomment install_rust --- Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 5a90fe5d..278f6713 100644 --- a/Makefile +++ b/Makefile @@ -40,11 +40,11 @@ CARGO_BUILD_TARGET ?= $(shell rustc -vV | sed -n 's|host: ||p') Cargo.lock: Cargo.toml cargo update --workspace -#install_rust: Cargo.lock -# cargo install soroban-cli --version 20.2.0 -# cargo install --path ./cmd/crates/soroban-test/tests/fixtures/hello --root ./target --debug --quiet +install_rust: Cargo.lock + #cargo install soroban-cli --version 20.2.0 + #cargo install --path ./cmd/crates/soroban-test/tests/fixtures/hello --root ./target --debug --quiet -install: build-libpreflight +install: install_rust build-libpreflight go install -ldflags="${GOLDFLAGS}" ${MACOS_MIN_VER} ./... build_rust: Cargo.lock @@ -58,12 +58,12 @@ build: build_rust build_go build-libpreflight: Cargo.lock cd cmd/soroban-rpc/lib/preflight && cargo build --target $(CARGO_BUILD_TARGET) --profile release-with-panic-unwind -#build-test-wasms: Cargo.lock +build-test-wasms: Cargo.lock #cargo build --package 'test_*' --profile test-wasms --target wasm32-unknown-unknown -#build-test: build-test-wasms install_rust +build-test: build-test-wasms install_rust -test: +test: build-test cargo test e2e-test: From 6a700d0a78609dc8445ba411ac0fbde41c381cda Mon Sep 17 00:00:00 2001 From: George Kudrayvtsev Date: Fri, 16 Feb 2024 14:50:33 -0800 Subject: [PATCH 5/6] Add hardcoded WASM file and reference it in tests --- .../internal/preflight/preflight_test.go | 4 ++-- cmd/soroban-rpc/internal/test/integration.go | 2 +- wasms/test_hello_world.wasm | Bin 0 -> 6796 bytes 3 files changed, 3 insertions(+), 3 deletions(-) create mode 100755 wasms/test_hello_world.wasm diff --git a/cmd/soroban-rpc/internal/preflight/preflight_test.go b/cmd/soroban-rpc/internal/preflight/preflight_test.go index 57a2e82b..601901ff 100644 --- a/cmd/soroban-rpc/internal/preflight/preflight_test.go +++ b/cmd/soroban-rpc/internal/preflight/preflight_test.go @@ -227,10 +227,10 @@ var mockLedgerEntries = func() []xdr.LedgerEntry { var helloWorldContract = func() []byte { _, filename, _, _ := runtime.Caller(0) testDirName := path.Dir(filename) - contractFile := path.Join(testDirName, "../../../../target/wasm32-unknown-unknown/test-wasms/test_hello_world.wasm") + contractFile := path.Join(testDirName, "../../../../wasms/test_hello_world.wasm") ret, err := os.ReadFile(contractFile) if err != nil { - log.Fatalf("unable to read test_hello_world.wasm (%v) please run `make build-test-wasms` at the project root directory", err) + log.Fatalf("unable to read test_hello_world.wasm (%v) please get it from `soroban-tools`", err) } return ret }() diff --git a/cmd/soroban-rpc/internal/test/integration.go b/cmd/soroban-rpc/internal/test/integration.go index d3755a9c..25096cda 100644 --- a/cmd/soroban-rpc/internal/test/integration.go +++ b/cmd/soroban-rpc/internal/test/integration.go @@ -43,7 +43,7 @@ const ( checkpointFrequency = 8 sorobanRPCPort = 8000 adminPort = 8080 - helloWorldContractPath = "../../../../target/wasm32-unknown-unknown/test-wasms/test_hello_world.wasm" + helloWorldContractPath = "../../../../wasms/test_hello_world.wasm" ) type TestConfig struct { diff --git a/wasms/test_hello_world.wasm b/wasms/test_hello_world.wasm new file mode 100755 index 0000000000000000000000000000000000000000..b3731d44efd34f6042fbb85a9c9c23a053dcc4c3 GIT binary patch literal 6796 zcmcIpdvKgp6~Fg>-)=Vf(r`l}jctXyOL0;q*-go#lyS(nGi_nYFn|jFx7}nn$!<2g zad*?gsNE7u0fj1xSa2M0z^TqqpQG|pf}%VWsaga@fzcU<@edy}_=kVt@0{E z+?jm$bxqK!m{1#d~4aA_&MuSR-1~Z1$M|nG+J<5!6elD||EfR#3O_&7i-+qZK)h{wcW&-#pVSQor@F8*JN-#o`@y+)m(6 zDb*=Nm(%44p}Ljoj@kAm+wM6hj-T%BwR?Jd&h4}N`upG0-)DFB_V#M3_u0+ETSCQdX%tEw=YA)~mC*rSZ{RshX?jtFuM%e!a9f zThAAYpsY6Q`RS$@>{(c|pDR`i zmUMEtxnh1XHrYXT>M#j_2$pG`bl;I5Pbqgr?1ebx#`kTKS;#P!{v%7Xx|PEn5?w#@yQGtqNn8Kk zYtnoc&qvb==in+7Vm=BnqsCRYi5WSrV7-aCiL(ASNl0N}zzA22D~+PNZ0vExQ2CTQ zRAPcVl!0RNDchiO<<@c44=EvhH~pWdb*+ON%zQOaH4^KZR8)wh#R$tGq4yA~*KCqT zWm}(2DuxQq@EqBFj^jRf^9p<=>E21D{tNXA=dx9XC?7wF_Apii+zUjipQY~>EL#Xd zPRd|`C455Zdx<1vWu;!B+9tr9l%B&-=hOc1JMxySeI4|)vgY=aN#)8UoC>;+D;ovY z4C+F+J!^b4(hfxWd6K3)-#Q7?!9aeNNLp<=8q3kNx`c_;Cy2#KQU^(3b+Noc|9}SI zb3dnYi}SLSRuEg6wXtQhAMLhPU#Oere1r|kJu3~s6R zZ^iPVr{CDF)l9|86a|B7n?Wt6CM}q?2LRdR!up57jLL15!DnL<(34XqW8K0b>;NX3 zuGCL>#BDL331YsV%^rkz%Ry!9$BELpTUnF|RABFlhzt(bl(ZuZF@=X38_p4kC03ro zuHH*)3jZ*wOxR#WNkzpfTJCm22!r(Dl56cS?ebt6O~vL@aTAYV+74p@QylgZOcxu} z;t@xQ-6g9;Ahe`zEC5a|43=Kqr6IR!pQ9LxBm6&|{oiw+>h0m$e`Xa#Wy0WLeJ(Sdj<>$@W?wx<{plTz?;c(ec(+%o`lJs331w3={Q zMnX^!B2XbLUDl71Bywv(NCe&u7$ul}B+|YXejp-nq#FdFv7P&6rL=0tgwEP=7pOfyJ^~pQ4SsusKMdaYOQ^1PaS5ZOw(FA4f) z%KCFO4YY#`7~ic2F`@7L9@#FRjQym|wFmS`;-0X;9?FD6>*K6DIX{a!y~f9{jlvHr z5W0ATg>uDifh6D^fH)rE@EFJO<_jd7#YT`gA6X?)ZoFB1*Eg3AZL2nmZ?MWT#5t>+ zU6D}uZzweKUx}&_`W~M(aDC^Bh!OUMjAw6MKMAyfSNVshRT{i&vo_oVA358s(-M)b zf}BqIZ zU-mViHqs0W!UwLmDh0`409lI%JW797o6XXk2x0P*e;#`10uZKqg_ zMHdVhGEc{P?*al3qw58A;Jj)qzF|1mw`V>qpyj(0NOmYOffUOJO;}AS_FHTp-SM!^ z;G78?qni;(0xxySN<~{K9I8z$mY*&fNO~!y|3CuOBw`YWEF9nY{)i){cjZF_{E`Tg zF*l-9TmOz^>(}Y)nti9}#7e-l>B`4dz!CR-`3PLJQEf3dpxA~y|Lj^x3%d-hsv#f#!PHo6b& zypMrGzd}4)oc$Yn0ByE#eA;N)3xFbd!8eJK7oThn7afNUnC2b%v2wp9D*Y!`EL8gp zH#gMtd0)?v{w1dGW~=q-_QtQd5nQ!!llo2j=*!#)#k|T*vYx?-94W+n3y?nLt%Fg1 zMS}~NuRC<}#zV_Ibn!X@jTKB`2UFa_#4r%+tdDY|3k`j1R6WL3*ut)$Z)@kcy}fZq z#PjK>`kAPDXFK&>+~^e9TWDL9&ZCqn!{hJTh;TdiBM$I%Voj<^qsVb73lXArHgPQ5 za}=OfID{z~6iBLAN{beSBHHK1O9Rb7IRIjj128mDrbWl@p#SU% zCHt~>9lh_Zx9<7J%@4J_(0cgRw@)np`^3Xfpp8|0T}k1+e4bJ1x!OW8JzK2RXN&3K zN^Lq{Nl)kNv$b@+I9qBo>o=tv_33n}S}5K)JYCN>i;dw@ZD@REWTLQh=hRewWGs^z znMpTl_1aXvI@Bo45ADnhUot$xeDo?hTyKc*mv1(U3yV$DteJeFU=Ed5Vi$ z=+YBxrNBB?N>fmgd--*jXYP65+rQ?`@h%Hsa%VYfuC{ z9aFVhrI@c06ZHji1>@B3y>k1;aJx{bqwJ$W{MvQ#=MBebyzP0Mn*1aAwqK`$pUwUD z+Oc&W)0vXNC0=$GA>uy2Jy)8YL!H_rE9j@;vmfCjEbO^_1ANxsL1&1#?YH)&o`y&^ z{leAF)ecpQgbcZE^tiCDiut(4T06;a6ZGnkK zytO~SH*ln4_25FWnGb!bpV@1nDys%#^#)>!DMWl^cw&4wa=}EsfgtsU(_W}vIF-+g qj^)QD@-vrCjLb~$x}-QdF*Y$eJ~eh}ek^mz)I@P+bYy(=Qt@Ba@>Puh literal 0 HcmV?d00001 From 441232e824eef190dcee113a7e6e5b906337e299 Mon Sep 17 00:00:00 2001 From: pritsheth Date: Fri, 16 Feb 2024 15:52:22 -0800 Subject: [PATCH 6/6] Change module from soroban-tool to rpc in go.mod --- cmd/soroban-rpc/internal/config/options.go | 2 +- cmd/soroban-rpc/internal/daemon/daemon.go | 18 +++++++++--------- cmd/soroban-rpc/internal/daemon/metrics.go | 4 ++-- cmd/soroban-rpc/internal/events/events.go | 4 ++-- cmd/soroban-rpc/internal/events/events_test.go | 4 ++-- cmd/soroban-rpc/internal/ingest/ledgerentry.go | 2 +- .../internal/ingest/mock_db_test.go | 2 +- cmd/soroban-rpc/internal/ingest/service.go | 10 +++++----- .../internal/ingest/service_test.go | 8 ++++---- cmd/soroban-rpc/internal/jsonrpc.go | 14 +++++++------- cmd/soroban-rpc/internal/methods/get_events.go | 2 +- .../internal/methods/get_events_test.go | 4 ++-- .../internal/methods/get_latest_ledger.go | 2 +- .../internal/methods/get_latest_ledger_test.go | 2 +- .../internal/methods/get_ledger_entries.go | 2 +- .../internal/methods/get_ledger_entry.go | 2 +- .../internal/methods/get_network.go | 2 +- .../internal/methods/get_transaction.go | 2 +- .../internal/methods/get_transaction_test.go | 4 ++-- cmd/soroban-rpc/internal/methods/health.go | 2 +- .../internal/methods/send_transaction.go | 4 ++-- .../internal/methods/simulate_transaction.go | 4 ++-- .../internal/network/requestdurationlimiter.go | 2 +- cmd/soroban-rpc/internal/preflight/pool.go | 4 ++-- .../internal/preflight/preflight.go | 2 +- .../internal/preflight/preflight_test.go | 2 +- .../internal/test/get_ledger_entries_test.go | 2 +- .../internal/test/get_ledger_entry_test.go | 2 +- .../internal/test/get_network_test.go | 2 +- cmd/soroban-rpc/internal/test/health_test.go | 2 +- cmd/soroban-rpc/internal/test/integration.go | 8 ++++---- cmd/soroban-rpc/internal/test/metrics_test.go | 2 +- .../internal/test/simulate_transaction_test.go | 2 +- .../internal/test/transaction_test.go | 2 +- .../internal/transactions/transactions.go | 4 ++-- .../internal/transactions/transactions_test.go | 2 +- cmd/soroban-rpc/main.go | 4 ++-- go.mod | 2 +- 38 files changed, 72 insertions(+), 72 deletions(-) diff --git a/cmd/soroban-rpc/internal/config/options.go b/cmd/soroban-rpc/internal/config/options.go index d38dd7cd..df503200 100644 --- a/cmd/soroban-rpc/internal/config/options.go +++ b/cmd/soroban-rpc/internal/config/options.go @@ -14,7 +14,7 @@ import ( "github.com/stellar/go/support/errors" "github.com/stellar/go/support/strutils" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/ledgerbucketwindow" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/ledgerbucketwindow" ) const defaultHTTPEndpoint = "localhost:8000" diff --git a/cmd/soroban-rpc/internal/daemon/daemon.go b/cmd/soroban-rpc/internal/daemon/daemon.go index 7658b096..9e21f97a 100644 --- a/cmd/soroban-rpc/internal/daemon/daemon.go +++ b/cmd/soroban-rpc/internal/daemon/daemon.go @@ -22,15 +22,15 @@ import ( "github.com/stellar/go/support/storage" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/config" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/db" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/events" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/ingest" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/ledgerbucketwindow" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/preflight" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/transactions" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/util" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/config" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/events" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/ingest" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/ledgerbucketwindow" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/preflight" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/transactions" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/util" ) const ( diff --git a/cmd/soroban-rpc/internal/daemon/metrics.go b/cmd/soroban-rpc/internal/daemon/metrics.go index c7c44484..b9ed4084 100644 --- a/cmd/soroban-rpc/internal/daemon/metrics.go +++ b/cmd/soroban-rpc/internal/daemon/metrics.go @@ -11,8 +11,8 @@ import ( "github.com/stellar/go/support/logmetrics" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/config" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/config" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon/interfaces" ) func (d *Daemon) registerMetrics() { diff --git a/cmd/soroban-rpc/internal/events/events.go b/cmd/soroban-rpc/internal/events/events.go index d4352983..6eb42c01 100644 --- a/cmd/soroban-rpc/internal/events/events.go +++ b/cmd/soroban-rpc/internal/events/events.go @@ -11,8 +11,8 @@ import ( "github.com/stellar/go/ingest" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/ledgerbucketwindow" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon/interfaces" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/ledgerbucketwindow" ) type event struct { diff --git a/cmd/soroban-rpc/internal/events/events_test.go b/cmd/soroban-rpc/internal/events/events_test.go index df9b3385..55145fba 100644 --- a/cmd/soroban-rpc/internal/events/events_test.go +++ b/cmd/soroban-rpc/internal/events/events_test.go @@ -7,8 +7,8 @@ import ( "github.com/stellar/go/xdr" "github.com/stretchr/testify/require" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/ledgerbucketwindow" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon/interfaces" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/ledgerbucketwindow" ) var ( diff --git a/cmd/soroban-rpc/internal/ingest/ledgerentry.go b/cmd/soroban-rpc/internal/ingest/ledgerentry.go index 1e16efe3..9e4cc01d 100644 --- a/cmd/soroban-rpc/internal/ingest/ledgerentry.go +++ b/cmd/soroban-rpc/internal/ingest/ledgerentry.go @@ -10,7 +10,7 @@ import ( "github.com/stellar/go/ingest" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/db" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db" ) func (s *Service) ingestLedgerEntryChanges(ctx context.Context, reader ingest.ChangeReader, tx db.WriteTx, progressLogPeriod int) error { diff --git a/cmd/soroban-rpc/internal/ingest/mock_db_test.go b/cmd/soroban-rpc/internal/ingest/mock_db_test.go index 221bdc70..cb883eac 100644 --- a/cmd/soroban-rpc/internal/ingest/mock_db_test.go +++ b/cmd/soroban-rpc/internal/ingest/mock_db_test.go @@ -6,7 +6,7 @@ import ( "github.com/stellar/go/xdr" "github.com/stretchr/testify/mock" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/db" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db" ) var ( diff --git a/cmd/soroban-rpc/internal/ingest/service.go b/cmd/soroban-rpc/internal/ingest/service.go index 2cc082cb..d2c00b7b 100644 --- a/cmd/soroban-rpc/internal/ingest/service.go +++ b/cmd/soroban-rpc/internal/ingest/service.go @@ -16,12 +16,12 @@ import ( "github.com/stellar/go/support/log" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/db" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/util" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon/interfaces" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/util" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/events" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/transactions" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/events" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/transactions" ) const ( diff --git a/cmd/soroban-rpc/internal/ingest/service_test.go b/cmd/soroban-rpc/internal/ingest/service_test.go index a517562d..1fb233c0 100644 --- a/cmd/soroban-rpc/internal/ingest/service_test.go +++ b/cmd/soroban-rpc/internal/ingest/service_test.go @@ -14,10 +14,10 @@ import ( "github.com/stellar/go/xdr" "github.com/stretchr/testify/assert" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/db" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/events" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/transactions" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon/interfaces" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/events" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/transactions" ) type ErrorReadWriter struct { diff --git a/cmd/soroban-rpc/internal/jsonrpc.go b/cmd/soroban-rpc/internal/jsonrpc.go index 4bc4f17c..d122b9a0 100644 --- a/cmd/soroban-rpc/internal/jsonrpc.go +++ b/cmd/soroban-rpc/internal/jsonrpc.go @@ -16,13 +16,13 @@ import ( "github.com/rs/cors" "github.com/stellar/go/support/log" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/config" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/db" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/events" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/methods" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/network" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/transactions" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/config" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon/interfaces" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/events" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/methods" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/network" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/transactions" ) // maxHTTPRequestSize defines the largest request size that the http handler diff --git a/cmd/soroban-rpc/internal/methods/get_events.go b/cmd/soroban-rpc/internal/methods/get_events.go index 71cad1e9..dda0fa06 100644 --- a/cmd/soroban-rpc/internal/methods/get_events.go +++ b/cmd/soroban-rpc/internal/methods/get_events.go @@ -14,7 +14,7 @@ import ( "github.com/stellar/go/support/errors" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/events" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/events" ) type eventTypeSet map[string]interface{} diff --git a/cmd/soroban-rpc/internal/methods/get_events_test.go b/cmd/soroban-rpc/internal/methods/get_events_test.go index 5d1b929c..087a3ffd 100644 --- a/cmd/soroban-rpc/internal/methods/get_events_test.go +++ b/cmd/soroban-rpc/internal/methods/get_events_test.go @@ -14,8 +14,8 @@ import ( "github.com/stellar/go/strkey" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/events" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon/interfaces" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/events" ) func TestEventTypeSetMatches(t *testing.T) { diff --git a/cmd/soroban-rpc/internal/methods/get_latest_ledger.go b/cmd/soroban-rpc/internal/methods/get_latest_ledger.go index 11bd997a..2f933304 100644 --- a/cmd/soroban-rpc/internal/methods/get_latest_ledger.go +++ b/cmd/soroban-rpc/internal/methods/get_latest_ledger.go @@ -6,7 +6,7 @@ import ( "github.com/creachadair/jrpc2" "github.com/creachadair/jrpc2/handler" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/db" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db" ) type GetLatestLedgerResponse struct { diff --git a/cmd/soroban-rpc/internal/methods/get_latest_ledger_test.go b/cmd/soroban-rpc/internal/methods/get_latest_ledger_test.go index 474b3b8d..30e05afa 100644 --- a/cmd/soroban-rpc/internal/methods/get_latest_ledger_test.go +++ b/cmd/soroban-rpc/internal/methods/get_latest_ledger_test.go @@ -8,7 +8,7 @@ import ( "github.com/stellar/go/xdr" "github.com/stretchr/testify/assert" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/db" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db" ) const ( diff --git a/cmd/soroban-rpc/internal/methods/get_ledger_entries.go b/cmd/soroban-rpc/internal/methods/get_ledger_entries.go index 4063858c..e9e58868 100644 --- a/cmd/soroban-rpc/internal/methods/get_ledger_entries.go +++ b/cmd/soroban-rpc/internal/methods/get_ledger_entries.go @@ -9,7 +9,7 @@ import ( "github.com/stellar/go/support/log" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/db" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db" ) var ErrLedgerTtlEntriesCannotBeQueriedDirectly = "ledger ttl entries cannot be queried directly" diff --git a/cmd/soroban-rpc/internal/methods/get_ledger_entry.go b/cmd/soroban-rpc/internal/methods/get_ledger_entry.go index b78d1099..e457a3b1 100644 --- a/cmd/soroban-rpc/internal/methods/get_ledger_entry.go +++ b/cmd/soroban-rpc/internal/methods/get_ledger_entry.go @@ -10,7 +10,7 @@ import ( "github.com/stellar/go/support/log" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/db" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db" ) // Deprecated. Use GetLedgerEntriesRequest instead. diff --git a/cmd/soroban-rpc/internal/methods/get_network.go b/cmd/soroban-rpc/internal/methods/get_network.go index be2e0305..5c990c41 100644 --- a/cmd/soroban-rpc/internal/methods/get_network.go +++ b/cmd/soroban-rpc/internal/methods/get_network.go @@ -6,7 +6,7 @@ import ( "github.com/creachadair/jrpc2" "github.com/creachadair/jrpc2/handler" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon/interfaces" ) type GetNetworkRequest struct{} diff --git a/cmd/soroban-rpc/internal/methods/get_transaction.go b/cmd/soroban-rpc/internal/methods/get_transaction.go index de58be64..8b1846f8 100644 --- a/cmd/soroban-rpc/internal/methods/get_transaction.go +++ b/cmd/soroban-rpc/internal/methods/get_transaction.go @@ -10,7 +10,7 @@ import ( "github.com/creachadair/jrpc2/handler" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/transactions" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/transactions" ) const ( diff --git a/cmd/soroban-rpc/internal/methods/get_transaction_test.go b/cmd/soroban-rpc/internal/methods/get_transaction_test.go index 263dd92a..dadf145f 100644 --- a/cmd/soroban-rpc/internal/methods/get_transaction_test.go +++ b/cmd/soroban-rpc/internal/methods/get_transaction_test.go @@ -9,8 +9,8 @@ import ( "github.com/stellar/go/network" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/transactions" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon/interfaces" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/transactions" ) func txHash(acctSeq uint32) xdr.Hash { diff --git a/cmd/soroban-rpc/internal/methods/health.go b/cmd/soroban-rpc/internal/methods/health.go index ab51cc78..ab46d62a 100644 --- a/cmd/soroban-rpc/internal/methods/health.go +++ b/cmd/soroban-rpc/internal/methods/health.go @@ -8,7 +8,7 @@ import ( "github.com/creachadair/jrpc2" "github.com/creachadair/jrpc2/handler" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/transactions" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/transactions" ) type HealthCheckResult struct { diff --git a/cmd/soroban-rpc/internal/methods/send_transaction.go b/cmd/soroban-rpc/internal/methods/send_transaction.go index c8a0ff84..c8404c69 100644 --- a/cmd/soroban-rpc/internal/methods/send_transaction.go +++ b/cmd/soroban-rpc/internal/methods/send_transaction.go @@ -11,8 +11,8 @@ import ( "github.com/stellar/go/support/log" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/transactions" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon/interfaces" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/transactions" ) // SendTransactionResponse represents the transaction submission response returned Soroban-RPC diff --git a/cmd/soroban-rpc/internal/methods/simulate_transaction.go b/cmd/soroban-rpc/internal/methods/simulate_transaction.go index a278c9c2..580a5d2f 100644 --- a/cmd/soroban-rpc/internal/methods/simulate_transaction.go +++ b/cmd/soroban-rpc/internal/methods/simulate_transaction.go @@ -10,8 +10,8 @@ import ( "github.com/stellar/go/support/log" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/db" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/preflight" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/preflight" ) type SimulateTransactionRequest struct { diff --git a/cmd/soroban-rpc/internal/network/requestdurationlimiter.go b/cmd/soroban-rpc/internal/network/requestdurationlimiter.go index 05204591..141b2486 100644 --- a/cmd/soroban-rpc/internal/network/requestdurationlimiter.go +++ b/cmd/soroban-rpc/internal/network/requestdurationlimiter.go @@ -9,7 +9,7 @@ import ( "github.com/creachadair/jrpc2" "github.com/stellar/go/support/log" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/util" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/util" ) const maxUint = ^uint64(0) //18446744073709551615 diff --git a/cmd/soroban-rpc/internal/preflight/pool.go b/cmd/soroban-rpc/internal/preflight/pool.go index 1d182411..4eeddb53 100644 --- a/cmd/soroban-rpc/internal/preflight/pool.go +++ b/cmd/soroban-rpc/internal/preflight/pool.go @@ -11,8 +11,8 @@ import ( "github.com/stellar/go/support/log" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/db" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon/interfaces" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db" ) type workerResult struct { diff --git a/cmd/soroban-rpc/internal/preflight/preflight.go b/cmd/soroban-rpc/internal/preflight/preflight.go index e342ab43..584c47d6 100644 --- a/cmd/soroban-rpc/internal/preflight/preflight.go +++ b/cmd/soroban-rpc/internal/preflight/preflight.go @@ -11,7 +11,7 @@ import ( "github.com/stellar/go/support/log" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/db" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db" ) /* diff --git a/cmd/soroban-rpc/internal/preflight/preflight_test.go b/cmd/soroban-rpc/internal/preflight/preflight_test.go index 601901ff..926c2611 100644 --- a/cmd/soroban-rpc/internal/preflight/preflight_test.go +++ b/cmd/soroban-rpc/internal/preflight/preflight_test.go @@ -12,7 +12,7 @@ import ( "github.com/stellar/go/xdr" "github.com/stretchr/testify/require" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/db" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db" ) var mockContractID = xdr.Hash{0xa, 0xb, 0xc} diff --git a/cmd/soroban-rpc/internal/test/get_ledger_entries_test.go b/cmd/soroban-rpc/internal/test/get_ledger_entries_test.go index 889b4e04..50c0af9e 100644 --- a/cmd/soroban-rpc/internal/test/get_ledger_entries_test.go +++ b/cmd/soroban-rpc/internal/test/get_ledger_entries_test.go @@ -14,7 +14,7 @@ import ( "github.com/stellar/go/txnbuild" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/methods" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/methods" ) func TestGetLedgerEntriesNotFound(t *testing.T) { diff --git a/cmd/soroban-rpc/internal/test/get_ledger_entry_test.go b/cmd/soroban-rpc/internal/test/get_ledger_entry_test.go index b453f4d8..df606bfc 100644 --- a/cmd/soroban-rpc/internal/test/get_ledger_entry_test.go +++ b/cmd/soroban-rpc/internal/test/get_ledger_entry_test.go @@ -14,7 +14,7 @@ import ( "github.com/stellar/go/keypair" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/methods" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/methods" ) func TestGetLedgerEntryNotFound(t *testing.T) { diff --git a/cmd/soroban-rpc/internal/test/get_network_test.go b/cmd/soroban-rpc/internal/test/get_network_test.go index 9c8ef266..6cc2fa5e 100644 --- a/cmd/soroban-rpc/internal/test/get_network_test.go +++ b/cmd/soroban-rpc/internal/test/get_network_test.go @@ -8,7 +8,7 @@ import ( "github.com/creachadair/jrpc2/jhttp" "github.com/stretchr/testify/assert" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/methods" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/methods" ) func TestGetNetworkSucceeds(t *testing.T) { diff --git a/cmd/soroban-rpc/internal/test/health_test.go b/cmd/soroban-rpc/internal/test/health_test.go index 517b374d..46a327fd 100644 --- a/cmd/soroban-rpc/internal/test/health_test.go +++ b/cmd/soroban-rpc/internal/test/health_test.go @@ -6,7 +6,7 @@ import ( "github.com/creachadair/jrpc2" "github.com/creachadair/jrpc2/jhttp" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/methods" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/methods" "github.com/stretchr/testify/assert" ) diff --git a/cmd/soroban-rpc/internal/test/integration.go b/cmd/soroban-rpc/internal/test/integration.go index 25096cda..60633b1f 100644 --- a/cmd/soroban-rpc/internal/test/integration.go +++ b/cmd/soroban-rpc/internal/test/integration.go @@ -24,10 +24,10 @@ import ( "github.com/stellar/go/keypair" "github.com/stellar/go/txnbuild" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/config" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/db" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/ledgerbucketwindow" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/config" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/ledgerbucketwindow" ) const ( diff --git a/cmd/soroban-rpc/internal/test/metrics_test.go b/cmd/soroban-rpc/internal/test/metrics_test.go index b807cb77..a487fe02 100644 --- a/cmd/soroban-rpc/internal/test/metrics_test.go +++ b/cmd/soroban-rpc/internal/test/metrics_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/config" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/config" ) func TestMetrics(t *testing.T) { diff --git a/cmd/soroban-rpc/internal/test/simulate_transaction_test.go b/cmd/soroban-rpc/internal/test/simulate_transaction_test.go index 12387530..26866ed7 100644 --- a/cmd/soroban-rpc/internal/test/simulate_transaction_test.go +++ b/cmd/soroban-rpc/internal/test/simulate_transaction_test.go @@ -19,7 +19,7 @@ import ( "github.com/stellar/go/txnbuild" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/methods" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/methods" ) var ( diff --git a/cmd/soroban-rpc/internal/test/transaction_test.go b/cmd/soroban-rpc/internal/test/transaction_test.go index 9027bc58..372e4ee2 100644 --- a/cmd/soroban-rpc/internal/test/transaction_test.go +++ b/cmd/soroban-rpc/internal/test/transaction_test.go @@ -17,7 +17,7 @@ import ( "github.com/stellar/go/txnbuild" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/methods" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/methods" ) func TestSendTransactionSucceedsWithoutResults(t *testing.T) { diff --git a/cmd/soroban-rpc/internal/transactions/transactions.go b/cmd/soroban-rpc/internal/transactions/transactions.go index f2feef49..6b24f429 100644 --- a/cmd/soroban-rpc/internal/transactions/transactions.go +++ b/cmd/soroban-rpc/internal/transactions/transactions.go @@ -8,8 +8,8 @@ import ( "github.com/stellar/go/ingest" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/ledgerbucketwindow" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon/interfaces" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/ledgerbucketwindow" ) type transaction struct { diff --git a/cmd/soroban-rpc/internal/transactions/transactions_test.go b/cmd/soroban-rpc/internal/transactions/transactions_test.go index 27b500c4..73ddbaa6 100644 --- a/cmd/soroban-rpc/internal/transactions/transactions_test.go +++ b/cmd/soroban-rpc/internal/transactions/transactions_test.go @@ -12,7 +12,7 @@ import ( "github.com/stellar/go/xdr" "github.com/stretchr/testify/require" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon/interfaces" ) func expectedTransaction(t *testing.T, ledger uint32, feeBump bool) Transaction { diff --git a/cmd/soroban-rpc/main.go b/cmd/soroban-rpc/main.go index e7e8713b..48698223 100644 --- a/cmd/soroban-rpc/main.go +++ b/cmd/soroban-rpc/main.go @@ -7,8 +7,8 @@ import ( "github.com/spf13/cobra" goxdr "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/config" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/config" + "github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon" ) func main() { diff --git a/go.mod b/go.mod index 52a105e1..9c1e46ce 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/stellar/soroban-tools +module github.com/stellar/soroban-rpc go 1.21